Merge pull request #597 from jonathandturner/spreadsheet_terms

Move us away from OOP terms to spreadsheet terms
This commit is contained in:
Jonathan Turner 2019-09-05 04:56:16 +12:00 committed by GitHub
commit ede45e21de
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 69 additions and 66 deletions

View File

@ -90,7 +90,7 @@ The second container is a bit smaller, if size is important to you.
# Philosophy # Philosophy
Nu draws inspiration from projects like PowerShell, functional programming languages, and modern cli tools. Rather than thinking of files and services as raw streams of text, Nu looks at each input as something with structure. For example, when you list the contents of a directory, what you get back is a list of objects, where each object represents an item in that directory. These values can be piped through a series of steps, in a series of commands called a 'pipeline'. Nu draws inspiration from projects like PowerShell, functional programming languages, and modern cli tools. Rather than thinking of files and services as raw streams of text, Nu looks at each input as something with structure. For example, when you list the contents of a directory, what you get back is a table of rows, where each row represents an item in that directory. These values can be piped through a series of steps, in a series of commands called a 'pipeline'.
## Pipelines ## Pipelines
@ -104,17 +104,18 @@ Commands are separated by the pipe symbol (`|`) to denote a pipeline flowing lef
``` ```
/home/jonathan/Source/nushell(master)> ls | where type == "Directory" | autoview /home/jonathan/Source/nushell(master)> ls | where type == "Directory" | autoview
--------+-----------+----------+--------+--------------+---------------- ━━━━┯━━━━━━━━━━━┯━━━━━━━━━━━┯━━━━━━━━━━┯━━━━━━━━┯━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━
name | type | readonly | size | accessed | modified # │ name │ type │ readonly │ size │ accessed │ modified
--------+-----------+----------+--------+--------------+---------------- ────┼───────────┼───────────┼──────────┼────────┼──────────────┼────────────────
target | Directory | | 4.1 KB | 19 hours ago | 19 hours ago 0 │ .azure │ Directory │ │ 4.1 KB │ 2 months ago │ a day ago
images | Directory | | 4.1 KB | 2 weeks ago | a week ago 1 │ target │ Directory │ │ 4.1 KB │ 3 days ago │ 3 days ago
tests | Directory | | 4.1 KB | 2 weeks ago | 18 minutes ago 2 │ images │ Directory │ │ 4.1 KB │ 2 months ago │ 2 weeks ago
docs | Directory | | 4.1 KB | a week ago | a week ago 3 │ tests │ Directory │ │ 4.1 KB │ 2 months ago │ 37 minutes ago
.git | Directory | | 4.1 KB | 2 weeks ago | 25 minutes ago 4 │ tmp │ Directory │ │ 4.1 KB │ 2 weeks ago │ 2 weeks ago
src | Directory | | 4.1 KB | 2 weeks ago | 25 minutes ago 5 │ src │ Directory │ │ 4.1 KB │ 2 months ago │ 37 minutes ago
.cargo | Directory | | 4.1 KB | 2 weeks ago | 2 weeks ago 6 │ assets │ Directory │ │ 4.1 KB │ a month ago │ a month ago
--------+-----------+----------+--------+--------------+---------------- 7 │ docs │ Directory │ │ 4.1 KB │ 2 months ago │ 2 months ago
━━━━┷━━━━━━━━━━━┷━━━━━━━━━━━┷━━━━━━━━━━┷━━━━━━━━┷━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━
``` ```
Because most of the time you'll want to see the output of a pipeline, `autoview` is assumed. We could have also written the above: Because most of the time you'll want to see the output of a pipeline, `autoview` is assumed. We could have also written the above:
@ -126,15 +127,16 @@ Because most of the time you'll want to see the output of a pipeline, `autoview`
Being able to use the same commands and compose them differently is an important philosophy in Nu. For example, we could use the built-in `ps` command as well to get a list of the running processes, using the same `where` as above. Being able to use the same commands and compose them differently is an important philosophy in Nu. For example, we could use the built-in `ps` command as well to get a list of the running processes, using the same `where` as above.
```text ```text
C:\Code\nushell(master)> ps | where cpu > 0 /home/jonathan/Source/nushell(master)> ps | where cpu > 0
------------------ +-----+-------+-------+---------- ━━━┯━━━━━━━┯━━━━━━━━━━━━━━━━━┯━━━━━━━━━━┯━━━━━━━━━━
name | cmd | cpu | pid | status # │ pid │ name │ status │ cpu
------------------ +-----+-------+-------+---------- ───┼───────┼─────────────────┼──────────┼──────────
msedge.exe | - | 0.77 | 26472 | Runnable 0 │ 992 │ chrome │ Sleeping │ 6.988768
nu.exe | - | 7.83 | 15473 | Runnable 1 │ 4240 │ chrome │ Sleeping │ 5.645982
SearchIndexer.exe | - | 82.17 | 23476 | Runnable 2 │ 13973 │ qemu-system-x86 │ Sleeping │ 4.996551
BlueJeans.exe | - | 4.54 | 10000 | Runnable 3 │ 15746 │ nu │ Sleeping │ 84.59905
-------------------+-----+-------+-------+---------- ━━━┷━━━━━━━┷━━━━━━━━━━━━━━━━━┷━━━━━━━━━━┷━━━━━━━━━━
``` ```
## Opening files ## Opening files
@ -143,22 +145,22 @@ Nu can load file and URL contents as raw text or as structured data (if it recog
``` ```
/home/jonathan/Source/nushell(master)> open Cargo.toml /home/jonathan/Source/nushell(master)> open Cargo.toml
-----------------+------------------+----------------- ━━━━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━━━
dependencies | dev-dependencies | package bin │ dependencies │ dev-dependencies
-----------------+------------------+----------------- ──────────────────┼────────────────┼──────────────────
[object Object] | [object Object] | [object Object] [table: 12 rows] │ [table: 1 row] │ [table: 1 row]
-----------------+------------------+----------------- ━━━━━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━━━
``` ```
We can pipeline this into a command that gets the contents of one of the columns: We can pipeline this into a command that gets the contents of one of the columns:
``` ```
/home/jonathan/Source/nushell(master)> open Cargo.toml | get package /home/jonathan/Source/nushell(master)> open Cargo.toml | get package
-------------+----------------------------+---------+---------+------+--------- ━━━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━━━━┯━━━━━━━━━┯━━━━━━━━━┯━━━━━━┯━━━━━━━━━
authors | description | edition | license | name | version authors │ description │ edition │ license │ name │ version
-------------+----------------------------+---------+---------+------+--------- ─────────────────┼────────────────────────────┼─────────┼─────────┼──────┼─────────
[list List] | A shell for the GitHub era | 2018 | MIT | nu | 0.2.0 [table: 3 rows] │ A shell for the GitHub era │ 2018 │ ISC │ nu │ 0.2.0
-------------+----------------------------+---------+---------+------+--------- ━━━━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━━━━┷━━━━━━━━━┷━━━━━━━━━┷━━━━━━┷━━━━━━━━━
``` ```
Finally, we can use commands outside of Nu once we have the data we want: Finally, we can use commands outside of Nu once we have the data we want:
@ -180,7 +182,7 @@ Finally, to get a list of all the current shells, you can use the `shells` comma
## Plugins ## Plugins
Nu supports plugins that offer additional functionality to the shell and follow the same object model that built-in commands use. This allows you to extend nu for your needs. Nu supports plugins that offer additional functionality to the shell and follow the same structured data model that built-in commands use. This allows you to extend nu for your needs.
There are a few examples in the `plugins` directory. There are a few examples in the `plugins` directory.
@ -196,7 +198,7 @@ Nu adheres closely to a set of goals that make up its design philosophy. As feat
* Nu's workflow and tools should have the usability in day-to-day experience of using a shell in 2019 (and beyond). * Nu's workflow and tools should have the usability in day-to-day experience of using a shell in 2019 (and beyond).
* Nu views data as both structured and unstructured. It is an object shell like PowerShell. * Nu views data as both structured and unstructured. It is a structured shell like PowerShell.
* Finally, Nu views data functionally. Rather than using mutation, pipelines act as a means to load, change, and save data without mutable state. * Finally, Nu views data functionally. Rather than using mutation, pipelines act as a means to load, change, and save data without mutable state.
@ -233,18 +235,18 @@ Nu adheres closely to a set of goals that make up its design philosophy. As feat
| get column-or-column-path | Open column and get data from the corresponding cells | | get column-or-column-path | Open column and get data from the corresponding cells |
| sort-by ...columns | Sort by the given columns | | sort-by ...columns | Sort by the given columns |
| where condition | Filter table to match the condition | | where condition | Filter table to match the condition |
| inc (field) | Increment a value or version. Optional use the field of a table | | inc (column-or-column-path) | Increment a value or version. Optionally use the column of a table |
| add field value | Add a new field to the table | | add column-or-column-path value | Add a new column to the table |
| embed field | Embeds a new field to the table | | embed column | Creates a new table of one column with the given name, and places the current table inside of it |
| sum | Sum a column of values | | sum | Sum a column of values |
| edit field value | Edit an existing field to have a new value | | edit column-or-column-path value | Edit an existing column to have a new value |
| reverse | Reverses the table. | | reverse | Reverses the table. |
| skip amount | Skip a number of rows | | skip amount | Skip a number of rows |
| skip-while condition | Skips rows while the condition matches. | | skip-while condition | Skips rows while the condition matches. |
| first amount | Show only the first number of rows | | first amount | Show only the first number of rows |
| last amount | Show only the last number of rows | | last amount | Show only the last number of rows |
| nth row-number | Return only the selected row | | nth row-number | Return only the selected row |
| str (field) | Apply string function. Optional use the field of a table | | str (column) | Apply string function. Optionally use the column of a table |
| tags | Read the tags (metadata) for values | | tags | Read the tags (metadata) for values |
| to-json | Convert table into .json text | | to-json | Convert table into .json text |
| to-toml | Convert table into .toml text | | to-toml | Convert table into .toml text |
@ -269,7 +271,7 @@ Nu adheres closely to a set of goals that make up its design philosophy. As feat
| from-yaml | Parse text as a .yaml/.yml and create a table | | from-yaml | Parse text as a .yaml/.yml and create a table |
| lines | Split single string into rows, one per line | | lines | Split single string into rows, one per line |
| size | Gather word count statistics on the text | | size | Gather word count statistics on the text |
| split-column sep ...fields | Split row contents across multiple columns via the separator | | split-column sep ...column-names | Split row contents across multiple columns via the separator, optionally give the columns names |
| split-row sep | Split row contents over multiple rows via the separator | | split-row sep | Split row contents over multiple rows via the separator |
| trim | Trim leading and following whitespace from text data | | trim | Trim leading and following whitespace from text data |
| {external-command} $it | Run external command with given arguments, replacing $it with each row text | | {external-command} $it | Run external command with given arguments, replacing $it with each row text |

View File

@ -238,7 +238,7 @@ impl ExternalCommand {
if let Some(span) = span { if let Some(span) = span {
return Err(ShellError::labeled_error( return Err(ShellError::labeled_error(
"External $it needs string data", "External $it needs string data",
"given object instead of string data", "given row instead of string data",
span, span,
)); ));
} else { } else {
@ -293,7 +293,7 @@ impl ExternalCommand {
} }
return Err(ShellError::labeled_error( return Err(ShellError::labeled_error(
"External $it needs string data", "External $it needs string data",
"given object instead of string data", "given row instead of string data",
span, span,
)); ));
} }

View File

@ -256,7 +256,7 @@ fn to_bson(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream
Value::Binary(x).simple_spanned(name_span), Value::Binary(x).simple_spanned(name_span),
), ),
_ => yield Err(ShellError::labeled_error_with_secondary( _ => yield Err(ShellError::labeled_error_with_secondary(
"Expected an object with BSON-compatible structure.span() from pipeline", "Expected a table with BSON-compatible structure.span() from pipeline",
"requires BSON-compatible input", "requires BSON-compatible input",
name_span, name_span,
"originates from here".to_string(), "originates from here".to_string(),
@ -265,7 +265,7 @@ fn to_bson(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream
} }
} }
_ => yield Err(ShellError::labeled_error( _ => yield Err(ShellError::labeled_error(
"Expected an object with BSON-compatible structure from pipeline", "Expected a table with BSON-compatible structure from pipeline",
"requires BSON-compatible input", "requires BSON-compatible input",
name_span)) name_span))
} }

