mirror of
https://github.com/nushell/nushell
synced 2024-12-26 04:53:09 +00:00
Cleanup for upcoming release
This commit is contained in:
parent
3d28b50a53
commit
2ed46046bd
29 changed files with 139 additions and 570 deletions
32
Cargo.lock
generated
32
Cargo.lock
generated
|
@ -1285,13 +1285,13 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "language-reporting"
|
||||
version = "0.3.0"
|
||||
source = "git+https://github.com/jonathandturner/language-reporting#0a6c284a19a00b5b6b680480c0ad5f241fc5edac"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"derive-new 0.5.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"itertools 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"render-tree 0.1.1 (git+https://github.com/jonathandturner/language-reporting)",
|
||||
"render-tree 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.94 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.94 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"termcolor 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -1620,9 +1620,9 @@ dependencies = [
|
|||
]
|
||||
|
||||
[[package]]
|
||||
name = "nom_locate"
|
||||
version = "0.3.1"
|
||||
source = "git+https://github.com/wycats/nom_locate.git?branch=nom5#5baeede19605e2049994eca8f7b366ddc85bb9cd"
|
||||
name = "nom5_locate"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bytecount 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -1659,7 +1659,7 @@ dependencies = [
|
|||
"image 0.21.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"language-reporting 0.3.0 (git+https://github.com/jonathandturner/language-reporting)",
|
||||
"language-reporting 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"logos 0.10.0-rc2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -1667,7 +1667,7 @@ dependencies = [
|
|||
"mime 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"neso 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"nom 5.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"nom_locate 0.3.1 (git+https://github.com/wycats/nom_locate.git?branch=nom5)",
|
||||
"nom5_locate 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ordered-float 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pretty-hex 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pretty_assertions 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -1675,7 +1675,7 @@ dependencies = [
|
|||
"prettyprint 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"prettytable-rs 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ptree 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rawkey 0.1.0 (git+https://github.com/jonathandturner/rawkey.git)",
|
||||
"rawkey 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex 1.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"reqwest 0.9.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"roxmltree 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -2266,8 +2266,8 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "rawkey"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/jonathandturner/rawkey.git#f06456a6f662eff142ed019fb5583043e11b771c"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"readkey 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"user32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -2365,7 +2365,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "render-tree"
|
||||
version = "0.1.1"
|
||||
source = "git+https://github.com/jonathandturner/language-reporting#0a6c284a19a00b5b6b680480c0ad5f241fc5edac"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"itertools 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -3517,7 +3517,7 @@ dependencies = [
|
|||
"checksum itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f"
|
||||
"checksum jpeg-decoder 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "c8b7d43206b34b3f94ea9445174bda196e772049b9bddbc620c9d29b2d20110d"
|
||||
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
|
||||
"checksum language-reporting 0.3.0 (git+https://github.com/jonathandturner/language-reporting)" = "<none>"
|
||||
"checksum language-reporting 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "628912b84af4304e1e7e78ebb6a1f503f3a973cba79d072d12e6eb40e7f815db"
|
||||
"checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73"
|
||||
"checksum lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bc5729f27f159ddd61f4df6228e827e86643d4d3e7c32183cb30a1c08f604a14"
|
||||
"checksum lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f"
|
||||
|
@ -3553,7 +3553,7 @@ dependencies = [
|
|||
"checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945"
|
||||
"checksum nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2ad2a91a8e869eeb30b9cb3119ae87773a8f4ae617f41b1eb9c154b2905f7bd6"
|
||||
"checksum nom 5.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e9761d859320e381010a4f7f8ed425f2c924de33ad121ace447367c713ad561b"
|
||||
"checksum nom_locate 0.3.1 (git+https://github.com/wycats/nom_locate.git?branch=nom5)" = "<none>"
|
||||
"checksum nom5_locate 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5cff5bb6aea818b580fbbf2793cf19b95865220f82ac0ea59d3c8443bcb71b7d"
|
||||
"checksum num-derive 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "eafd0b45c5537c3ba526f79d3e75120036502bebacbb3f3220914067ce39dbf2"
|
||||
"checksum num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "b85e541ef8255f6cf42bbfe4ef361305c6c135d10919ecc26126c4e5ae94bc09"
|
||||
"checksum num-iter 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "76bd5272412d173d6bf9afdf98db8612bbabc9a7a830b7bfc9c188911716132e"
|
||||
|
@ -3615,7 +3615,7 @@ dependencies = [
|
|||
"checksum rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071"
|
||||
"checksum rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44"
|
||||
"checksum rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c"
|
||||
"checksum rawkey 0.1.0 (git+https://github.com/jonathandturner/rawkey.git)" = "<none>"
|
||||
"checksum rawkey 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0cd49689ad95f53f9ba07322fa4fa75f08c338f5f7556eb2952705071eaf681b"
|
||||
"checksum rayon 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a4b0186e22767d5b9738a05eab7c6ac90b15db17e5b5f9bd87976dd7d89a10a4"
|
||||
"checksum rayon-core 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ebbe0df8435ac0c397d467b6cad6d25543d06e8a019ef3f6af3c384597515bd2"
|
||||
"checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"
|
||||
|
@ -3626,7 +3626,7 @@ dependencies = [
|
|||
"checksum regex 1.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "d9d8297cc20bbb6184f8b45ff61c8ee6a9ac56c156cec8e38c3e5084773c44ad"
|
||||
"checksum regex-syntax 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)" = "9d76410686f9e3a17f06128962e0ecc5755870bb890c34820c7af7f1db2e1d48"
|
||||
"checksum remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e"
|
||||
"checksum render-tree 0.1.1 (git+https://github.com/jonathandturner/language-reporting)" = "<none>"
|
||||
"checksum render-tree 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "68ed587df09cfb7ce1bc6fe8f77e24db219f222c049326ccbfb948ec67e31664"
|
||||
"checksum reqwest 0.9.18 (registry+https://github.com/rust-lang/crates.io-index)" = "00eb63f212df0e358b427f0f40aa13aaea010b470be642ad422bcbca2feff2e4"
|
||||
"checksum result 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "194d8e591e405d1eecf28819740abed6d719d1a2db87fc0bcdedee9a26d55560"
|
||||
"checksum roxmltree 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "330d8f80a274bc3cb608908ee345970e7e24b96907f1ad69615a498bec57871c"
|
||||
|
|
|
@ -41,7 +41,7 @@ serde_bytes = "0.11.1"
|
|||
getset = "0.0.7"
|
||||
logos = "0.10.0-rc2"
|
||||
logos-derive = "0.10.0-rc2"
|
||||
language-reporting = {git = "https://github.com/jonathandturner/language-reporting"}
|
||||
language-reporting = "0.3.1"
|
||||
app_dirs = "1.2.1"
|
||||
toml = "0.5.1"
|
||||
toml-query = "0.9.2"
|
||||
|
@ -56,7 +56,7 @@ ptree = "0.2"
|
|||
clipboard = "0.5"
|
||||
reqwest = "0.9"
|
||||
roxmltree = "0.6.1"
|
||||
nom_locate = { git = "https://github.com/wycats/nom_locate.git", branch = "nom5" }
|
||||
nom5_locate = "0.1.0"
|
||||
derive_more = "0.15.0"
|
||||
enum-utils = "0.1.1"
|
||||
unicode-xid = "0.1.0"
|
||||
|
@ -67,7 +67,7 @@ mime = "0.3.13"
|
|||
regex = "1.1.9"
|
||||
pretty-hex = "0.1.0"
|
||||
neso = "0.5.0"
|
||||
rawkey = { git = "https://github.com/jonathandturner/rawkey.git" }
|
||||
rawkey = "0.1.1"
|
||||
crossterm = "0.9.6"
|
||||
tempfile = "3.1.0"
|
||||
image = "0.21.2"
|
||||
|
|
59
README.md
59
README.md
|
@ -19,7 +19,7 @@ Nu draws inspiration from projects like PowerShell, functional programming langu
|
|||
In Unix, it's common to pipe between commands to split up a sophisticated command over multiple steps. Nu takes this a step further and builds heavily on the idea of _pipelines_. Just as the Unix philosophy, Nu allows commands to output from stdout and read from stdin. Additionally, commands can output structured data (you can think of this as a third kind of stream). Commands that work in the pipeline fit into one of three categories
|
||||
|
||||
* Commands that produce a stream (eg, `ls`)
|
||||
* Commands that filter a stream (eg, `where "file type" == "Directory"`)
|
||||
* Commands that filter a stream (eg, `where type == "Directory"`)
|
||||
* Commands that consumes the output of the pipeline (eg, `autoview`)
|
||||
|
||||
Commands are separated by the pipe symbol (`|`) to denote a pipeline flowing left to right.
|
||||
|
@ -93,52 +93,13 @@ Finally, we can use commands outside of Nu once we have the data we want:
|
|||
Here we use the variable `$it` to refer to the value being piped to the external command.
|
||||
|
||||
|
||||
## Navigation
|
||||
## Plugins
|
||||
|
||||
By default, Nu opens up into your filesystem and the current working directory. One way to think of this is a pair: the current object and the current path in the object. The filesystem is our first object, and the path is the cwd.
|
||||
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.
|
||||
|
||||
| object | path |
|
||||
| ------ | ---- |
|
||||
| Filesystem | /home/jonathan/Source/nushell |
|
||||
There are a few examples in the `plugins` directory.
|
||||
|
||||
Using the `cd` command allows you to change the path from the current path to a new path, just as you might expect. Using `ls` allows you to view the contents of the filesystem at the current path (or at the path of your choosing).
|
||||
|
||||
In addition to `cd` and `ls`, we can `enter` an object. Entering an object makes it the current object to navigate (similar to the concept of mounting a filesystem in Unix systems).
|
||||
|
||||
```
|
||||
/home/jonathan/Source/nushell(master)> enter Cargo.toml
|
||||
object/>
|
||||
```
|
||||
|
||||
As we enter, we create a stack of objects we're navigating:
|
||||
|
||||
| object | path |
|
||||
| ------ | ---- |
|
||||
| Filesystem | /home/jonathan/Source/nushell |
|
||||
| object (from Cargo.toml) | / |
|
||||
|
||||
Commands `cd` and `ls` now work on the object being navigated.
|
||||
|
||||
```
|
||||
object/> ls
|
||||
-----------------+------------------+-----------------
|
||||
dependencies | dev-dependencies | package
|
||||
-----------------+------------------+-----------------
|
||||
[object Object] | [object Object] | [object Object]
|
||||
-----------------+------------------+-----------------
|
||||
```
|
||||
|
||||
```
|
||||
object/> cd package/version
|
||||
object/package/version> ls
|
||||
-------
|
||||
value
|
||||
-------
|
||||
0.1.2
|
||||
-------
|
||||
```
|
||||
|
||||
The `exit` command will pop the stack and get us back to a previous object we were navigating.
|
||||
Plugins are binaries that are available in your path and follow a "nu_plugin_*" naming convention. These binaries interact with nu via a simple JSON-RPC protocol where the command identifies itself and passes along its configuration, which then makes it available for use. If the plugin is a filter, data streams to it one element at a time, and it can stream data back in return via stdin/stdout. If the plugin is a sink, it is given the full vector of final data and is given free reign over stdin/stdout to use as it pleases.
|
||||
|
||||
# Goals
|
||||
|
||||
|
@ -152,7 +113,7 @@ Nu adheres closely to a set of goals that make up its design philosophy. As feat
|
|||
|
||||
* Nu views data as both structured and unstructured. It is an object shell like PowerShell.
|
||||
|
||||
These goals are all critical, project-defining priorities. Priority #1 is "direct compatibility" because any new shell absolutely needs a way to use existing executables in a direct and natural way.
|
||||
* Finally, Nu views data functionally. Rather than using mutation, pipelines act as a mean to load, change, and save data without mutable state.
|
||||
|
||||
# Commands
|
||||
## Initial commands
|
||||
|
@ -163,8 +124,7 @@ These goals are all critical, project-defining priorities. Priority #1 is "direc
|
|||
| ps | View current processes |
|
||||
| sysinfo | View information about the current system |
|
||||
| open {filename or url} | Load a file into a cell, convert to table if possible (avoid by appending '--raw') |
|
||||
| enter {filename or url} | Enter (mount) the given contents as the current object |
|
||||
| exit | Leave/pop from the current object (exits if in filesystem object) |
|
||||
| exit | Exit the shell |
|
||||
|
||||
## Filters on tables (structured data)
|
||||
| command | description |
|
||||
|
@ -179,7 +139,7 @@ These goals are all critical, project-defining priorities. Priority #1 is "direc
|
|||
| to-array | Collapse rows into a single list |
|
||||
| to-json | Convert table into .json text |
|
||||
| to-toml | Convert table into .toml text |
|
||||
| to-ini | Convert table into .ini text |
|
||||
| to-yaml | Convert table into .yaml text |
|
||||
|
||||
## Filters on text (unstructured data)
|
||||
| command | description |
|
||||
|
@ -189,6 +149,8 @@ These goals are all critical, project-defining priorities. Priority #1 is "direc
|
|||
| from-toml | Parse text as .toml and create table |
|
||||
| from-xml | Parse text as .xml 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 |
|
||||
| size | Gather word count statistics on the text |
|
||||
| split-column sep ...fields | Split row contents across multiple columns via the separator |
|
||||
| split-row sep | Split row contents over multiple rows via the separator |
|
||||
| trim | Trim leading and following whitespace from text data |
|
||||
|
@ -198,6 +160,7 @@ These goals are all critical, project-defining priorities. Priority #1 is "direc
|
|||
| command | description |
|
||||
| ------------- | ------------- |
|
||||
| autoview | View the contents of the pipeline as a table or list |
|
||||
| binaryview | Autoview of binary data |
|
||||
| clip | Copy the contents of the pipeline to the copy/paste buffer |
|
||||
| save filename | Save the contents of the pipeline to a file |
|
||||
| table | View the contents of the pipeline as a table |
|
||||
|
|
27
src/cli.rs
27
src/cli.rs
|
@ -154,8 +154,6 @@ pub async fn cli() -> Result<(), Box<dyn Error>> {
|
|||
command("ls", Box::new(ls::ls)),
|
||||
command("sysinfo", Box::new(sysinfo::sysinfo)),
|
||||
command("cd", Box::new(cd::cd)),
|
||||
command("view", Box::new(view::view)),
|
||||
// command("skip", skip::Skip),
|
||||
command("first", Box::new(first::first)),
|
||||
command("size", Box::new(size::size)),
|
||||
command("from-ini", Box::new(from_ini::from_ini)),
|
||||
|
@ -182,7 +180,6 @@ pub async fn cli() -> Result<(), Box<dyn Error>> {
|
|||
Arc::new(Where),
|
||||
Arc::new(Config),
|
||||
Arc::new(SkipWhile),
|
||||
Arc::new(Enter),
|
||||
]);
|
||||
|
||||
context.add_sinks(vec![
|
||||
|
@ -220,22 +217,18 @@ pub async fn cli() -> Result<(), Box<dyn Error>> {
|
|||
continue;
|
||||
}
|
||||
|
||||
let (obj, cwd) = {
|
||||
let cwd = {
|
||||
let env = context.env.lock().unwrap();
|
||||
let last = env.back().unwrap();
|
||||
(last.obj().clone(), last.path().display().to_string())
|
||||
};
|
||||
let readline = match obj.item {
|
||||
Value::Filesystem => rl.readline(&format!(
|
||||
"{}{}> ",
|
||||
cwd,
|
||||
match current_branch() {
|
||||
Some(s) => format!("({})", s),
|
||||
None => "".to_string(),
|
||||
}
|
||||
)),
|
||||
_ => rl.readline(&format!("{}{}> ", obj.type_name(), cwd)),
|
||||
env.path().display().to_string()
|
||||
};
|
||||
let readline = rl.readline(&format!(
|
||||
"{}{}> ",
|
||||
cwd,
|
||||
match current_branch() {
|
||||
Some(s) => format!("({})", s),
|
||||
None => "".to_string(),
|
||||
}
|
||||
));
|
||||
|
||||
match process_line(readline, &mut context).await {
|
||||
LineResult::Success(line) => {
|
||||
|
|
|
@ -8,7 +8,6 @@ crate mod classified;
|
|||
crate mod clip;
|
||||
crate mod command;
|
||||
crate mod config;
|
||||
crate mod enter;
|
||||
crate mod exit;
|
||||
crate mod first;
|
||||
crate mod from_ini;
|
||||
|
@ -37,13 +36,11 @@ crate mod to_json;
|
|||
crate mod to_toml;
|
||||
crate mod to_yaml;
|
||||
crate mod trim;
|
||||
crate mod view;
|
||||
crate mod vtable;
|
||||
crate mod where_;
|
||||
|
||||
crate use command::command;
|
||||
crate use config::Config;
|
||||
crate use enter::Enter;
|
||||
crate use open::Open;
|
||||
crate use skip_while::SkipWhile;
|
||||
crate use where_::Where;
|
||||
|
|
|
@ -1,85 +1,52 @@
|
|||
use crate::errors::ShellError;
|
||||
use crate::prelude::*;
|
||||
use std::env;
|
||||
use std::path::PathBuf;
|
||||
|
||||
pub fn cd(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let env = args.env.lock().unwrap();
|
||||
let latest = env.back().unwrap();
|
||||
let obj = &latest.obj;
|
||||
let cwd = env.path().to_path_buf();
|
||||
|
||||
match obj.item() {
|
||||
Value::Filesystem => {
|
||||
let cwd = latest.path().to_path_buf();
|
||||
|
||||
let path = match args.nth(0) {
|
||||
None => match dirs::home_dir() {
|
||||
Some(o) => o,
|
||||
_ => {
|
||||
return Err(ShellError::maybe_labeled_error(
|
||||
"Can not change to home directory",
|
||||
"can not go to home",
|
||||
args.name_span,
|
||||
))
|
||||
}
|
||||
},
|
||||
Some(v) => {
|
||||
let target = v.as_string()?;
|
||||
match dunce::canonicalize(cwd.join(target).as_path()) {
|
||||
Ok(p) => p,
|
||||
Err(_) => {
|
||||
return Err(ShellError::labeled_error(
|
||||
"Can not change to directory",
|
||||
"directory not found",
|
||||
v.span.clone(),
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let mut stream = VecDeque::new();
|
||||
match env::set_current_dir(&path) {
|
||||
Ok(_) => {}
|
||||
let path = match args.nth(0) {
|
||||
None => match dirs::home_dir() {
|
||||
Some(o) => o,
|
||||
_ => {
|
||||
return Err(ShellError::maybe_labeled_error(
|
||||
"Can not change to home directory",
|
||||
"can not go to home",
|
||||
args.name_span,
|
||||
))
|
||||
}
|
||||
},
|
||||
Some(v) => {
|
||||
let target = v.as_string()?;
|
||||
match dunce::canonicalize(cwd.join(target).as_path()) {
|
||||
Ok(p) => p,
|
||||
Err(_) => {
|
||||
if args.len() > 0 {
|
||||
return Err(ShellError::labeled_error(
|
||||
"Can not change to directory",
|
||||
"directory not found",
|
||||
args.nth(0).unwrap().span.clone(),
|
||||
));
|
||||
} else {
|
||||
return Err(ShellError::string("Can not change to directory"));
|
||||
}
|
||||
return Err(ShellError::labeled_error(
|
||||
"Can not change to directory",
|
||||
"directory not found",
|
||||
v.span.clone(),
|
||||
));
|
||||
}
|
||||
}
|
||||
stream.push_back(ReturnSuccess::change_cwd(path));
|
||||
Ok(stream.into())
|
||||
}
|
||||
_ => {
|
||||
let mut stream = VecDeque::new();
|
||||
match args.nth(0) {
|
||||
None => {
|
||||
stream.push_back(ReturnSuccess::change_cwd(PathBuf::from("/")));
|
||||
}
|
||||
Some(v) => {
|
||||
let mut cwd = latest.path().to_path_buf();
|
||||
let target = v.as_string()?.clone();
|
||||
match target {
|
||||
x if x == ".." => {
|
||||
cwd.pop();
|
||||
}
|
||||
_ => match target.chars().nth(0) {
|
||||
Some(x) if x == '/' => cwd = PathBuf::from(target),
|
||||
_ => {
|
||||
cwd.push(target);
|
||||
}
|
||||
},
|
||||
}
|
||||
stream.push_back(ReturnSuccess::change_cwd(cwd));
|
||||
}
|
||||
};
|
||||
Ok(stream.into())
|
||||
};
|
||||
|
||||
let mut stream = VecDeque::new();
|
||||
match env::set_current_dir(&path) {
|
||||
Ok(_) => {}
|
||||
Err(_) => {
|
||||
if args.len() > 0 {
|
||||
return Err(ShellError::labeled_error(
|
||||
"Can not change to directory",
|
||||
"directory not found",
|
||||
args.nth(0).unwrap().span.clone(),
|
||||
));
|
||||
} else {
|
||||
return Err(ShellError::string("Can not change to directory"));
|
||||
}
|
||||
}
|
||||
}
|
||||
stream.push_back(ReturnSuccess::change_cwd(path));
|
||||
Ok(stream.into())
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@ use futures::stream::StreamExt;
|
|||
use futures_codec::{Decoder, Encoder, Framed};
|
||||
use log::{log_enabled, trace};
|
||||
use std::io::{Error, ErrorKind};
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
use subprocess::Exec;
|
||||
|
||||
|
@ -145,30 +144,9 @@ impl InternalCommand {
|
|||
match item? {
|
||||
ReturnSuccess::Action(action) => match action {
|
||||
CommandAction::ChangePath(path) => {
|
||||
context.env.lock().unwrap().back_mut().map(|x| {
|
||||
x.path = path;
|
||||
x
|
||||
});
|
||||
context.env.lock().unwrap().path = path;
|
||||
}
|
||||
CommandAction::Enter(obj) => {
|
||||
let new_env = Environment {
|
||||
obj: obj,
|
||||
path: PathBuf::from("/"),
|
||||
};
|
||||
context.env.lock().unwrap().push_back(new_env);
|
||||
}
|
||||
CommandAction::Exit => match context.env.lock().unwrap().pop_back() {
|
||||
Some(Environment {
|
||||
obj:
|
||||
Spanned {
|
||||
item: Value::Filesystem,
|
||||
..
|
||||
},
|
||||
..
|
||||
}) => std::process::exit(0),
|
||||
None => std::process::exit(-1),
|
||||
_ => {}
|
||||
},
|
||||
CommandAction::Exit => std::process::exit(0),
|
||||
},
|
||||
|
||||
ReturnSuccess::Value(v) => {
|
||||
|
@ -306,7 +284,7 @@ impl ExternalCommand {
|
|||
|
||||
process = Exec::shell(new_arg_string);
|
||||
}
|
||||
process = process.cwd(context.env.lock().unwrap().front().unwrap().path());
|
||||
process = process.cwd(context.env.lock().unwrap().path());
|
||||
|
||||
let mut process = match stream_next {
|
||||
StreamNext::Last => process,
|
||||
|
|
|
@ -13,7 +13,7 @@ use std::path::PathBuf;
|
|||
#[get = "crate"]
|
||||
pub struct CommandArgs {
|
||||
pub host: Arc<Mutex<dyn Host + Send>>,
|
||||
pub env: Arc<Mutex<VecDeque<Environment>>>,
|
||||
pub env: Arc<Mutex<Environment>>,
|
||||
pub name_span: Option<Span>,
|
||||
pub args: Args,
|
||||
pub input: InputStream,
|
||||
|
@ -40,6 +40,7 @@ impl CommandArgs {
|
|||
self.args.get(name)
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
pub fn has(&self, name: &str) -> bool {
|
||||
self.args.has(name)
|
||||
}
|
||||
|
@ -55,7 +56,6 @@ pub struct SinkCommandArgs {
|
|||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub enum CommandAction {
|
||||
ChangePath(PathBuf),
|
||||
Enter(Spanned<Value>),
|
||||
Exit,
|
||||
}
|
||||
|
||||
|
|
|
@ -1,105 +0,0 @@
|
|||
use crate::commands::command::CommandAction;
|
||||
use crate::commands::open::{fetch, parse_as_value};
|
||||
use crate::errors::ShellError;
|
||||
use crate::object::{Primitive, Value};
|
||||
use crate::parser::registry::{CommandConfig, PositionalType};
|
||||
use crate::prelude::*;
|
||||
use std::path::PathBuf;
|
||||
|
||||
pub struct Enter;
|
||||
|
||||
impl Command for Enter {
|
||||
fn config(&self) -> CommandConfig {
|
||||
CommandConfig {
|
||||
name: self.name().to_string(),
|
||||
positional: vec![PositionalType::mandatory_block("path")],
|
||||
rest_positional: false,
|
||||
is_filter: false,
|
||||
is_sink: false,
|
||||
named: indexmap::IndexMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
fn name(&self) -> &str {
|
||||
"enter"
|
||||
}
|
||||
|
||||
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
enter(args)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn enter(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
if args.len() == 0 {
|
||||
return Err(ShellError::maybe_labeled_error(
|
||||
"open requires a path or url",
|
||||
"missing path",
|
||||
args.name_span,
|
||||
));
|
||||
}
|
||||
|
||||
let span = args.name_span;
|
||||
|
||||
let cwd = args
|
||||
.env()
|
||||
.lock()
|
||||
.unwrap()
|
||||
.front()
|
||||
.unwrap()
|
||||
.path()
|
||||
.to_path_buf();
|
||||
|
||||
let full_path = PathBuf::from(cwd);
|
||||
|
||||
let (file_extension, contents, contents_span) = match &args.expect_nth(0)?.item {
|
||||
Value::Primitive(Primitive::String(s)) => fetch(&full_path, s, args.expect_nth(0)?.span)?,
|
||||
_ => {
|
||||
return Err(ShellError::labeled_error(
|
||||
"Expected string value for filename",
|
||||
"expected filename",
|
||||
args.expect_nth(0)?.span,
|
||||
));
|
||||
}
|
||||
};
|
||||
|
||||
let mut stream = VecDeque::new();
|
||||
|
||||
let file_extension = if args.has("raw") {
|
||||
None
|
||||
} else if args.has("json") {
|
||||
Some("json".to_string())
|
||||
} else if args.has("xml") {
|
||||
Some("xml".to_string())
|
||||
} else if args.has("ini") {
|
||||
Some("ini".to_string())
|
||||
} else if args.has("yaml") {
|
||||
Some("yaml".to_string())
|
||||
} else if args.has("toml") {
|
||||
Some("toml".to_string())
|
||||
} else {
|
||||
if let Some(ref named_args) = args.args.named {
|
||||
for named in named_args.iter() {
|
||||
return Err(ShellError::labeled_error(
|
||||
"Unknown flag for enter",
|
||||
"unknown flag",
|
||||
named.1.span.clone(),
|
||||
));
|
||||
}
|
||||
file_extension
|
||||
} else {
|
||||
file_extension
|
||||
}
|
||||
};
|
||||
|
||||
match contents {
|
||||
Value::Primitive(Primitive::String(string)) => {
|
||||
stream.push_back(Ok(ReturnSuccess::Action(CommandAction::Enter(
|
||||
parse_as_value(file_extension, string, contents_span, span)?,
|
||||
))));
|
||||
}
|
||||
|
||||
other => stream.push_back(ReturnSuccess::value(other.spanned(contents_span))),
|
||||
};
|
||||
|
||||
Ok(stream.into())
|
||||
}
|
|
@ -2,13 +2,11 @@ use crate::errors::ShellError;
|
|||
use crate::object::{dir_entry_dict, Primitive, Value};
|
||||
use crate::parser::Spanned;
|
||||
use crate::prelude::*;
|
||||
use std::ffi::OsStr;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
pub fn ls(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let env = args.env.lock().unwrap();
|
||||
let path = env.back().unwrap().path.to_path_buf();
|
||||
let obj = &env.back().unwrap().obj;
|
||||
let path = env.path.to_path_buf();
|
||||
let mut full_path = PathBuf::from(path);
|
||||
match &args.nth(0) {
|
||||
Some(Spanned {
|
||||
|
@ -18,126 +16,32 @@ pub fn ls(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
|||
_ => {}
|
||||
}
|
||||
|
||||
match obj.item {
|
||||
Value::Filesystem => {
|
||||
let entries = std::fs::read_dir(&full_path);
|
||||
let entries = std::fs::read_dir(&full_path);
|
||||
|
||||
let entries = match entries {
|
||||
Err(e) => {
|
||||
if let Some(s) = args.nth(0) {
|
||||
return Err(ShellError::labeled_error(
|
||||
e.to_string(),
|
||||
e.to_string(),
|
||||
s.span,
|
||||
));
|
||||
} else {
|
||||
return Err(ShellError::maybe_labeled_error(
|
||||
e.to_string(),
|
||||
e.to_string(),
|
||||
args.name_span,
|
||||
));
|
||||
}
|
||||
}
|
||||
Ok(o) => o,
|
||||
};
|
||||
|
||||
let mut shell_entries = VecDeque::new();
|
||||
|
||||
for entry in entries {
|
||||
let value = dir_entry_dict(&entry?, args.name_span)?;
|
||||
shell_entries.push_back(ReturnSuccess::value(value))
|
||||
let entries = match entries {
|
||||
Err(e) => {
|
||||
if let Some(s) = args.nth(0) {
|
||||
return Err(ShellError::labeled_error(
|
||||
e.to_string(),
|
||||
e.to_string(),
|
||||
s.span,
|
||||
));
|
||||
} else {
|
||||
return Err(ShellError::maybe_labeled_error(
|
||||
e.to_string(),
|
||||
e.to_string(),
|
||||
args.name_span,
|
||||
));
|
||||
}
|
||||
Ok(shell_entries.to_output_stream())
|
||||
}
|
||||
_ => {
|
||||
let mut entries = VecDeque::new();
|
||||
let mut viewed = obj;
|
||||
let sep_string = std::path::MAIN_SEPARATOR.to_string();
|
||||
let sep = OsStr::new(&sep_string);
|
||||
for p in full_path.iter() {
|
||||
//let p = p.to_string_lossy();
|
||||
match p {
|
||||
x if x == sep => {}
|
||||
step => {
|
||||
let tmp = step.to_string_lossy();
|
||||
let split_tmp = tmp.split('[');
|
||||
let mut first = true;
|
||||
Ok(o) => o,
|
||||
};
|
||||
|
||||
for s in split_tmp {
|
||||
if !first {
|
||||
match s.find(']') {
|
||||
Some(finish) => {
|
||||
let idx = s[0..finish].parse::<usize>();
|
||||
match idx {
|
||||
Ok(idx) => match viewed.get_data_by_index(idx) {
|
||||
Some(v) => {
|
||||
viewed = v;
|
||||
}
|
||||
_ => {
|
||||
return Err(ShellError::maybe_labeled_error(
|
||||
"Given incorrect index",
|
||||
format!("path given bad index: {}", idx),
|
||||
args.name_span,
|
||||
))
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
return Err(ShellError::maybe_labeled_error(
|
||||
"Given incorrect index",
|
||||
format!(
|
||||
"path index not a number: {}",
|
||||
&s[0..finish]
|
||||
),
|
||||
args.name_span,
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
return Err(ShellError::maybe_labeled_error(
|
||||
"Index not closed",
|
||||
format!("path missing closing ']'"),
|
||||
if args.len() > 0 {
|
||||
Some(args.nth(0).unwrap().span)
|
||||
} else {
|
||||
args.name_span
|
||||
},
|
||||
))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
match viewed.get_data_by_key(s) {
|
||||
Some(v) => {
|
||||
viewed = v;
|
||||
}
|
||||
_ => {
|
||||
return Err(ShellError::maybe_labeled_error(
|
||||
"Could not find key",
|
||||
format!("could not find: {}", s),
|
||||
args.name_span,
|
||||
))
|
||||
}
|
||||
}
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
match viewed {
|
||||
Spanned {
|
||||
item: Value::List(l),
|
||||
..
|
||||
} => {
|
||||
for item in l {
|
||||
entries.push_back(ReturnSuccess::value(item.clone()));
|
||||
}
|
||||
}
|
||||
x => {
|
||||
entries.push_back(ReturnSuccess::value(x.clone()));
|
||||
}
|
||||
}
|
||||
Ok(entries.to_output_stream())
|
||||
}
|
||||
let mut shell_entries = VecDeque::new();
|
||||
|
||||
for entry in entries {
|
||||
let value = dir_entry_dict(&entry?, args.name_span)?;
|
||||
shell_entries.push_back(ReturnSuccess::value(value))
|
||||
}
|
||||
Ok(shell_entries.to_output_stream())
|
||||
}
|
||||
|
|
|
@ -14,8 +14,6 @@ command! {
|
|||
.env
|
||||
.lock()
|
||||
.unwrap()
|
||||
.front()
|
||||
.unwrap()
|
||||
.path()
|
||||
.to_path_buf();
|
||||
|
||||
|
@ -39,29 +37,8 @@ command! {
|
|||
|
||||
let file_extension = if raw.is_present() {
|
||||
None
|
||||
} else if args.has("json") {
|
||||
Some("json".to_string())
|
||||
} else if args.has("xml") {
|
||||
Some("xml".to_string())
|
||||
} else if args.has("ini") {
|
||||
Some("ini".to_string())
|
||||
} else if args.has("yaml") {
|
||||
Some("yaml".to_string())
|
||||
} else if args.has("toml") {
|
||||
Some("toml".to_string())
|
||||
} else {
|
||||
if let Some(ref named_args) = args.args.named {
|
||||
for named in named_args.iter() {
|
||||
return Err(ShellError::labeled_error(
|
||||
"Unknown flag for open",
|
||||
"unknown flag",
|
||||
named.1.span.clone(),
|
||||
));
|
||||
}
|
||||
file_extension
|
||||
} else {
|
||||
file_extension
|
||||
}
|
||||
file_extension
|
||||
};
|
||||
|
||||
match contents {
|
||||
|
|
|
@ -21,15 +21,7 @@ pub fn save(args: SinkCommandArgs) -> Result<(), ShellError> {
|
|||
Some(p) => p,
|
||||
};
|
||||
|
||||
let cwd = args
|
||||
.ctx
|
||||
.env
|
||||
.lock()
|
||||
.unwrap()
|
||||
.front()
|
||||
.unwrap()
|
||||
.path()
|
||||
.to_path_buf();
|
||||
let cwd = args.ctx.env.lock().unwrap().path().to_path_buf();
|
||||
let mut full_path = PathBuf::from(cwd);
|
||||
match &(positional[0].item) {
|
||||
Value::Primitive(Primitive::String(s)) => full_path.push(Path::new(s)),
|
||||
|
|
|
@ -1,42 +1,23 @@
|
|||
use crate::errors::ShellError;
|
||||
use crate::object::{SpannedDictBuilder, Value};
|
||||
use crate::prelude::*;
|
||||
use std::fs::File;
|
||||
use std::io::prelude::*;
|
||||
|
||||
pub fn size(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
if args.len() == 0 {
|
||||
return Err(ShellError::maybe_labeled_error(
|
||||
"Size requires a filepath",
|
||||
"needs path",
|
||||
args.name_span,
|
||||
));
|
||||
}
|
||||
let cwd = args
|
||||
.env
|
||||
.lock()
|
||||
.unwrap()
|
||||
.front()
|
||||
.unwrap()
|
||||
.path()
|
||||
.to_path_buf();
|
||||
|
||||
let mut contents = String::new();
|
||||
|
||||
let mut list: VecDeque<ReturnValue> = VecDeque::new();
|
||||
for spanned_name in args.positional_iter() {
|
||||
let name = spanned_name.as_string()?;
|
||||
let path = cwd.join(&name);
|
||||
let mut file = File::open(path)?;
|
||||
file.read_to_string(&mut contents)?;
|
||||
list.push_back(count(&name, &contents, spanned_name).into());
|
||||
contents.clear();
|
||||
}
|
||||
|
||||
Ok(list.to_output_stream())
|
||||
let input = args.input;
|
||||
Ok(input
|
||||
.values
|
||||
.map(move |v| match v.item {
|
||||
Value::Primitive(Primitive::String(s)) => ReturnSuccess::value(count(&s, v.span)),
|
||||
_ => Err(ShellError::maybe_labeled_error(
|
||||
"Expected string values from pipeline",
|
||||
"expects strings from pipeline",
|
||||
Some(v.span),
|
||||
)),
|
||||
})
|
||||
.to_output_stream())
|
||||
}
|
||||
|
||||
fn count(name: &str, contents: &str, span: impl Into<Span>) -> Spanned<Value> {
|
||||
fn count(contents: &str, span: impl Into<Span>) -> Spanned<Value> {
|
||||
let mut lines: i64 = 0;
|
||||
let mut words: i64 = 0;
|
||||
let mut chars: i64 = 0;
|
||||
|
@ -62,7 +43,8 @@ fn count(name: &str, contents: &str, span: impl Into<Span>) -> Spanned<Value> {
|
|||
}
|
||||
|
||||
let mut dict = SpannedDictBuilder::new(span);
|
||||
dict.insert("name", Value::string(name));
|
||||
//TODO: add back in name when we have it in the span
|
||||
//dict.insert("name", Value::string(name));
|
||||
dict.insert("lines", Value::int(lines));
|
||||
dict.insert("words", Value::int(words));
|
||||
dict.insert("chars", Value::int(chars));
|
||||
|
|
|
@ -3,8 +3,6 @@ use crate::object::{Primitive, SpannedDictBuilder, Value};
|
|||
use crate::prelude::*;
|
||||
use log::trace;
|
||||
|
||||
// TODO: "Amount remaining" wrapper
|
||||
|
||||
pub fn split_column(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let positional: Vec<_> = args.positional_iter().cloned().collect();
|
||||
let span = args.name_span;
|
||||
|
|
|
@ -4,8 +4,6 @@ use crate::parser::Spanned;
|
|||
use crate::prelude::*;
|
||||
use log::trace;
|
||||
|
||||
// TODO: "Amount remaining" wrapper
|
||||
|
||||
pub fn split_row(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let positional: Vec<Spanned<Value>> = args.positional_iter().cloned().collect();
|
||||
let span = args.name_span;
|
||||
|
|
|
@ -19,7 +19,6 @@ pub fn value_to_json_value(v: &Value) -> serde_json::Value {
|
|||
Value::Primitive(Primitive::String(s)) => serde_json::Value::String(s.clone()),
|
||||
Value::Primitive(Primitive::Path(s)) => serde_json::Value::String(s.display().to_string()),
|
||||
|
||||
Value::Filesystem => serde_json::Value::Null,
|
||||
Value::List(l) => {
|
||||
serde_json::Value::Array(l.iter().map(|x| value_to_json_value(x)).collect())
|
||||
}
|
||||
|
|
|
@ -15,7 +15,6 @@ pub fn value_to_toml_value(v: &Value) -> toml::Value {
|
|||
Value::Primitive(Primitive::String(s)) => toml::Value::String(s.clone()),
|
||||
Value::Primitive(Primitive::Path(s)) => toml::Value::String(s.display().to_string()),
|
||||
|
||||
Value::Filesystem => toml::Value::String("<Filesystem>".to_string()),
|
||||
Value::List(l) => toml::Value::Array(l.iter().map(|x| value_to_toml_value(x)).collect()),
|
||||
Value::Block(_) => toml::Value::String("<Block>".to_string()),
|
||||
Value::Binary(b) => {
|
||||
|
|
|
@ -19,7 +19,6 @@ pub fn value_to_yaml_value(v: &Value) -> serde_yaml::Value {
|
|||
Value::Primitive(Primitive::String(s)) => serde_yaml::Value::String(s.clone()),
|
||||
Value::Primitive(Primitive::Path(s)) => serde_yaml::Value::String(s.display().to_string()),
|
||||
|
||||
Value::Filesystem => serde_yaml::Value::Null,
|
||||
Value::List(l) => {
|
||||
serde_yaml::Value::Sequence(l.iter().map(|x| value_to_yaml_value(x)).collect())
|
||||
}
|
||||
|
|
|
@ -1,50 +0,0 @@
|
|||
use crate::errors::ShellError;
|
||||
use crate::prelude::*;
|
||||
use prettyprint::PrettyPrinter;
|
||||
|
||||
pub fn view(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
if args.len() == 0 {
|
||||
return Err(ShellError::maybe_labeled_error(
|
||||
"View requires a filename",
|
||||
"needs parameter",
|
||||
args.name_span,
|
||||
));
|
||||
}
|
||||
|
||||
let target = match args.expect_nth(0)?.as_string() {
|
||||
Ok(s) => s.clone(),
|
||||
Err(e) => {
|
||||
if let Some(span) = args.name_span {
|
||||
return Err(ShellError::labeled_error(
|
||||
"Expected a string",
|
||||
"not a filename",
|
||||
span,
|
||||
));
|
||||
} else {
|
||||
return Err(e);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let cwd = args
|
||||
.env
|
||||
.lock()
|
||||
.unwrap()
|
||||
.front()
|
||||
.unwrap()
|
||||
.path()
|
||||
.to_path_buf();
|
||||
|
||||
let printer = PrettyPrinter::default()
|
||||
.line_numbers(false)
|
||||
.header(false)
|
||||
.grid(false)
|
||||
.build()
|
||||
.map_err(|e| ShellError::string(e))?;
|
||||
|
||||
let file = cwd.join(&target);
|
||||
|
||||
let _ = printer.file(file.display().to_string());
|
||||
|
||||
Ok(OutputStream::empty())
|
||||
}
|
|
@ -14,18 +14,16 @@ pub struct Context {
|
|||
commands: IndexMap<String, Arc<dyn Command>>,
|
||||
sinks: IndexMap<String, Arc<dyn Sink>>,
|
||||
crate host: Arc<Mutex<dyn Host + Send>>,
|
||||
crate env: Arc<Mutex<VecDeque<Environment>>>,
|
||||
crate env: Arc<Mutex<Environment>>,
|
||||
}
|
||||
|
||||
impl Context {
|
||||
crate fn basic() -> Result<Context, Box<dyn Error>> {
|
||||
let mut env = VecDeque::new();
|
||||
env.push_back(Environment::basic()?);
|
||||
Ok(Context {
|
||||
commands: indexmap::IndexMap::new(),
|
||||
sinks: indexmap::IndexMap::new(),
|
||||
host: Arc::new(Mutex::new(crate::env::host::BasicHost)),
|
||||
env: Arc::new(Mutex::new(env)),
|
||||
env: Arc::new(Mutex::new(Environment::basic()?)),
|
||||
})
|
||||
}
|
||||
|
||||
|
|
12
src/env/environment.rs
vendored
12
src/env/environment.rs
vendored
|
@ -1,10 +1,7 @@
|
|||
use crate::object::base::Value;
|
||||
use crate::prelude::*;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Environment {
|
||||
crate obj: Spanned<Value>,
|
||||
crate path: PathBuf,
|
||||
}
|
||||
|
||||
|
@ -12,17 +9,10 @@ impl Environment {
|
|||
pub fn basic() -> Result<Environment, std::io::Error> {
|
||||
let path = std::env::current_dir()?;
|
||||
|
||||
Ok(Environment {
|
||||
obj: Value::Filesystem.spanned_unknown(),
|
||||
path,
|
||||
})
|
||||
Ok(Environment { path })
|
||||
}
|
||||
|
||||
pub fn path(&self) -> &Path {
|
||||
self.path.as_path()
|
||||
}
|
||||
|
||||
pub fn obj(&self) -> &Spanned<Value> {
|
||||
&self.obj
|
||||
}
|
||||
}
|
||||
|
|
|
@ -98,7 +98,7 @@ impl ShellError {
|
|||
}
|
||||
|
||||
crate fn parse_error(
|
||||
error: nom::Err<(nom_locate::LocatedSpan<&str>, nom::error::ErrorKind)>,
|
||||
error: nom::Err<(nom5_locate::LocatedSpan<&str>, nom::error::ErrorKind)>,
|
||||
) -> ShellError {
|
||||
use language_reporting::*;
|
||||
|
||||
|
|
|
@ -40,11 +40,6 @@ impl RenderView for GenericView<'value> {
|
|||
host.stdout("<Binary>");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Value::Filesystem => {
|
||||
host.stdout("<filesystem>");
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -185,7 +185,6 @@ pub enum Value {
|
|||
List(Vec<Spanned<Value>>),
|
||||
#[allow(unused)]
|
||||
Block(Block),
|
||||
Filesystem,
|
||||
}
|
||||
|
||||
pub fn debug_list(values: &'a Vec<Spanned<Value>>) -> ValuesDebug<'a> {
|
||||
|
@ -215,7 +214,6 @@ impl fmt::Debug for ValueDebug<'a> {
|
|||
Value::Object(o) => o.debug(f),
|
||||
Value::List(l) => debug_list(l).fmt(f),
|
||||
Value::Block(_) => write!(f, "[[block]]"),
|
||||
Value::Filesystem => write!(f, "[[filesystem]]"),
|
||||
Value::Binary(_) => write!(f, "[[binary]]"),
|
||||
}
|
||||
}
|
||||
|
@ -300,7 +298,6 @@ impl Value {
|
|||
Value::Object(_) => format!("object"),
|
||||
Value::List(_) => format!("list"),
|
||||
Value::Block(_) => format!("block"),
|
||||
Value::Filesystem => format!("filesystem"),
|
||||
Value::Binary(_) => format!("binary"),
|
||||
}
|
||||
}
|
||||
|
@ -316,7 +313,6 @@ impl Value {
|
|||
.collect(),
|
||||
Value::Block(_) => vec![],
|
||||
Value::List(_) => vec![],
|
||||
Value::Filesystem => vec![],
|
||||
Value::Binary(_) => vec![],
|
||||
}
|
||||
}
|
||||
|
@ -343,6 +339,7 @@ impl Value {
|
|||
}
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
crate fn get_data_by_index(&'a self, idx: usize) -> Option<&Spanned<Value>> {
|
||||
match self {
|
||||
Value::List(l) => l.iter().nth(idx),
|
||||
|
@ -353,7 +350,6 @@ impl Value {
|
|||
pub fn get_data(&'a self, desc: &String) -> MaybeOwned<'a, Value> {
|
||||
match self {
|
||||
p @ Value::Primitive(_) => MaybeOwned::Borrowed(p),
|
||||
p @ Value::Filesystem => MaybeOwned::Borrowed(p),
|
||||
Value::Object(o) => o.get_data(desc),
|
||||
Value::Block(_) => MaybeOwned::Owned(Value::nothing()),
|
||||
Value::List(_) => MaybeOwned::Owned(Value::nothing()),
|
||||
|
@ -372,7 +368,6 @@ impl Value {
|
|||
),
|
||||
Value::Object(_) => format!("[object Object]"),
|
||||
Value::List(_) => format!("[list List]"),
|
||||
Value::Filesystem => format!("<filesystem>"),
|
||||
Value::Binary(_) => format!("<binary>"),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ use log::trace;
|
|||
use nom::dbg;
|
||||
use nom::*;
|
||||
use nom::{AsBytes, FindSubstring, IResult, InputLength, InputTake, Slice};
|
||||
use nom_locate::{position, LocatedSpan};
|
||||
use nom5_locate::{position, LocatedSpan};
|
||||
use std::fmt::Debug;
|
||||
use std::str::FromStr;
|
||||
|
||||
|
|
|
@ -99,8 +99,8 @@ impl From<&Span> for Span {
|
|||
}
|
||||
}
|
||||
|
||||
impl From<nom_locate::LocatedSpan<&str>> for Span {
|
||||
fn from(input: nom_locate::LocatedSpan<&str>) -> Span {
|
||||
impl From<nom5_locate::LocatedSpan<&str>> for Span {
|
||||
fn from(input: nom5_locate::LocatedSpan<&str>) -> Span {
|
||||
Span {
|
||||
start: input.offset,
|
||||
end: input.offset + input.fragment.len(),
|
||||
|
@ -108,8 +108,8 @@ impl From<nom_locate::LocatedSpan<&str>> for Span {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T> From<(nom_locate::LocatedSpan<T>, nom_locate::LocatedSpan<T>)> for Span {
|
||||
fn from(input: (nom_locate::LocatedSpan<T>, nom_locate::LocatedSpan<T>)) -> Span {
|
||||
impl<T> From<(nom5_locate::LocatedSpan<T>, nom5_locate::LocatedSpan<T>)> for Span {
|
||||
fn from(input: (nom5_locate::LocatedSpan<T>, nom5_locate::LocatedSpan<T>)) -> Span {
|
||||
Span {
|
||||
start: input.0.offset,
|
||||
end: input.1.offset,
|
||||
|
|
|
@ -32,6 +32,10 @@ impl PositionalType {
|
|||
PositionalType::Mandatory(name.to_string(), SyntaxType::Any)
|
||||
}
|
||||
|
||||
pub fn mandatory_block(name: &str) -> PositionalType {
|
||||
PositionalType::Mandatory(name.to_string(), SyntaxType::Block)
|
||||
}
|
||||
|
||||
pub fn optional(name: &str, ty: SyntaxType) -> PositionalType {
|
||||
PositionalType::Optional(name.to_string(), ty)
|
||||
}
|
||||
|
@ -40,10 +44,6 @@ impl PositionalType {
|
|||
PositionalType::Optional(name.to_string(), SyntaxType::Any)
|
||||
}
|
||||
|
||||
pub fn mandatory_block(name: &str) -> PositionalType {
|
||||
PositionalType::Mandatory(name.to_string(), SyntaxType::Block)
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
crate fn to_coerce_hint(&self) -> Option<SyntaxType> {
|
||||
match self {
|
||||
|
|
|
@ -31,7 +31,6 @@ impl TreeView {
|
|||
}
|
||||
}
|
||||
Value::Block(_) => {}
|
||||
Value::Filesystem => {}
|
||||
Value::Binary(_) => {}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,6 +46,7 @@ pub struct OutputStream {
|
|||
}
|
||||
|
||||
impl OutputStream {
|
||||
#[allow(unused)]
|
||||
pub fn empty() -> OutputStream {
|
||||
let v: VecDeque<ReturnValue> = VecDeque::new();
|
||||
v.into()
|
||||
|
|
Loading…
Reference in a new issue