2020-12-18 07:53:49 +00:00
|
|
|
use std::sync::atomic::Ordering;
|
|
|
|
|
2019-12-07 03:46:05 +00:00
|
|
|
use crate::commands::UnevaluatedCallInfo;
|
2019-11-24 22:19:12 +00:00
|
|
|
use crate::prelude::*;
|
|
|
|
use log::{log_enabled, trace};
|
2019-11-21 17:18:00 +00:00
|
|
|
use nu_errors::ShellError;
|
2020-08-07 04:53:37 +00:00
|
|
|
use nu_protocol::hir::{ExternalRedirection, InternalCommand};
|
2020-12-18 07:53:49 +00:00
|
|
|
use nu_protocol::{CommandAction, Primitive, ReturnSuccess, UntaggedValue, Value};
|
2019-11-24 22:19:12 +00:00
|
|
|
|
2020-05-29 08:22:52 +00:00
|
|
|
pub(crate) async fn run_internal_command(
|
2019-11-24 22:19:12 +00:00
|
|
|
command: InternalCommand,
|
2020-12-18 07:53:49 +00:00
|
|
|
context: &EvaluationContext,
|
Move external closer to internal (#1611)
* Refactor InputStream and affected commands.
First, making `values` private and leaning on the `Stream` implementation makes
consumes of `InputStream` less likely to have to change in the future, if we
change what an `InputStream` is internally.
Second, we're dropping `Option<InputStream>` as the input to pipelines,
internals, and externals. Instead, `InputStream.is_empty` can be used to check
for "emptiness". Empty streams are typically only ever used as the first input
to a pipeline.
* Add run_external internal command.
We want to push external commands closer to internal commands, eventually
eliminating the concept of "external" completely. This means we can consolidate
a couple of things:
- Variable evaluation (for example, `$it`, `$nu`, alias vars)
- Behaviour of whole stream vs per-item external execution
It should also make it easier for us to start introducing argument signatures
for external commands,
* Update run_external.rs
* Update run_external.rs
* Update run_external.rs
* Update run_external.rs
Co-authored-by: Jonathan Turner <jonathandturner@users.noreply.github.com>
2020-04-20 03:30:44 +00:00
|
|
|
input: InputStream,
|
|
|
|
) -> Result<InputStream, ShellError> {
|
2019-11-24 22:19:12 +00:00
|
|
|
if log_enabled!(log::Level::Trace) {
|
|
|
|
trace!(target: "nu::run::internal", "->");
|
|
|
|
trace!(target: "nu::run::internal", "{}", command.name);
|
2019-11-24 22:19:12 +00:00
|
|
|
}
|
|
|
|
|
Move external closer to internal (#1611)
* Refactor InputStream and affected commands.
First, making `values` private and leaning on the `Stream` implementation makes
consumes of `InputStream` less likely to have to change in the future, if we
change what an `InputStream` is internally.
Second, we're dropping `Option<InputStream>` as the input to pipelines,
internals, and externals. Instead, `InputStream.is_empty` can be used to check
for "emptiness". Empty streams are typically only ever used as the first input
to a pipeline.
* Add run_external internal command.
We want to push external commands closer to internal commands, eventually
eliminating the concept of "external" completely. This means we can consolidate
a couple of things:
- Variable evaluation (for example, `$it`, `$nu`, alias vars)
- Behaviour of whole stream vs per-item external execution
It should also make it easier for us to start introducing argument signatures
for external commands,
* Update run_external.rs
* Update run_external.rs
* Update run_external.rs
* Update run_external.rs
Co-authored-by: Jonathan Turner <jonathandturner@users.noreply.github.com>
2020-04-20 03:30:44 +00:00
|
|
|
let objects: InputStream = trace_stream!(target: "nu::trace_stream::internal", "input" = input);
|
2020-12-18 07:53:49 +00:00
|
|
|
|
|
|
|
let internal_command = context.scope.expect_command(&command.name);
|
2019-11-24 22:19:12 +00:00
|
|
|
|
Autoenv rewrite, security and scripting (#2083)
* Add args in .nurc file to environment
* Working dummy version
* Add add_nurc to sync_env command
* Parse .nurc file
* Delete env vars after leaving directory
* Removing vals not working, strangely
* Refactoring, add comment
* Debugging
* Debug by logging to file
* Add and remove env var behavior appears correct
However, it does not use existing code that well.
* Move work to cli.rs
* Parse config directories
* I am in a state of distress
* Rename .nurc to .nu
* Some notes for me
* Refactoring
* Removing vars works, but not done in a very nice fashion
* Refactor env_vars_to_delete
* Refactor env_vars_to_add()
* Move directory environment code to separate file
* Refactor from_config
* Restore env values
* Working?
* Working?
* Update comments and change var name
* Formatting
* Remove vars after leaving dir
* Remove notes I made
* Rename config function
* Clippy
* Cleanup and handle errors
* cargo fmt
* Better error messages, remove last (?) unwrap
* FORMAT PLZ
* Rename whitelisted_directories to allowed_directories
* Add comment to clarify how overwritten values are restored.
* Change list of allowed dirs to indexmap
* Rewrite starting
* rewrite everything
* Overwritten env values tracks an indexmap instead of vector
* Refactor restore function
* Untrack removed vars properly
* Performance concerns
* Performance concerns
* Error handling
* Clippy
* Add type aliases for String and OsString
* Deletion almost works
* Working?
* Error handling and refactoring
* nicer errors
* Add TODO file
* Move outside of loop
* Error handling
* Reworking adding of vars
* Reworking adding of vars
* Ready for testing
* Refactoring
* Restore overwritten vals code
* todo.org
* Remove overwritten values tracking, as it is not needed
* Cleanup, stop tracking overwritten values as nu takes care of it
* Init autoenv command
* Initialize autoenv and autoenv trust
* autoenv trust toml
* toml
* Use serde for autoenv
* Optional directory arg
* Add autoenv untrust command
* ... actually add autoenv untrust this time
* OsString and paths
* Revert "OsString and paths"
This reverts commit e6eedf882498c1365ecfc899e5ec11bd83cb055c.
* Fix path
* Fix path
* Autoenv trust and untrust
* Start using autoenv
* Check hashes
* Use trust functionality when setting vars
* Remove unused code
* Clippy
* Nicer errors for autoenv commands
* Non-working errors
* Update error description
* Satisfy fmt
* Errors
* Errors print, but not nicely
* Nicer errors
* fmt
* Delete accidentally added todo.org file
* Rename direnv to autoenv
* Use ShellError instead of Error
* Change tests to pass, danger zone?
* Clippy and errors
* Clippy... again
* Replace match with or_else
* Use sha2 crate for hashing
* parsing and error msg
* Refactoring
* Only apply vars once
* if parent dir
* Delete vars
* Rework exit code
* Adding works
* restore
* Fix possibility of infinite loop
* Refactoring
* Non-working
* Revert "Non-working"
This reverts commit e231b85570bcb3fc838f950e9f5004c6a7c5a2ac.
* Revert "Revert "Non-working""
This reverts commit 804092e46a752266576b044401cc97c317e41f21.
* Autoenv trust works without restart
* Cargo fix
* Script vars
* Serde
* Serde errors
* Entry and exitscripts
* Clippy
* Support windows and handle errors
* Formatting
* Fix infinite loop on windows
* Debugging windows loop
* More windows infinite loop debugging
* Windows loop debugging #3
* windows loop #4
* Don't return err
* Cleanup unused code
* Infinite loop debug
* Loop debugging
* Check if infinite loop is vars_to_add
* env_vars_to_add does not terminate, skip loop as test
* Hypothesis: std::env::current_dir() is messing with something
* Hypothesis: std::env::current_dir() is messing with something
* plz
* make clippy happy
* debugging in env_vars_to_add
* Debbuging env_vars_to_add #2
* clippy
* clippy..
* Fool clippy
* Fix another infinite loop
* Binary search for error location x)
* Binary search #3
* fmt
* Binary search #4
* more searching...
* closing in... maybe
* PLZ
* Cleanup
* Restore commented out functionality
* Handle case when user gives the directory "."
* fmt
* Use fs::canonicalize for paths
* Create optional script section
* fmt
* Add exitscripts even if no entryscripts are defined
* All sections in .nu-env are now optional
* Re-read config file each directory change
* Hot reload after autoenv untrust, don't run exitscripts if untrusted
* Debugging
* Fix issue with recursive adding of vars
* Thank you for finding my issues Mr. Azure
* use std::env
2020-07-05 17:34:00 +00:00
|
|
|
if command.name == "autoenv untrust" {
|
2020-12-18 07:53:49 +00:00
|
|
|
context
|
|
|
|
.user_recently_used_autoenv_untrust
|
|
|
|
.store(true, Ordering::SeqCst);
|
Autoenv rewrite, security and scripting (#2083)
* Add args in .nurc file to environment
* Working dummy version
* Add add_nurc to sync_env command
* Parse .nurc file
* Delete env vars after leaving directory
* Removing vals not working, strangely
* Refactoring, add comment
* Debugging
* Debug by logging to file
* Add and remove env var behavior appears correct
However, it does not use existing code that well.
* Move work to cli.rs
* Parse config directories
* I am in a state of distress
* Rename .nurc to .nu
* Some notes for me
* Refactoring
* Removing vars works, but not done in a very nice fashion
* Refactor env_vars_to_delete
* Refactor env_vars_to_add()
* Move directory environment code to separate file
* Refactor from_config
* Restore env values
* Working?
* Working?
* Update comments and change var name
* Formatting
* Remove vars after leaving dir
* Remove notes I made
* Rename config function
* Clippy
* Cleanup and handle errors
* cargo fmt
* Better error messages, remove last (?) unwrap
* FORMAT PLZ
* Rename whitelisted_directories to allowed_directories
* Add comment to clarify how overwritten values are restored.
* Change list of allowed dirs to indexmap
* Rewrite starting
* rewrite everything
* Overwritten env values tracks an indexmap instead of vector
* Refactor restore function
* Untrack removed vars properly
* Performance concerns
* Performance concerns
* Error handling
* Clippy
* Add type aliases for String and OsString
* Deletion almost works
* Working?
* Error handling and refactoring
* nicer errors
* Add TODO file
* Move outside of loop
* Error handling
* Reworking adding of vars
* Reworking adding of vars
* Ready for testing
* Refactoring
* Restore overwritten vals code
* todo.org
* Remove overwritten values tracking, as it is not needed
* Cleanup, stop tracking overwritten values as nu takes care of it
* Init autoenv command
* Initialize autoenv and autoenv trust
* autoenv trust toml
* toml
* Use serde for autoenv
* Optional directory arg
* Add autoenv untrust command
* ... actually add autoenv untrust this time
* OsString and paths
* Revert "OsString and paths"
This reverts commit e6eedf882498c1365ecfc899e5ec11bd83cb055c.
* Fix path
* Fix path
* Autoenv trust and untrust
* Start using autoenv
* Check hashes
* Use trust functionality when setting vars
* Remove unused code
* Clippy
* Nicer errors for autoenv commands
* Non-working errors
* Update error description
* Satisfy fmt
* Errors
* Errors print, but not nicely
* Nicer errors
* fmt
* Delete accidentally added todo.org file
* Rename direnv to autoenv
* Use ShellError instead of Error
* Change tests to pass, danger zone?
* Clippy and errors
* Clippy... again
* Replace match with or_else
* Use sha2 crate for hashing
* parsing and error msg
* Refactoring
* Only apply vars once
* if parent dir
* Delete vars
* Rework exit code
* Adding works
* restore
* Fix possibility of infinite loop
* Refactoring
* Non-working
* Revert "Non-working"
This reverts commit e231b85570bcb3fc838f950e9f5004c6a7c5a2ac.
* Revert "Revert "Non-working""
This reverts commit 804092e46a752266576b044401cc97c317e41f21.
* Autoenv trust works without restart
* Cargo fix
* Script vars
* Serde
* Serde errors
* Entry and exitscripts
* Clippy
* Support windows and handle errors
* Formatting
* Fix infinite loop on windows
* Debugging windows loop
* More windows infinite loop debugging
* Windows loop debugging #3
* windows loop #4
* Don't return err
* Cleanup unused code
* Infinite loop debug
* Loop debugging
* Check if infinite loop is vars_to_add
* env_vars_to_add does not terminate, skip loop as test
* Hypothesis: std::env::current_dir() is messing with something
* Hypothesis: std::env::current_dir() is messing with something
* plz
* make clippy happy
* debugging in env_vars_to_add
* Debbuging env_vars_to_add #2
* clippy
* clippy..
* Fool clippy
* Fix another infinite loop
* Binary search for error location x)
* Binary search #3
* fmt
* Binary search #4
* more searching...
* closing in... maybe
* PLZ
* Cleanup
* Restore commented out functionality
* Handle case when user gives the directory "."
* fmt
* Use fs::canonicalize for paths
* Create optional script section
* fmt
* Add exitscripts even if no entryscripts are defined
* All sections in .nu-env are now optional
* Re-read config file each directory change
* Hot reload after autoenv untrust, don't run exitscripts if untrusted
* Debugging
* Fix issue with recursive adding of vars
* Thank you for finding my issues Mr. Azure
* use std::env
2020-07-05 17:34:00 +00:00
|
|
|
}
|
|
|
|
|
2020-06-14 21:00:42 +00:00
|
|
|
let result = {
|
2020-05-29 08:22:52 +00:00
|
|
|
context
|
|
|
|
.run_command(
|
|
|
|
internal_command?,
|
|
|
|
Tag::unknown_anchor(command.name_span),
|
|
|
|
command.args.clone(),
|
|
|
|
objects,
|
|
|
|
)
|
2020-06-29 17:39:11 +00:00
|
|
|
.await?
|
2019-11-24 22:19:12 +00:00
|
|
|
};
|
2019-11-24 22:19:12 +00:00
|
|
|
|
2020-06-14 21:00:42 +00:00
|
|
|
let head = Arc::new(command.args.head.clone());
|
|
|
|
let context = context.clone();
|
|
|
|
let command = Arc::new(command);
|
2019-11-24 22:19:12 +00:00
|
|
|
|
2020-06-14 21:00:42 +00:00
|
|
|
Ok(InputStream::from_stream(
|
|
|
|
result
|
|
|
|
.then(move |item| {
|
|
|
|
let head = head.clone();
|
|
|
|
let command = command.clone();
|
2020-12-19 07:47:34 +00:00
|
|
|
let context = context.clone();
|
2020-06-14 21:00:42 +00:00
|
|
|
async move {
|
|
|
|
match item {
|
|
|
|
Ok(ReturnSuccess::Action(action)) => match action {
|
|
|
|
CommandAction::ChangePath(path) => {
|
|
|
|
context.shell_manager.set_path(path);
|
|
|
|
InputStream::from_stream(futures::stream::iter(vec![]))
|
|
|
|
}
|
|
|
|
CommandAction::Exit => std::process::exit(0), // TODO: save history.txt
|
|
|
|
CommandAction::Error(err) => {
|
|
|
|
context.error(err.clone());
|
|
|
|
InputStream::one(UntaggedValue::Error(err).into_untagged_value())
|
|
|
|
}
|
|
|
|
CommandAction::AutoConvert(tagged_contents, extension) => {
|
|
|
|
let contents_tag = tagged_contents.tag.clone();
|
|
|
|
let command_name = format!("from {}", extension);
|
|
|
|
let command = command.clone();
|
2020-12-18 07:53:49 +00:00
|
|
|
if let Some(converter) = context.scope.get_command(&command_name) {
|
2020-06-14 21:00:42 +00:00
|
|
|
let new_args = RawCommandArgs {
|
|
|
|
host: context.host.clone(),
|
|
|
|
ctrl_c: context.ctrl_c.clone(),
|
|
|
|
current_errors: context.current_errors.clone(),
|
|
|
|
shell_manager: context.shell_manager.clone(),
|
|
|
|
call_info: UnevaluatedCallInfo {
|
|
|
|
args: nu_protocol::hir::Call {
|
|
|
|
head: (&*head).clone(),
|
|
|
|
positional: None,
|
|
|
|
named: None,
|
|
|
|
span: Span::unknown(),
|
2020-08-07 04:53:37 +00:00
|
|
|
external_redirection: ExternalRedirection::Stdout,
|
2020-06-14 21:00:42 +00:00
|
|
|
},
|
|
|
|
name_tag: Tag::unknown_anchor(command.name_span),
|
|
|
|
},
|
2020-12-18 07:53:49 +00:00
|
|
|
scope: context.scope.clone(),
|
2020-06-14 21:00:42 +00:00
|
|
|
};
|
2020-06-29 17:39:11 +00:00
|
|
|
let result = converter
|
2020-12-18 07:53:49 +00:00
|
|
|
.run(new_args.with_input(vec![tagged_contents]))
|
2020-06-14 21:00:42 +00:00
|
|
|
.await;
|
2019-11-24 22:19:12 +00:00
|
|
|
|
2020-06-29 17:39:11 +00:00
|
|
|
match result {
|
|
|
|
Ok(mut result) => {
|
|
|
|
let result_vec: Vec<Result<ReturnSuccess, ShellError>> =
|
|
|
|
result.drain_vec().await;
|
|
|
|
|
|
|
|
let mut output = vec![];
|
|
|
|
for res in result_vec {
|
|
|
|
match res {
|
|
|
|
Ok(ReturnSuccess::Value(Value {
|
|
|
|
value: UntaggedValue::Table(list),
|
|
|
|
..
|
|
|
|
})) => {
|
|
|
|
for l in list {
|
|
|
|
output.push(Ok(l));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Ok(ReturnSuccess::Value(Value {
|
|
|
|
value,
|
|
|
|
..
|
|
|
|
})) => {
|
|
|
|
output
|
|
|
|
.push(Ok(value
|
|
|
|
.into_value(contents_tag.clone())));
|
|
|
|
}
|
|
|
|
Err(e) => output.push(Err(e)),
|
|
|
|
_ => {}
|
2020-06-14 21:00:42 +00:00
|
|
|
}
|
|
|
|
}
|
2020-06-29 17:39:11 +00:00
|
|
|
|
|
|
|
futures::stream::iter(output).to_input_stream()
|
|
|
|
}
|
|
|
|
Err(e) => {
|
|
|
|
context.add_error(e);
|
|
|
|
InputStream::empty()
|
2019-12-07 03:46:05 +00:00
|
|
|
}
|
|
|
|
}
|
2020-06-14 21:00:42 +00:00
|
|
|
} else {
|
|
|
|
InputStream::one(tagged_contents)
|
2019-12-07 03:46:05 +00:00
|
|
|
}
|
|
|
|
}
|
2020-06-14 21:00:42 +00:00
|
|
|
CommandAction::EnterHelpShell(value) => match value {
|
|
|
|
Value {
|
|
|
|
value: UntaggedValue::Primitive(Primitive::String(cmd)),
|
|
|
|
tag,
|
|
|
|
} => {
|
|
|
|
context.shell_manager.insert_at_current(Box::new(
|
|
|
|
match HelpShell::for_command(
|
|
|
|
UntaggedValue::string(cmd).into_value(tag),
|
2020-12-18 07:53:49 +00:00
|
|
|
&context.scope,
|
2020-06-14 21:00:42 +00:00
|
|
|
) {
|
|
|
|
Ok(v) => v,
|
|
|
|
Err(err) => {
|
|
|
|
return InputStream::one(
|
|
|
|
UntaggedValue::Error(err).into_untagged_value(),
|
|
|
|
)
|
|
|
|
}
|
|
|
|
},
|
|
|
|
));
|
|
|
|
InputStream::from_stream(futures::stream::iter(vec![]))
|
|
|
|
}
|
|
|
|
_ => {
|
|
|
|
context.shell_manager.insert_at_current(Box::new(
|
2020-12-18 07:53:49 +00:00
|
|
|
match HelpShell::index(&context.scope) {
|
2020-06-14 21:00:42 +00:00
|
|
|
Ok(v) => v,
|
|
|
|
Err(err) => {
|
|
|
|
return InputStream::one(
|
|
|
|
UntaggedValue::Error(err).into_untagged_value(),
|
|
|
|
)
|
|
|
|
}
|
|
|
|
},
|
|
|
|
));
|
|
|
|
InputStream::from_stream(futures::stream::iter(vec![]))
|
|
|
|
}
|
|
|
|
},
|
|
|
|
CommandAction::EnterValueShell(value) => {
|
|
|
|
context
|
|
|
|
.shell_manager
|
|
|
|
.insert_at_current(Box::new(ValueShell::new(value)));
|
|
|
|
InputStream::from_stream(futures::stream::iter(vec![]))
|
2019-11-24 22:19:12 +00:00
|
|
|
}
|
2020-06-14 21:00:42 +00:00
|
|
|
CommandAction::EnterShell(location) => {
|
Restructure and streamline token expansion (#1123)
Restructure and streamline token expansion
The purpose of this commit is to streamline the token expansion code, by
removing aspects of the code that are no longer relevant, removing
pointless duplication, and eliminating the need to pass the same
arguments to `expand_syntax`.
The first big-picture change in this commit is that instead of a handful
of `expand_` functions, which take a TokensIterator and ExpandContext, a
smaller number of methods on the `TokensIterator` do the same job.
The second big-picture change in this commit is fully eliminating the
coloring traits, making coloring a responsibility of the base expansion
implementations. This also means that the coloring tracer is merged into
the expansion tracer, so you can follow a single expansion and see how
the expansion process produced colored tokens.
One side effect of this change is that the expander itself is marginally
more error-correcting. The error correction works by switching from
structured expansion to `BackoffColoringMode` when an unexpected token
is found, which guarantees that all spans of the source are colored, but
may not be the most optimal error recovery strategy.
That said, because `BackoffColoringMode` only extends as far as a
closing delimiter (`)`, `]`, `}`) or pipe (`|`), it does result in
fairly granular correction strategy.
The current code still produces an `Err` (plus a complete list of
colored shapes) from the parsing process if any errors are encountered,
but this could easily be addressed now that the underlying expansion is
error-correcting.
This commit also colors any spans that are syntax errors in red, and
causes the parser to include some additional information about what
tokens were expected at any given point where an error was encountered,
so that completions and hinting could be more robust in the future.
Co-authored-by: Jonathan Turner <jonathandturner@users.noreply.github.com>
Co-authored-by: Andrés N. Robalino <andres@androbtech.com>
2020-01-21 22:45:03 +00:00
|
|
|
context.shell_manager.insert_at_current(Box::new(
|
2020-07-24 23:39:12 +00:00
|
|
|
match FilesystemShell::with_location(location) {
|
2020-06-14 21:00:42 +00:00
|
|
|
Ok(v) => v,
|
|
|
|
Err(err) => {
|
|
|
|
return InputStream::one(
|
|
|
|
UntaggedValue::Error(err.into())
|
|
|
|
.into_untagged_value(),
|
|
|
|
)
|
|
|
|
}
|
|
|
|
},
|
2019-11-24 22:19:12 +00:00
|
|
|
));
|
2020-06-14 21:00:42 +00:00
|
|
|
InputStream::from_stream(futures::stream::iter(vec![]))
|
2019-11-24 22:19:12 +00:00
|
|
|
}
|
2020-12-18 07:53:49 +00:00
|
|
|
CommandAction::AddVariable(name, value) => {
|
|
|
|
context.scope.add_var(name, value);
|
2020-06-14 21:00:42 +00:00
|
|
|
InputStream::from_stream(futures::stream::iter(vec![]))
|
|
|
|
}
|
2020-12-19 06:25:03 +00:00
|
|
|
CommandAction::AddEnvVariable(name, value) => {
|
|
|
|
context.scope.add_env_var(name, value);
|
|
|
|
InputStream::from_stream(futures::stream::iter(vec![]))
|
|
|
|
}
|
2020-12-19 07:47:34 +00:00
|
|
|
CommandAction::SourceScript(filename) => {
|
2021-01-01 04:33:38 +00:00
|
|
|
let contents = std::fs::read_to_string(&filename.item);
|
|
|
|
match contents {
|
|
|
|
Ok(contents) => {
|
|
|
|
let result = crate::script::run_script_standalone(
|
|
|
|
contents, true, &context, false,
|
|
|
|
)
|
|
|
|
.await;
|
2020-12-19 07:47:34 +00:00
|
|
|
|
2021-01-01 04:33:38 +00:00
|
|
|
if let Err(err) = result {
|
|
|
|
return InputStream::one(
|
|
|
|
UntaggedValue::Error(err.into())
|
|
|
|
.into_untagged_value(),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
InputStream::from_stream(futures::stream::iter(vec![]))
|
|
|
|
}
|
|
|
|
Err(_) => {
|
|
|
|
context.error(ShellError::labeled_error(
|
|
|
|
"Can't load file to source",
|
|
|
|
"can't load file",
|
|
|
|
filename.span(),
|
|
|
|
));
|
|
|
|
|
|
|
|
InputStream::from_stream(futures::stream::iter(vec![]))
|
2020-12-19 07:47:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-09-14 14:07:02 +00:00
|
|
|
CommandAction::AddPlugins(path) => {
|
|
|
|
match crate::plugin::scan(vec![std::path::PathBuf::from(path)]) {
|
|
|
|
Ok(plugins) => {
|
|
|
|
context.add_commands(
|
|
|
|
plugins
|
|
|
|
.into_iter()
|
|
|
|
.filter(|p| {
|
|
|
|
!context.is_command_registered(p.name())
|
|
|
|
})
|
|
|
|
.collect(),
|
|
|
|
);
|
|
|
|
|
|
|
|
InputStream::from_stream(futures::stream::iter(vec![]))
|
|
|
|
}
|
|
|
|
Err(reason) => {
|
|
|
|
context.error(reason.clone());
|
|
|
|
InputStream::one(
|
|
|
|
UntaggedValue::Error(reason).into_untagged_value(),
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-06-14 21:00:42 +00:00
|
|
|
CommandAction::PreviousShell => {
|
|
|
|
context.shell_manager.prev();
|
|
|
|
InputStream::from_stream(futures::stream::iter(vec![]))
|
|
|
|
}
|
|
|
|
CommandAction::NextShell => {
|
|
|
|
context.shell_manager.next();
|
|
|
|
InputStream::from_stream(futures::stream::iter(vec![]))
|
|
|
|
}
|
|
|
|
CommandAction::LeaveShell => {
|
|
|
|
context.shell_manager.remove_at_current();
|
|
|
|
if context.shell_manager.is_empty() {
|
|
|
|
std::process::exit(0); // TODO: save history.txt
|
|
|
|
}
|
|
|
|
InputStream::from_stream(futures::stream::iter(vec![]))
|
|
|
|
}
|
|
|
|
},
|
2020-02-09 02:24:33 +00:00
|
|
|
|
2020-06-14 21:00:42 +00:00
|
|
|
Ok(ReturnSuccess::Value(Value {
|
|
|
|
value: UntaggedValue::Error(err),
|
|
|
|
tag,
|
|
|
|
})) => {
|
|
|
|
context.error(err.clone());
|
|
|
|
InputStream::one(UntaggedValue::Error(err).into_value(tag))
|
|
|
|
}
|
2019-11-24 22:19:12 +00:00
|
|
|
|
2020-06-14 21:00:42 +00:00
|
|
|
Ok(ReturnSuccess::Value(v)) => InputStream::one(v),
|
2019-11-24 22:19:12 +00:00
|
|
|
|
2020-06-14 21:00:42 +00:00
|
|
|
Ok(ReturnSuccess::DebugValue(v)) => {
|
|
|
|
let doc = PrettyDebug::pretty_doc(&v);
|
|
|
|
let mut buffer = termcolor::Buffer::ansi();
|
2019-11-24 22:19:12 +00:00
|
|
|
|
2020-06-14 21:00:42 +00:00
|
|
|
let _ = doc.render_raw(
|
|
|
|
context.with_host(|host| host.width() - 5),
|
|
|
|
&mut nu_source::TermColored::new(&mut buffer),
|
|
|
|
);
|
2019-11-24 22:19:12 +00:00
|
|
|
|
2020-06-14 21:00:42 +00:00
|
|
|
let value = String::from_utf8_lossy(buffer.as_slice());
|
2019-11-24 22:19:12 +00:00
|
|
|
|
2020-06-14 21:00:42 +00:00
|
|
|
InputStream::one(UntaggedValue::string(value).into_untagged_value())
|
|
|
|
}
|
2019-11-24 22:19:12 +00:00
|
|
|
|
2020-06-14 21:00:42 +00:00
|
|
|
Err(err) => {
|
|
|
|
context.error(err.clone());
|
|
|
|
InputStream::one(UntaggedValue::Error(err).into_untagged_value())
|
|
|
|
}
|
|
|
|
}
|
2019-11-24 22:19:12 +00:00
|
|
|
}
|
2020-06-14 21:00:42 +00:00
|
|
|
})
|
|
|
|
.flatten()
|
|
|
|
.take_while(|x| futures::future::ready(!x.is_error())),
|
|
|
|
))
|
2019-11-24 22:19:12 +00:00
|
|
|
}
|