View File

@ -153,7 +153,7 @@ fn to_csv(
} }
_ => { _ => {
yield Err(ShellError::labeled_error_with_secondary( yield Err(ShellError::labeled_error_with_secondary(
"Expected an object with CSV-compatible structure.span() from pipeline", "Expected a table with CSV-compatible structure.span() from pipeline",
"requires CSV-compatible input", "requires CSV-compatible input",
name_span, name_span,
"originates from here".to_string(), "originates from here".to_string(),

View File

@ -100,7 +100,7 @@ fn to_json(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream
Value::Primitive(Primitive::String(x)).simple_spanned(name_span), Value::Primitive(Primitive::String(x)).simple_spanned(name_span),
), ),
_ => yield Err(ShellError::labeled_error_with_secondary( _ => yield Err(ShellError::labeled_error_with_secondary(
"Expected an object with JSON-compatible structure.span() from pipeline", "Expected a table with JSON-compatible structure.span() from pipeline",
"requires JSON-compatible input", "requires JSON-compatible input",
name_span, name_span,
"originates from here".to_string(), "originates from here".to_string(),
@ -109,7 +109,7 @@ fn to_json(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream
} }
} }
_ => yield Err(ShellError::labeled_error( _ => yield Err(ShellError::labeled_error(
"Expected an object with JSON-compatible structure from pipeline", "Expected a table with JSON-compatible structure from pipeline",
"requires JSON-compatible input", "requires JSON-compatible input",
name_span)) name_span))
} }

View File

@ -187,7 +187,7 @@ fn sqlite_input_stream_to_bytes(
other => { other => {
return Err(std::io::Error::new( return Err(std::io::Error::new(
std::io::ErrorKind::Other, std::io::ErrorKind::Other,
format!("Expected object, found {:?}", other), format!("Expected row, found {:?}", other),
)) ))
} }
} }
@ -207,7 +207,7 @@ fn to_sqlite(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStre
Ok(out) => yield ReturnSuccess::value(out), Ok(out) => yield ReturnSuccess::value(out),
_ => { _ => {
yield Err(ShellError::labeled_error( yield Err(ShellError::labeled_error(
"Expected an object with SQLite-compatible structure.span() from pipeline", "Expected a table with SQLite-compatible structure.span() from pipeline",
"requires SQLite-compatible input", "requires SQLite-compatible input",
name_span, name_span,
)) ))

View File

@ -95,7 +95,7 @@ fn to_toml(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream
Value::Primitive(Primitive::String(x)).simple_spanned(name_span), Value::Primitive(Primitive::String(x)).simple_spanned(name_span),
), ),
_ => yield Err(ShellError::labeled_error_with_secondary( _ => yield Err(ShellError::labeled_error_with_secondary(
"Expected an object with TOML-compatible structure.span() from pipeline", "Expected a table with TOML-compatible structure.span() from pipeline",
"requires TOML-compatible input", "requires TOML-compatible input",
name_span, name_span,
"originates from here".to_string(), "originates from here".to_string(),
@ -104,7 +104,7 @@ fn to_toml(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream
} }
} }
_ => yield Err(ShellError::labeled_error( _ => yield Err(ShellError::labeled_error(
"Expected an object with TOML-compatible structure from pipeline", "Expected a table with TOML-compatible structure from pipeline",
"requires TOML-compatible input", "requires TOML-compatible input",
name_span)) name_span))
} }

View File

@ -51,8 +51,8 @@ fn to_string_helper(v: &Value) -> Result<String, ShellError> {
Value::Primitive(Primitive::Date(d)) => Ok(d.to_string()), Value::Primitive(Primitive::Date(d)) => Ok(d.to_string()),
Value::Primitive(Primitive::Bytes(b)) => Ok(format!("{}", b)), Value::Primitive(Primitive::Bytes(b)) => Ok(format!("{}", b)),
Value::Primitive(Primitive::Boolean(_)) => Ok(v.as_string()?), Value::Primitive(Primitive::Boolean(_)) => Ok(v.as_string()?),
Value::List(_) => return Ok(String::from("[list list]")), Value::List(_) => return Ok(String::from("[table]")),
Value::Object(_) => return Ok(String::from("[object]")), Value::Object(_) => return Ok(String::from("[row]")),
Value::Primitive(Primitive::String(s)) => return Ok(s.to_string()), Value::Primitive(Primitive::String(s)) => return Ok(s.to_string()),
_ => Err(ShellError::string("Unexpected value")), _ => Err(ShellError::string("Unexpected value")),
} }
@ -152,7 +152,7 @@ fn to_tsv(
} }
_ => { _ => {
yield Err(ShellError::labeled_error_with_secondary( yield Err(ShellError::labeled_error_with_secondary(
"Expected an object with TSV-compatible structure.span() from pipeline", "Expected a table with TSV-compatible structure.span() from pipeline",
"requires TSV-compatible input", "requires TSV-compatible input",
name_span, name_span,
"originates from here".to_string(), "originates from here".to_string(),

View File

@ -96,7 +96,7 @@ fn to_yaml(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream
Value::Primitive(Primitive::String(x)).simple_spanned(name_span), Value::Primitive(Primitive::String(x)).simple_spanned(name_span),
), ),
_ => yield Err(ShellError::labeled_error_with_secondary( _ => yield Err(ShellError::labeled_error_with_secondary(
"Expected an object with YAML-compatible structure.span() from pipeline", "Expected a table with YAML-compatible structure.span() from pipeline",
"requires YAML-compatible input", "requires YAML-compatible input",
name_span, name_span,
"originates from here".to_string(), "originates from here".to_string(),
@ -105,7 +105,7 @@ fn to_yaml(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream
} }
} }
_ => yield Err(ShellError::labeled_error( _ => yield Err(ShellError::labeled_error(
"Expected an object with YAML-compatible structure from pipeline", "Expected a table with YAML-compatible structure from pipeline",
"requires YAML-compatible input", "requires YAML-compatible input",
name_span)) name_span))
} }

View File

@ -504,11 +504,11 @@ impl Value {
.map(|e| e.source(&b.source).to_string()), .map(|e| e.source(&b.source).to_string()),
"; ", "; ",
), ),
Value::Object(_) => format!("[{}]", self.type_name()), Value::Object(_) => format!("[table: 1 row]"),
Value::List(l) => format!( Value::List(l) => format!(
"[{} {}]", "[table: {} {}]",
l.len(), l.len(),
if l.len() == 1 { "item" } else { "items" } if l.len() == 1 { "row" } else { "rows" }
), ),
Value::Binary(_) => format!("<binary>"), Value::Binary(_) => format!("<binary>"),
} }

View File

@ -29,7 +29,7 @@ impl Add {
} }
}, },
None => Err(ShellError::string( None => Err(ShellError::string(
"add needs a field when adding a value to an object", "add needs a column name when adding a value to a table",
)), )),
}, },
x => Err(ShellError::string(format!( x => Err(ShellError::string(format!(
@ -46,7 +46,8 @@ impl Plugin for Add {
.desc("Add a new field to the table.") .desc("Add a new field to the table.")
.required("Field", SyntaxType::String) .required("Field", SyntaxType::String)
.required("Value", SyntaxType::String) .required("Value", SyntaxType::String)
.rest(SyntaxType::String).filter()) .rest(SyntaxType::String)
.filter())
} }
fn begin_filter(&mut self, call_info: CallInfo) -> Result<Vec<ReturnValue>, ShellError> { fn begin_filter(&mut self, call_info: CallInfo) -> Result<Vec<ReturnValue>, ShellError> {

View File

@ -23,12 +23,12 @@ impl Edit {
Some(v) => return Ok(v), Some(v) => return Ok(v),
None => { None => {
return Err(ShellError::string( return Err(ShellError::string(
"edit could not find place to insert field", "edit could not find place to insert column",
)) ))
} }
}, },
None => Err(ShellError::string( None => Err(ShellError::string(
"edit needs a field when adding a value to an object", "edit needs a column when changing a value in a table",
)), )),
}, },
x => Err(ShellError::string(format!( x => Err(ShellError::string(format!(
@ -42,7 +42,7 @@ impl Edit {
impl Plugin for Edit { impl Plugin for Edit {
fn config(&mut self) -> Result<Signature, ShellError> { fn config(&mut self) -> Result<Signature, ShellError> {
Ok(Signature::build("edit") Ok(Signature::build("edit")
.desc("Edit an existing field to have a new value.") .desc("Edit an existing column to have a new value.")
.required("Field", SyntaxType::String) .required("Field", SyntaxType::String)
.required("Value", SyntaxType::String) .required("Value", SyntaxType::String)
.filter()) .filter())

View File

@ -102,7 +102,7 @@ impl Inc {
} }
} }
None => Err(ShellError::string( None => Err(ShellError::string(
"inc needs a field when incrementing a value in an object", "inc needs a field when incrementing a column in a table",
)), )),
}, },
x => Err(ShellError::string(format!( x => Err(ShellError::string(format!(
@ -116,7 +116,7 @@ impl Inc {
impl Plugin for Inc { impl Plugin for Inc {
fn config(&mut self) -> Result<Signature, ShellError> { fn config(&mut self) -> Result<Signature, ShellError> {
Ok(Signature::build("inc") Ok(Signature::build("inc")
.desc("Increment a value or version. Optional use the field of a table.") .desc("Increment a value or version. Optionally use the column of a table.")
.switch("major") .switch("major")
.switch("minor") .switch("minor")
.switch("patch") .switch("patch")

View File

@ -153,7 +153,7 @@ impl Str {
} }
None => Err(ShellError::string(format!( None => Err(ShellError::string(format!(
"{}: {}", "{}: {}",
"str needs a field when applying it to a value in an object", "str needs a column when applied to a value in a row",
Str::usage() Str::usage()
))), ))),
}, },