forked from extern/nushell
Fix incorrect handling of boolean flags for builtin commands (#11492)
# Description
Possible fix of #11456
This PR fixes a bug where builtin commands did not respect the logic of
dynamically passed boolean flags. The reason is
[has_flag](6f59abaf43/crates/nu-protocol/src/ast/call.rs (L204C5-L212C6)
)
method did not evaluate and take into consideration expression used with
flag.
To address this issue a solution is proposed:
1. `has_flag` method is moved to `CallExt` and new logic to evaluate
expression and check if it is a boolean value is added
2. `has_flag_const` method is added to `CallExt` which is a constant
version of `has_flag`
3. `has_named` method is added to `Call` which is basically the old
logic of `has_flag`
4. All usages of `has_flag` in code are updated, mostly to pass
`engine_state` and `stack` to new `has_flag`. In `run_const` commands it
is replaced with `has_flag_const`. And in a few select places: parser,
`to nuon` and `into string` old logic via `has_named` is used.
# User-Facing Changes
Explicit values of boolean flags are now respected in builtin commands.
Before:

After:

Another example:
Before:

After:

# Tests + Formatting
Added test reproducing some variants of original issue.
This commit is contained in:
@ -75,7 +75,7 @@ impl Command for BytesAdd {
|
||||
let cell_paths: Vec<CellPath> = call.rest(engine_state, stack, 1)?;
|
||||
let cell_paths = (!cell_paths.is_empty()).then_some(cell_paths);
|
||||
let index: Option<usize> = call.get_flag(engine_state, stack, "index")?;
|
||||
let end = call.has_flag("end");
|
||||
let end = call.has_flag(engine_state, stack, "end")?;
|
||||
|
||||
let arg = Arguments {
|
||||
added_data,
|
||||
|
@ -1,4 +1,4 @@
|
||||
use nu_engine::{eval_expression, CallExt};
|
||||
use nu_engine::eval_expression;
|
||||
use nu_protocol::ast::Call;
|
||||
use nu_protocol::engine::{Command, EngineState, Stack};
|
||||
use nu_protocol::{
|
||||
|
@ -73,8 +73,8 @@ impl Command for BytesIndexOf {
|
||||
let cell_paths = (!cell_paths.is_empty()).then_some(cell_paths);
|
||||
let arg = Arguments {
|
||||
pattern,
|
||||
end: call.has_flag("end"),
|
||||
all: call.has_flag("all"),
|
||||
end: call.has_flag(engine_state, stack, "end")?,
|
||||
all: call.has_flag(engine_state, stack, "all")?,
|
||||
cell_paths,
|
||||
};
|
||||
operate(index_of, arg, input, call.head, engine_state.ctrlc.clone())
|
||||
|
@ -74,9 +74,9 @@ impl Command for BytesRemove {
|
||||
let pattern_to_remove: Vec<u8> = pattern_to_remove.item;
|
||||
let arg = Arguments {
|
||||
pattern: pattern_to_remove,
|
||||
end: call.has_flag("end"),
|
||||
end: call.has_flag(engine_state, stack, "end")?,
|
||||
cell_paths,
|
||||
all: call.has_flag("all"),
|
||||
all: call.has_flag(engine_state, stack, "all")?,
|
||||
};
|
||||
|
||||
operate(remove, arg, input, call.head, engine_state.ctrlc.clone())
|
||||
|
@ -76,7 +76,7 @@ impl Command for BytesReplace {
|
||||
find: find.item,
|
||||
replace: call.req::<Vec<u8>>(engine_state, stack, 1)?,
|
||||
cell_paths,
|
||||
all: call.has_flag("all"),
|
||||
all: call.has_flag(engine_state, stack, "all")?,
|
||||
};
|
||||
|
||||
operate(replace, arg, input, call.head, engine_state.ctrlc.clone())
|
||||
|
@ -148,7 +148,7 @@ fn into_binary(
|
||||
_ => {
|
||||
let args = Arguments {
|
||||
cell_paths,
|
||||
compact: call.has_flag("compact"),
|
||||
compact: call.has_flag(engine_state, stack, "compact")?,
|
||||
};
|
||||
operate(action, args, input, call.head, engine_state.ctrlc.clone())
|
||||
}
|
||||
|
@ -116,9 +116,9 @@ impl Command for SubCommand {
|
||||
call: &Call,
|
||||
input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
if call.has_flag("list") {
|
||||
if call.has_flag(engine_state, stack, "list")? {
|
||||
Ok(generate_strftime_list(call.head, true).into_pipeline_data())
|
||||
} else if call.has_flag("list-human") {
|
||||
} else if call.has_flag(engine_state, stack, "list-human")? {
|
||||
Ok(list_human_readable_examples(call.head).into_pipeline_data())
|
||||
} else {
|
||||
let cell_paths = call.rest(engine_state, stack, 0)?;
|
||||
|
@ -11,7 +11,6 @@ use num_format::ToFormattedString;
|
||||
|
||||
struct Arguments {
|
||||
decimals_value: Option<i64>,
|
||||
decimals: bool,
|
||||
cell_paths: Option<Vec<CellPath>>,
|
||||
config: Config,
|
||||
}
|
||||
@ -148,11 +147,10 @@ fn string_helper(
|
||||
call: &Call,
|
||||
input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let decimals = call.has_flag("decimals");
|
||||
let head = call.head;
|
||||
let decimals_value: Option<i64> = call.get_flag(engine_state, stack, "decimals")?;
|
||||
if let Some(decimal_val) = decimals_value {
|
||||
if decimals && decimal_val.is_negative() {
|
||||
if decimal_val.is_negative() {
|
||||
return Err(ShellError::TypeMismatch {
|
||||
err_message: "Cannot accept negative integers for decimals arguments".to_string(),
|
||||
span: head,
|
||||
@ -164,7 +162,6 @@ fn string_helper(
|
||||
let config = engine_state.get_config().clone();
|
||||
let args = Arguments {
|
||||
decimals_value,
|
||||
decimals,
|
||||
cell_paths,
|
||||
config,
|
||||
};
|
||||
@ -186,7 +183,6 @@ fn string_helper(
|
||||
}
|
||||
|
||||
fn action(input: &Value, args: &Arguments, span: Span) -> Value {
|
||||
let decimals = args.decimals;
|
||||
let digits = args.decimals_value;
|
||||
let config = &args.config;
|
||||
match input {
|
||||
@ -196,8 +192,8 @@ fn action(input: &Value, args: &Arguments, span: Span) -> Value {
|
||||
Value::string(res, span)
|
||||
}
|
||||
Value::Float { val, .. } => {
|
||||
if decimals {
|
||||
let decimal_value = digits.unwrap_or(2) as usize;
|
||||
if let Some(decimal_value) = digits {
|
||||
let decimal_value = decimal_value as usize;
|
||||
Value::string(format!("{val:.decimal_value$}"), span)
|
||||
} else {
|
||||
Value::string(val.to_string(), span)
|
||||
|
@ -41,8 +41,8 @@ impl Command for Ast {
|
||||
_input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let pipeline: Spanned<String> = call.req(engine_state, stack, 0)?;
|
||||
let to_json = call.has_flag("json");
|
||||
let minify = call.has_flag("minify");
|
||||
let to_json = call.has_flag(engine_state, stack, "json")?;
|
||||
let minify = call.has_flag(engine_state, stack, "minify")?;
|
||||
let mut working_set = StateWorkingSet::new(engine_state);
|
||||
let block_output = parse(&mut working_set, None, pipeline.item.as_bytes(), false);
|
||||
let error_output = working_set.parse_errors.first();
|
||||
|
@ -1,3 +1,4 @@
|
||||
use nu_engine::CallExt;
|
||||
use nu_protocol::ast::Call;
|
||||
use nu_protocol::engine::{Command, EngineState, Stack};
|
||||
use nu_protocol::{Category, Example, PipelineData, ShellError, Signature, Span, Type, Value};
|
||||
@ -31,13 +32,13 @@ impl Command for Debug {
|
||||
fn run(
|
||||
&self,
|
||||
engine_state: &EngineState,
|
||||
_stack: &mut Stack,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let head = call.head;
|
||||
let config = engine_state.get_config().clone();
|
||||
let raw = call.has_flag("raw");
|
||||
let raw = call.has_flag(engine_state, stack, "raw")?;
|
||||
|
||||
// Should PipelineData::Empty result in an error here?
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
use nu_engine::env_to_strings;
|
||||
use nu_engine::{env_to_strings, CallExt};
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EngineState, Stack},
|
||||
@ -59,7 +59,7 @@ impl Command for ConfigEnv {
|
||||
input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
// `--default` flag handling
|
||||
if call.has_flag("default") {
|
||||
if call.has_flag(engine_state, stack, "default")? {
|
||||
let head = call.head;
|
||||
return Ok(Value::string(nu_utils::get_default_env(), head).into_pipeline_data());
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
use nu_engine::env_to_strings;
|
||||
use nu_engine::{env_to_strings, CallExt};
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EngineState, Stack},
|
||||
@ -63,7 +63,7 @@ impl Command for ConfigNu {
|
||||
input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
// `--default` flag handling
|
||||
if call.has_flag("default") {
|
||||
if call.has_flag(engine_state, stack, "default")? {
|
||||
let head = call.head;
|
||||
return Ok(Value::string(nu_utils::get_default_config(), head).into_pipeline_data());
|
||||
}
|
||||
|
11
crates/nu-command/src/env/config/config_reset.rs
vendored
11
crates/nu-command/src/env/config/config_reset.rs
vendored
@ -1,4 +1,5 @@
|
||||
use chrono::Local;
|
||||
use nu_engine::CallExt;
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EngineState, Stack},
|
||||
@ -39,14 +40,14 @@ impl Command for ConfigReset {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
_engine_state: &EngineState,
|
||||
_stack: &mut Stack,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
_input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let only_nu = call.has_flag("nu");
|
||||
let only_env = call.has_flag("env");
|
||||
let no_backup = call.has_flag("without-backup");
|
||||
let only_nu = call.has_flag(engine_state, stack, "nu")?;
|
||||
let only_env = call.has_flag(engine_state, stack, "env")?;
|
||||
let no_backup = call.has_flag(engine_state, stack, "without-backup")?;
|
||||
let span = call.head;
|
||||
let mut config_path = match nu_path::config_dir() {
|
||||
Some(path) => path,
|
||||
|
@ -76,11 +76,11 @@ impl Command for Cp {
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let src: Spanned<String> = call.req(engine_state, stack, 0)?;
|
||||
let dst: Spanned<String> = call.req(engine_state, stack, 1)?;
|
||||
let recursive = call.has_flag("recursive");
|
||||
let verbose = call.has_flag("verbose");
|
||||
let interactive = call.has_flag("interactive");
|
||||
let progress = call.has_flag("progress");
|
||||
let update_mode = call.has_flag("update");
|
||||
let recursive = call.has_flag(engine_state, stack, "recursive")?;
|
||||
let verbose = call.has_flag(engine_state, stack, "verbose")?;
|
||||
let interactive = call.has_flag(engine_state, stack, "interactive")?;
|
||||
let progress = call.has_flag(engine_state, stack, "progress")?;
|
||||
let update_mode = call.has_flag(engine_state, stack, "update")?;
|
||||
|
||||
let current_dir_path = current_dir(engine_state, stack)?;
|
||||
let destination = current_dir_path.join(dst.item.as_str());
|
||||
@ -229,7 +229,7 @@ impl Command for Cp {
|
||||
inner: vec![],
|
||||
})?;
|
||||
|
||||
let not_follow_symlink = call.has_flag("no-symlink");
|
||||
let not_follow_symlink = call.has_flag(engine_state, stack, "no-symlink")?;
|
||||
let sources = sources.paths_applying_with(|(source_file, depth_level)| {
|
||||
let mut dest = destination.clone();
|
||||
|
||||
|
@ -137,9 +137,9 @@ impl Command for Glob {
|
||||
let span = call.head;
|
||||
let glob_pattern: Spanned<String> = call.req(engine_state, stack, 0)?;
|
||||
let depth = call.get_flag(engine_state, stack, "depth")?;
|
||||
let no_dirs = call.has_flag("no-dir");
|
||||
let no_files = call.has_flag("no-file");
|
||||
let no_symlinks = call.has_flag("no-symlink");
|
||||
let no_dirs = call.has_flag(engine_state, stack, "no-dir")?;
|
||||
let no_files = call.has_flag(engine_state, stack, "no-file")?;
|
||||
let no_symlinks = call.has_flag(engine_state, stack, "no-symlink")?;
|
||||
|
||||
let paths_to_exclude: Option<Value> = call.get_flag(engine_state, stack, "exclude")?;
|
||||
|
||||
|
@ -73,13 +73,13 @@ impl Command for Ls {
|
||||
call: &Call,
|
||||
_input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let all = call.has_flag("all");
|
||||
let long = call.has_flag("long");
|
||||
let short_names = call.has_flag("short-names");
|
||||
let full_paths = call.has_flag("full-paths");
|
||||
let du = call.has_flag("du");
|
||||
let directory = call.has_flag("directory");
|
||||
let use_mime_type = call.has_flag("mime-type");
|
||||
let all = call.has_flag(engine_state, stack, "all")?;
|
||||
let long = call.has_flag(engine_state, stack, "long")?;
|
||||
let short_names = call.has_flag(engine_state, stack, "short-names")?;
|
||||
let full_paths = call.has_flag(engine_state, stack, "full-paths")?;
|
||||
let du = call.has_flag(engine_state, stack, "du")?;
|
||||
let directory = call.has_flag(engine_state, stack, "directory")?;
|
||||
let use_mime_type = call.has_flag(engine_state, stack, "mime-type")?;
|
||||
let ctrl_c = engine_state.ctrlc.clone();
|
||||
let call_span = call.head;
|
||||
let cwd = current_dir(engine_state, stack)?;
|
||||
|
@ -51,7 +51,7 @@ impl Command for Mkdir {
|
||||
.map(|dir| path.join(dir))
|
||||
.peekable();
|
||||
|
||||
let is_verbose = call.has_flag("verbose");
|
||||
let is_verbose = call.has_flag(engine_state, stack, "verbose")?;
|
||||
let mut stream: VecDeque<Value> = VecDeque::new();
|
||||
|
||||
if directories.peek().is_none() {
|
||||
|
@ -84,9 +84,9 @@ impl Command for Mktemp {
|
||||
.cloned()
|
||||
.map(|i: Spanned<String>| i.item)
|
||||
.unwrap_or("tmp.XXXXXXXXXX".to_string()); // same as default in coreutils
|
||||
let directory = call.has_flag("directory");
|
||||
let directory = call.has_flag(engine_state, stack, "directory")?;
|
||||
let suffix = call.get_flag(engine_state, stack, "suffix")?;
|
||||
let tmpdir = call.has_flag("tmpdir");
|
||||
let tmpdir = call.has_flag(engine_state, stack, "tmpdir")?;
|
||||
let tmpdir_path = call
|
||||
.get_flag(engine_state, stack, "tmpdir-path")?
|
||||
.map(|i: Spanned<PathBuf>| i.item);
|
||||
|
@ -65,10 +65,10 @@ impl Command for Mv {
|
||||
// TODO: handle invalid directory or insufficient permissions when moving
|
||||
let spanned_source: Spanned<String> = call.req(engine_state, stack, 0)?;
|
||||
let spanned_destination: Spanned<String> = call.req(engine_state, stack, 1)?;
|
||||
let verbose = call.has_flag("verbose");
|
||||
let interactive = call.has_flag("interactive");
|
||||
let force = call.has_flag("force");
|
||||
let update_mode = call.has_flag("update");
|
||||
let verbose = call.has_flag(engine_state, stack, "verbose")?;
|
||||
let interactive = call.has_flag(engine_state, stack, "interactive")?;
|
||||
let force = call.has_flag(engine_state, stack, "force")?;
|
||||
let update_mode = call.has_flag(engine_state, stack, "update")?;
|
||||
|
||||
let ctrlc = engine_state.ctrlc.clone();
|
||||
|
||||
|
@ -59,7 +59,7 @@ impl Command for Open {
|
||||
call: &Call,
|
||||
input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let raw = call.has_flag("raw");
|
||||
let raw = call.has_flag(engine_state, stack, "raw")?;
|
||||
let call_span = call.head;
|
||||
let ctrlc = engine_state.ctrlc.clone();
|
||||
let cwd = current_dir(engine_state, stack)?;
|
||||
|
@ -124,13 +124,13 @@ fn rm(
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let trash = call.has_flag("trash");
|
||||
let permanent = call.has_flag("permanent");
|
||||
let recursive = call.has_flag("recursive");
|
||||
let force = call.has_flag("force");
|
||||
let verbose = call.has_flag("verbose");
|
||||
let interactive = call.has_flag("interactive");
|
||||
let interactive_once = call.has_flag("interactive-once") && !interactive;
|
||||
let trash = call.has_flag(engine_state, stack, "trash")?;
|
||||
let permanent = call.has_flag(engine_state, stack, "permanent")?;
|
||||
let recursive = call.has_flag(engine_state, stack, "recursive")?;
|
||||
let force = call.has_flag(engine_state, stack, "force")?;
|
||||
let verbose = call.has_flag(engine_state, stack, "verbose")?;
|
||||
let interactive = call.has_flag(engine_state, stack, "interactive")?;
|
||||
let interactive_once = call.has_flag(engine_state, stack, "interactive-once")? && !interactive;
|
||||
|
||||
let ctrlc = engine_state.ctrlc.clone();
|
||||
|
||||
|
@ -63,10 +63,10 @@ impl Command for Save {
|
||||
call: &Call,
|
||||
input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let raw = call.has_flag("raw");
|
||||
let append = call.has_flag("append");
|
||||
let force = call.has_flag("force");
|
||||
let progress = call.has_flag("progress");
|
||||
let raw = call.has_flag(engine_state, stack, "raw")?;
|
||||
let append = call.has_flag(engine_state, stack, "append")?;
|
||||
let force = call.has_flag(engine_state, stack, "force")?;
|
||||
let progress = call.has_flag(engine_state, stack, "progress")?;
|
||||
let out_append = if let Some(Expression {
|
||||
expr: Expr::Bool(out_append),
|
||||
..
|
||||
|
@ -67,10 +67,10 @@ impl Command for Touch {
|
||||
call: &Call,
|
||||
_input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let mut change_mtime: bool = call.has_flag("modified");
|
||||
let mut change_atime: bool = call.has_flag("access");
|
||||
let use_reference: bool = call.has_flag("reference");
|
||||
let no_create: bool = call.has_flag("no-create");
|
||||
let mut change_mtime: bool = call.has_flag(engine_state, stack, "modified")?;
|
||||
let mut change_atime: bool = call.has_flag(engine_state, stack, "access")?;
|
||||
let use_reference: bool = call.has_flag(engine_state, stack, "reference")?;
|
||||
let no_create: bool = call.has_flag(engine_state, stack, "no-create")?;
|
||||
let target: String = call.req(engine_state, stack, 0)?;
|
||||
let rest: Vec<String> = call.rest(engine_state, stack, 1)?;
|
||||
|
||||
|
@ -96,19 +96,19 @@ impl Command for UCp {
|
||||
call: &Call,
|
||||
_input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let interactive = call.has_flag("interactive");
|
||||
let (update, copy_mode) = if call.has_flag("update") {
|
||||
let interactive = call.has_flag(engine_state, stack, "interactive")?;
|
||||
let (update, copy_mode) = if call.has_flag(engine_state, stack, "update")? {
|
||||
(UpdateMode::ReplaceIfOlder, CopyMode::Update)
|
||||
} else {
|
||||
(UpdateMode::ReplaceAll, CopyMode::Copy)
|
||||
};
|
||||
let force = call.has_flag("force");
|
||||
let no_clobber = call.has_flag("no-clobber");
|
||||
let progress = call.has_flag("progress");
|
||||
let recursive = call.has_flag("recursive");
|
||||
let verbose = call.has_flag("verbose");
|
||||
let force = call.has_flag(engine_state, stack, "force")?;
|
||||
let no_clobber = call.has_flag(engine_state, stack, "no-clobber")?;
|
||||
let progress = call.has_flag(engine_state, stack, "progress")?;
|
||||
let recursive = call.has_flag(engine_state, stack, "recursive")?;
|
||||
let verbose = call.has_flag(engine_state, stack, "verbose")?;
|
||||
|
||||
let debug = call.has_flag("debug");
|
||||
let debug = call.has_flag(engine_state, stack, "debug")?;
|
||||
let overwrite = if no_clobber {
|
||||
uu_cp::OverwriteMode::NoClobber
|
||||
} else if interactive {
|
||||
|
@ -57,7 +57,7 @@ impl Command for UMkdir {
|
||||
.map(|dir| nu_path::expand_path_with(dir, &cwd))
|
||||
.peekable();
|
||||
|
||||
let is_verbose = call.has_flag("verbose");
|
||||
let is_verbose = call.has_flag(engine_state, stack, "verbose")?;
|
||||
|
||||
if directories.peek().is_none() {
|
||||
return Err(ShellError::MissingParameter {
|
||||
|
@ -96,7 +96,7 @@ impl Command for Watch {
|
||||
.get_block(capture_block.block_id)
|
||||
.clone();
|
||||
|
||||
let verbose = call.has_flag("verbose");
|
||||
let verbose = call.has_flag(engine_state, stack, "verbose")?;
|
||||
|
||||
let debounce_duration_flag: Option<Spanned<i64>> =
|
||||
call.get_flag(engine_state, stack, "debounce-ms")?;
|
||||
|
@ -51,7 +51,7 @@ impl Command for Compact {
|
||||
call: &Call,
|
||||
input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let empty = call.has_flag("empty");
|
||||
let empty = call.has_flag(engine_state, stack, "empty")?;
|
||||
compact(engine_state, stack, call, input, empty)
|
||||
}
|
||||
|
||||
|
@ -114,7 +114,7 @@ with 'transpose' first."#
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let capture_block: Closure = call.req(engine_state, stack, 0)?;
|
||||
|
||||
let keep_empty = call.has_flag("keep-empty");
|
||||
let keep_empty = call.has_flag(engine_state, stack, "keep-empty")?;
|
||||
|
||||
let metadata = input.metadata();
|
||||
let ctrlc = engine_state.ctrlc.clone();
|
||||
|
@ -71,7 +71,7 @@ impl Command for Every {
|
||||
stride => stride,
|
||||
};
|
||||
|
||||
let skip = call.has_flag("skip");
|
||||
let skip = call.has_flag(engine_state, stack, "skip")?;
|
||||
|
||||
let metadata = input.metadata();
|
||||
|
||||
|
@ -219,7 +219,7 @@ impl Command for Find {
|
||||
fn find_with_regex(
|
||||
regex: String,
|
||||
engine_state: &EngineState,
|
||||
_stack: &mut Stack,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
@ -227,10 +227,10 @@ fn find_with_regex(
|
||||
let ctrlc = engine_state.ctrlc.clone();
|
||||
let config = engine_state.get_config().clone();
|
||||
|
||||
let insensitive = call.has_flag("ignore-case");
|
||||
let multiline = call.has_flag("multiline");
|
||||
let dotall = call.has_flag("dotall");
|
||||
let invert = call.has_flag("invert");
|
||||
let insensitive = call.has_flag(engine_state, stack, "ignore-case")?;
|
||||
let multiline = call.has_flag(engine_state, stack, "multiline")?;
|
||||
let dotall = call.has_flag(engine_state, stack, "dotall")?;
|
||||
let invert = call.has_flag(engine_state, stack, "invert")?;
|
||||
|
||||
let flags = match (insensitive, multiline, dotall) {
|
||||
(false, false, false) => "",
|
||||
@ -336,7 +336,7 @@ fn find_with_rest_and_highlight(
|
||||
let engine_state = engine_state.clone();
|
||||
let config = engine_state.get_config().clone();
|
||||
let filter_config = engine_state.get_config().clone();
|
||||
let invert = call.has_flag("invert");
|
||||
let invert = call.has_flag(&engine_state, stack, "invert")?;
|
||||
let terms = call.rest::<Value>(&engine_state, stack, 0)?;
|
||||
let lower_terms = terms
|
||||
.iter()
|
||||
|
@ -128,7 +128,7 @@ fn flatten(
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let columns: Vec<CellPath> = call.rest(engine_state, stack, 0)?;
|
||||
let metadata = input.metadata();
|
||||
let flatten_all = call.has_flag("all");
|
||||
let flatten_all = call.has_flag(engine_state, stack, "all")?;
|
||||
|
||||
input
|
||||
.flat_map(
|
||||
|
@ -66,8 +66,8 @@ If multiple cell paths are given, this will produce a list of values."#
|
||||
let span = call.head;
|
||||
let mut cell_path: CellPath = call.req(engine_state, stack, 0)?;
|
||||
let mut rest: Vec<CellPath> = call.rest(engine_state, stack, 1)?;
|
||||
let ignore_errors = call.has_flag("ignore-errors");
|
||||
let sensitive = call.has_flag("sensitive");
|
||||
let ignore_errors = call.has_flag(engine_state, stack, "ignore-errors")?;
|
||||
let sensitive = call.has_flag(engine_state, stack, "sensitive")?;
|
||||
let ctrlc = engine_state.ctrlc.clone();
|
||||
let metadata = input.metadata();
|
||||
|
||||
|
@ -188,7 +188,7 @@ pub fn group_by(
|
||||
None => group_no_grouper(values)?,
|
||||
};
|
||||
|
||||
let value = if call.has_flag("to-table") {
|
||||
let value = if call.has_flag(engine_state, stack, "to-table")? {
|
||||
groups_to_table(groups, span)
|
||||
} else {
|
||||
groups_to_record(groups, span)
|
||||
|
@ -75,7 +75,7 @@ impl Command for Join {
|
||||
.opt(engine_state, stack, 2)?
|
||||
.unwrap_or_else(|| l_on.clone());
|
||||
let span = call.head;
|
||||
let join_type = join_type(call)?;
|
||||
let join_type = join_type(engine_state, stack, call)?;
|
||||
|
||||
// FIXME: we should handle ListStreams properly instead of collecting
|
||||
let collected_input = input.into_value(span);
|
||||
@ -116,12 +116,16 @@ impl Command for Join {
|
||||
}
|
||||
}
|
||||
|
||||
fn join_type(call: &Call) -> Result<JoinType, nu_protocol::ShellError> {
|
||||
fn join_type(
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
) -> Result<JoinType, nu_protocol::ShellError> {
|
||||
match (
|
||||
call.has_flag("inner"),
|
||||
call.has_flag("left"),
|
||||
call.has_flag("right"),
|
||||
call.has_flag("outer"),
|
||||
call.has_flag(engine_state, stack, "inner")?,
|
||||
call.has_flag(engine_state, stack, "left")?,
|
||||
call.has_flag(engine_state, stack, "right")?,
|
||||
call.has_flag(engine_state, stack, "outer")?,
|
||||
) {
|
||||
(_, false, false, false) => Ok(JoinType::Inner),
|
||||
(false, true, false, false) => Ok(JoinType::Left),
|
||||
|
@ -1,3 +1,4 @@
|
||||
use nu_engine::CallExt;
|
||||
use nu_protocol::ast::Call;
|
||||
use nu_protocol::engine::{Command, EngineState, Stack};
|
||||
use nu_protocol::{
|
||||
@ -30,13 +31,13 @@ impl Command for Lines {
|
||||
fn run(
|
||||
&self,
|
||||
engine_state: &EngineState,
|
||||
_stack: &mut Stack,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let head = call.head;
|
||||
let ctrlc = engine_state.ctrlc.clone();
|
||||
let skip_empty = call.has_flag("skip-empty");
|
||||
let skip_empty = call.has_flag(engine_state, stack, "skip-empty")?;
|
||||
|
||||
// match \r\n or \n
|
||||
static LINE_BREAK_REGEX: Lazy<Regex> =
|
||||
|
@ -121,7 +121,7 @@ impl Command for ParEach {
|
||||
let capture_block: Closure = call.req(engine_state, stack, 0)?;
|
||||
let threads: Option<usize> = call.get_flag(engine_state, stack, "threads")?;
|
||||
let max_threads = threads.unwrap_or(0);
|
||||
let keep_order = call.has_flag("keep-order");
|
||||
let keep_order = call.has_flag(engine_state, stack, "keep-order")?;
|
||||
let metadata = input.metadata();
|
||||
let ctrlc = engine_state.ctrlc.clone();
|
||||
let outer_ctrlc = engine_state.ctrlc.clone();
|
||||
|
@ -133,7 +133,7 @@ impl Command for Reject {
|
||||
}
|
||||
let span = call.head;
|
||||
|
||||
let ignore_errors = call.has_flag("ignore-errors");
|
||||
let ignore_errors = call.has_flag(engine_state, stack, "ignore-errors")?;
|
||||
if ignore_errors {
|
||||
for cell_path in &mut new_columns {
|
||||
cell_path.make_optional();
|
||||
|
@ -137,7 +137,7 @@ produce a table, a list will produce a list, and a record will produce a record.
|
||||
}
|
||||
}
|
||||
}
|
||||
let ignore_errors = call.has_flag("ignore-errors");
|
||||
let ignore_errors = call.has_flag(engine_state, stack, "ignore-errors")?;
|
||||
let span = call.head;
|
||||
|
||||
if ignore_errors {
|
||||
@ -235,7 +235,7 @@ fn select(
|
||||
let columns = new_columns;
|
||||
|
||||
let input = if !unique_rows.is_empty() {
|
||||
// let skip = call.has_flag("skip");
|
||||
// let skip = call.has_flag(engine_state, stack, "skip")?;
|
||||
let metadata = input.metadata();
|
||||
let pipeline_iter: PipelineIterator = input.into_iter();
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
use alphanumeric_sort::compare_str;
|
||||
use nu_engine::CallExt;
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EngineState, Stack},
|
||||
@ -134,20 +135,20 @@ impl Command for Sort {
|
||||
fn run(
|
||||
&self,
|
||||
engine_state: &EngineState,
|
||||
_stack: &mut Stack,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let reverse = call.has_flag("reverse");
|
||||
let insensitive = call.has_flag("ignore-case");
|
||||
let natural = call.has_flag("natural");
|
||||
let reverse = call.has_flag(engine_state, stack, "reverse")?;
|
||||
let insensitive = call.has_flag(engine_state, stack, "ignore-case")?;
|
||||
let natural = call.has_flag(engine_state, stack, "natural")?;
|
||||
let metadata = &input.metadata();
|
||||
|
||||
let span = input.span().unwrap_or(call.head);
|
||||
match input {
|
||||
// Records have two sorting methods, toggled by presence or absence of -v
|
||||
PipelineData::Value(Value::Record { val, .. }, ..) => {
|
||||
let sort_by_value = call.has_flag("values");
|
||||
let sort_by_value = call.has_flag(engine_state, stack, "values")?;
|
||||
let record = sort_record(val, span, sort_by_value, reverse, insensitive, natural);
|
||||
Ok(record.into_pipeline_data())
|
||||
}
|
||||
|
@ -85,9 +85,9 @@ impl Command for SortBy {
|
||||
input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let columns: Vec<String> = call.rest(engine_state, stack, 0)?;
|
||||
let reverse = call.has_flag("reverse");
|
||||
let insensitive = call.has_flag("ignore-case");
|
||||
let natural = call.has_flag("natural");
|
||||
let reverse = call.has_flag(engine_state, stack, "reverse")?;
|
||||
let insensitive = call.has_flag(engine_state, stack, "ignore-case")?;
|
||||
let natural = call.has_flag(engine_state, stack, "natural")?;
|
||||
let metadata = &input.metadata();
|
||||
let mut vec: Vec<_> = input.into_iter_strict(call.head)?.collect();
|
||||
|
||||
|
@ -145,11 +145,11 @@ pub fn transpose(
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let name = call.head;
|
||||
let args = TransposeArgs {
|
||||
header_row: call.has_flag("header-row"),
|
||||
ignore_titles: call.has_flag("ignore-titles"),
|
||||
as_record: call.has_flag("as-record"),
|
||||
keep_last: call.has_flag("keep-last"),
|
||||
keep_all: call.has_flag("keep-all"),
|
||||
header_row: call.has_flag(engine_state, stack, "header-row")?,
|
||||
ignore_titles: call.has_flag(engine_state, stack, "ignore-titles")?,
|
||||
as_record: call.has_flag(engine_state, stack, "as-record")?,
|
||||
keep_last: call.has_flag(engine_state, stack, "keep-last")?,
|
||||
keep_all: call.has_flag(engine_state, stack, "keep-all")?,
|
||||
rest: call.rest(engine_state, stack, 0)?,
|
||||
};
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
use crate::formats::value_to_string;
|
||||
use itertools::Itertools;
|
||||
use nu_engine::CallExt;
|
||||
use nu_protocol::ast::Call;
|
||||
use nu_protocol::engine::{Command, EngineState, Stack};
|
||||
use nu_protocol::{
|
||||
@ -247,7 +248,7 @@ fn generate_results_with_count(head: Span, uniq_values: Vec<ValueCounter>) -> Ve
|
||||
|
||||
pub fn uniq(
|
||||
engine_state: &EngineState,
|
||||
_stack: &mut Stack,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
input: Vec<Value>,
|
||||
item_mapper: Box<dyn Fn(ItemMapperState) -> ValueCounter>,
|
||||
@ -255,10 +256,10 @@ pub fn uniq(
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let ctrlc = engine_state.ctrlc.clone();
|
||||
let head = call.head;
|
||||
let flag_show_count = call.has_flag("count");
|
||||
let flag_show_repeated = call.has_flag("repeated");
|
||||
let flag_ignore_case = call.has_flag("ignore-case");
|
||||
let flag_only_uniques = call.has_flag("unique");
|
||||
let flag_show_count = call.has_flag(engine_state, stack, "count")?;
|
||||
let flag_show_repeated = call.has_flag(engine_state, stack, "repeated")?;
|
||||
let flag_ignore_case = call.has_flag(engine_state, stack, "ignore-case")?;
|
||||
let flag_only_uniques = call.has_flag(engine_state, stack, "unique")?;
|
||||
|
||||
let uniq_values = input
|
||||
.into_iter()
|
||||
|
@ -120,7 +120,7 @@ impl Command for Window {
|
||||
let ctrlc = engine_state.ctrlc.clone();
|
||||
let metadata = input.metadata();
|
||||
let stride: Option<usize> = call.get_flag(engine_state, stack, "stride")?;
|
||||
let remainder = call.has_flag("remainder");
|
||||
let remainder = call.has_flag(engine_state, stack, "remainder")?;
|
||||
|
||||
let stride = stride.unwrap_or(1);
|
||||
|
||||
|
@ -166,9 +166,9 @@ fn from_csv(
|
||||
.get_flag(engine_state, stack, "escape")?
|
||||
.map(|v: Value| v.as_char())
|
||||
.transpose()?;
|
||||
let no_infer = call.has_flag("no-infer");
|
||||
let noheaders = call.has_flag("noheaders");
|
||||
let flexible = call.has_flag("flexible");
|
||||
let no_infer = call.has_flag(engine_state, stack, "no-infer")?;
|
||||
let noheaders = call.has_flag(engine_state, stack, "noheaders")?;
|
||||
let flexible = call.has_flag(engine_state, stack, "flexible")?;
|
||||
let trim = trim_from_str(call.get_flag(engine_state, stack, "trim")?)?;
|
||||
|
||||
let config = DelimitedReaderConfig {
|
||||
|
@ -1,3 +1,4 @@
|
||||
use nu_engine::CallExt;
|
||||
use nu_protocol::ast::Call;
|
||||
use nu_protocol::engine::{Command, EngineState, Stack};
|
||||
use nu_protocol::{
|
||||
@ -47,7 +48,7 @@ impl Command for FromJson {
|
||||
fn run(
|
||||
&self,
|
||||
engine_state: &EngineState,
|
||||
_stack: &mut Stack,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
@ -59,7 +60,7 @@ impl Command for FromJson {
|
||||
}
|
||||
|
||||
// TODO: turn this into a structured underline of the nu_json error
|
||||
if call.has_flag("objects") {
|
||||
if call.has_flag(engine_state, stack, "objects")? {
|
||||
let converted_lines: Vec<Value> = string_input
|
||||
.lines()
|
||||
.filter_map(move |x| {
|
||||
|
@ -289,8 +289,8 @@ fn from_ssv(
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let name = call.head;
|
||||
|
||||
let noheaders = call.has_flag("noheaders");
|
||||
let aligned_columns = call.has_flag("aligned-columns");
|
||||
let noheaders = call.has_flag(engine_state, stack, "noheaders")?;
|
||||
let aligned_columns = call.has_flag(engine_state, stack, "aligned-columns")?;
|
||||
let minimum_spaces: Option<Spanned<usize>> =
|
||||
call.get_flag(engine_state, stack, "minimum-spaces")?;
|
||||
|
||||
|
@ -132,9 +132,9 @@ fn from_tsv(
|
||||
.get_flag(engine_state, stack, "escape")?
|
||||
.map(|v: Value| v.as_char())
|
||||
.transpose()?;
|
||||
let no_infer = call.has_flag("no-infer");
|
||||
let noheaders = call.has_flag("noheaders");
|
||||
let flexible = call.has_flag("flexible");
|
||||
let no_infer = call.has_flag(engine_state, stack, "no-infer")?;
|
||||
let noheaders = call.has_flag(engine_state, stack, "noheaders")?;
|
||||
let flexible = call.has_flag(engine_state, stack, "flexible")?;
|
||||
let trim = trim_from_str(call.get_flag(engine_state, stack, "trim")?)?;
|
||||
|
||||
let config = DelimitedReaderConfig {
|
||||
|
@ -1,5 +1,6 @@
|
||||
use crate::formats::nu_xml_format::{COLUMN_ATTRS_NAME, COLUMN_CONTENT_NAME, COLUMN_TAG_NAME};
|
||||
use indexmap::map::IndexMap;
|
||||
use nu_engine::CallExt;
|
||||
use nu_protocol::ast::Call;
|
||||
use nu_protocol::engine::{Command, EngineState, Stack};
|
||||
use nu_protocol::{
|
||||
@ -46,14 +47,14 @@ string. This way content of every tag is always a table and is easier to parse"#
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
_engine_state: &EngineState,
|
||||
_stack: &mut Stack,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let head = call.head;
|
||||
let keep_comments = call.has_flag("keep-comments");
|
||||
let keep_processing_instructions = call.has_flag("keep-pi");
|
||||
let keep_comments = call.has_flag(engine_state, stack, "keep-comments")?;
|
||||
let keep_processing_instructions = call.has_flag(engine_state, stack, "keep-pi")?;
|
||||
let info = ParsingInfo {
|
||||
span: head,
|
||||
keep_comments,
|
||||
|
@ -67,7 +67,7 @@ impl Command for ToCsv {
|
||||
input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let head = call.head;
|
||||
let noheaders = call.has_flag("noheaders");
|
||||
let noheaders = call.has_flag(engine_state, stack, "noheaders")?;
|
||||
let separator: Option<Spanned<String>> = call.get_flag(engine_state, stack, "separator")?;
|
||||
let config = engine_state.get_config();
|
||||
to_csv(input, noheaders, separator, head, config)
|
||||
|
@ -44,8 +44,8 @@ impl Command for ToJson {
|
||||
call: &Call,
|
||||
input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let raw = call.has_flag("raw");
|
||||
let use_tabs = call.has_flag("tabs");
|
||||
let raw = call.has_flag(engine_state, stack, "raw")?;
|
||||
let use_tabs = call.has_flag(engine_state, stack, "tabs")?;
|
||||
|
||||
let span = call.head;
|
||||
// allow ranges to expand and turn into array
|
||||
|
@ -1,5 +1,6 @@
|
||||
use indexmap::map::IndexMap;
|
||||
use nu_cmd_base::formats::to::delimited::merge_descriptors;
|
||||
use nu_engine::CallExt;
|
||||
use nu_protocol::ast::Call;
|
||||
use nu_protocol::engine::{Command, EngineState, Stack};
|
||||
use nu_protocol::{
|
||||
@ -67,13 +68,13 @@ impl Command for ToMd {
|
||||
fn run(
|
||||
&self,
|
||||
engine_state: &EngineState,
|
||||
_stack: &mut Stack,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let head = call.head;
|
||||
let pretty = call.has_flag("pretty");
|
||||
let per_element = call.has_flag("per-element");
|
||||
let pretty = call.has_flag(engine_state, stack, "pretty")?;
|
||||
let per_element = call.has_flag(engine_state, stack, "per-element")?;
|
||||
let config = engine_state.get_config();
|
||||
to_md(input, pretty, per_element, config, head)
|
||||
}
|
||||
|
@ -53,20 +53,18 @@ impl Command for ToNuon {
|
||||
call: &Call,
|
||||
input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let raw = call.has_flag("raw");
|
||||
let use_tabs = call.has_flag("tabs");
|
||||
let use_indent = call.has_flag("indent");
|
||||
let raw = call.has_flag(engine_state, stack, "raw")?;
|
||||
let tabs: Option<usize> = call.get_flag(engine_state, stack, "tabs")?;
|
||||
let indent: Option<usize> = call.get_flag(engine_state, stack, "indent")?;
|
||||
|
||||
let span = call.head;
|
||||
let value = input.into_value(span);
|
||||
|
||||
let nuon_result = if raw {
|
||||
value_to_string(&value, span, 0, None)
|
||||
} else if use_tabs {
|
||||
let tab_count: usize = call.get_flag(engine_state, stack, "tabs")?.unwrap_or(1);
|
||||
} else if let Some(tab_count) = tabs {
|
||||
value_to_string(&value, span, 0, Some(&"\t".repeat(tab_count)))
|
||||
} else if use_indent {
|
||||
let indent: usize = call.get_flag(engine_state, stack, "indent")?.unwrap_or(2);
|
||||
} else if let Some(indent) = indent {
|
||||
value_to_string(&value, span, 0, Some(&" ".repeat(indent)))
|
||||
} else {
|
||||
value_to_string(&value, span, 0, None)
|
||||
|
@ -1,4 +1,5 @@
|
||||
use crate::formats::to::delimited::to_delimited_data;
|
||||
use nu_engine::CallExt;
|
||||
use nu_protocol::ast::Call;
|
||||
use nu_protocol::engine::{Command, EngineState, Stack};
|
||||
use nu_protocol::{
|
||||
@ -49,12 +50,12 @@ impl Command for ToTsv {
|
||||
fn run(
|
||||
&self,
|
||||
engine_state: &EngineState,
|
||||
_stack: &mut Stack,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let head = call.head;
|
||||
let noheaders = call.has_flag("noheaders");
|
||||
let noheaders = call.has_flag(engine_state, stack, "noheaders")?;
|
||||
let config = engine_state.get_config();
|
||||
to_tsv(input, noheaders, head, config)
|
||||
}
|
||||
|
@ -101,10 +101,10 @@ pub fn cal(
|
||||
let (current_year, current_month, current_day) = get_current_date();
|
||||
|
||||
let arguments = Arguments {
|
||||
year: call.has_flag("year"),
|
||||
month: call.has_flag("month"),
|
||||
month_names: call.has_flag("month-names"),
|
||||
quarter: call.has_flag("quarter"),
|
||||
year: call.has_flag(engine_state, stack, "year")?,
|
||||
month: call.has_flag(engine_state, stack, "month")?,
|
||||
month_names: call.has_flag(engine_state, stack, "month-names")?,
|
||||
quarter: call.has_flag(engine_state, stack, "quarter")?,
|
||||
full_year: call.get_flag(engine_state, stack, "full-year")?,
|
||||
week_start: call.get_flag(engine_state, stack, "week-start")?,
|
||||
};
|
||||
|
@ -129,7 +129,7 @@ impl Command for SeqDate {
|
||||
let end_date: Option<Spanned<String>> = call.get_flag(engine_state, stack, "end-date")?;
|
||||
let increment: Option<Spanned<i64>> = call.get_flag(engine_state, stack, "increment")?;
|
||||
let days: Option<Spanned<i64>> = call.get_flag(engine_state, stack, "days")?;
|
||||
let reverse = call.has_flag("reverse");
|
||||
let reverse = call.has_flag(engine_state, stack, "reverse")?;
|
||||
|
||||
let outformat = match output_format {
|
||||
Some(s) => Some(Value::string(s.item, s.span)),
|
||||
|
@ -87,7 +87,7 @@ where
|
||||
call: &Call,
|
||||
input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let binary = call.has_flag("binary");
|
||||
let binary = call.has_flag(engine_state, stack, "binary")?;
|
||||
let cell_paths: Vec<CellPath> = call.rest(engine_state, stack, 0)?;
|
||||
let cell_paths = (!cell_paths.is_empty()).then_some(cell_paths);
|
||||
let args = Arguments { binary, cell_paths };
|
||||
|
@ -1,5 +1,6 @@
|
||||
use super::variance::compute_variance as variance;
|
||||
use crate::math::utils::run_with_function;
|
||||
use nu_engine::CallExt;
|
||||
use nu_protocol::ast::Call;
|
||||
use nu_protocol::engine::{Command, EngineState, Stack};
|
||||
use nu_protocol::{Category, Example, PipelineData, ShellError, Signature, Span, Type, Value};
|
||||
@ -40,12 +41,12 @@ impl Command for SubCommand {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
_engine_state: &EngineState,
|
||||
_stack: &mut Stack,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let sample = call.has_flag("sample");
|
||||
let sample = call.has_flag(engine_state, stack, "sample")?;
|
||||
run_with_function(call, input, compute_stddev(sample))
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
use crate::math::utils::run_with_function;
|
||||
use nu_engine::CallExt;
|
||||
use nu_protocol::ast::Call;
|
||||
use nu_protocol::engine::{Command, EngineState, Stack};
|
||||
use nu_protocol::{Category, Example, PipelineData, ShellError, Signature, Span, Type, Value};
|
||||
@ -32,12 +33,12 @@ impl Command for SubCommand {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
_engine_state: &EngineState,
|
||||
_stack: &mut Stack,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let sample = call.has_flag("sample");
|
||||
let sample = call.has_flag(engine_state, stack, "sample")?;
|
||||
run_with_function(call, input, compute_variance(sample))
|
||||
}
|
||||
|
||||
|
@ -170,13 +170,13 @@ fn run_delete(
|
||||
headers: call.get_flag(engine_state, stack, "headers")?,
|
||||
data: call.get_flag(engine_state, stack, "data")?,
|
||||
content_type: call.get_flag(engine_state, stack, "content-type")?,
|
||||
raw: call.has_flag("raw"),
|
||||
insecure: call.has_flag("insecure"),
|
||||
raw: call.has_flag(engine_state, stack, "raw")?,
|
||||
insecure: call.has_flag(engine_state, stack, "insecure")?,
|
||||
user: call.get_flag(engine_state, stack, "user")?,
|
||||
password: call.get_flag(engine_state, stack, "password")?,
|
||||
timeout: call.get_flag(engine_state, stack, "max-time")?,
|
||||
full: call.has_flag("full"),
|
||||
allow_errors: call.has_flag("allow-errors"),
|
||||
full: call.has_flag(engine_state, stack, "full")?,
|
||||
allow_errors: call.has_flag(engine_state, stack, "allow-errors")?,
|
||||
redirect: call.get_flag(engine_state, stack, "redirect-mode")?,
|
||||
};
|
||||
|
||||
|
@ -154,13 +154,13 @@ fn run_get(
|
||||
let args = Arguments {
|
||||
url: call.req(engine_state, stack, 0)?,
|
||||
headers: call.get_flag(engine_state, stack, "headers")?,
|
||||
raw: call.has_flag("raw"),
|
||||
insecure: call.has_flag("insecure"),
|
||||
raw: call.has_flag(engine_state, stack, "raw")?,
|
||||
insecure: call.has_flag(engine_state, stack, "insecure")?,
|
||||
user: call.get_flag(engine_state, stack, "user")?,
|
||||
password: call.get_flag(engine_state, stack, "password")?,
|
||||
timeout: call.get_flag(engine_state, stack, "max-time")?,
|
||||
full: call.has_flag("full"),
|
||||
allow_errors: call.has_flag("allow-errors"),
|
||||
full: call.has_flag(engine_state, stack, "full")?,
|
||||
allow_errors: call.has_flag(engine_state, stack, "allow-errors")?,
|
||||
redirect: call.get_flag(engine_state, stack, "redirect-mode")?,
|
||||
};
|
||||
helper(engine_state, stack, call, args)
|
||||
|
@ -132,7 +132,7 @@ fn run_head(
|
||||
let args = Arguments {
|
||||
url: call.req(engine_state, stack, 0)?,
|
||||
headers: call.get_flag(engine_state, stack, "headers")?,
|
||||
insecure: call.has_flag("insecure"),
|
||||
insecure: call.has_flag(engine_state, stack, "insecure")?,
|
||||
user: call.get_flag(engine_state, stack, "user")?,
|
||||
password: call.get_flag(engine_state, stack, "password")?,
|
||||
timeout: call.get_flag(engine_state, stack, "max-time")?,
|
||||
|
@ -139,11 +139,11 @@ fn run_get(
|
||||
let args = Arguments {
|
||||
url: call.req(engine_state, stack, 0)?,
|
||||
headers: call.get_flag(engine_state, stack, "headers")?,
|
||||
insecure: call.has_flag("insecure"),
|
||||
insecure: call.has_flag(engine_state, stack, "insecure")?,
|
||||
user: call.get_flag(engine_state, stack, "user")?,
|
||||
password: call.get_flag(engine_state, stack, "password")?,
|
||||
timeout: call.get_flag(engine_state, stack, "max-time")?,
|
||||
allow_errors: call.has_flag("allow-errors"),
|
||||
allow_errors: call.has_flag(engine_state, stack, "allow-errors")?,
|
||||
};
|
||||
helper(engine_state, stack, call, args)
|
||||
}
|
||||
|
@ -162,13 +162,13 @@ fn run_patch(
|
||||
headers: call.get_flag(engine_state, stack, "headers")?,
|
||||
data: call.req(engine_state, stack, 1)?,
|
||||
content_type: call.get_flag(engine_state, stack, "content-type")?,
|
||||
raw: call.has_flag("raw"),
|
||||
insecure: call.has_flag("insecure"),
|
||||
raw: call.has_flag(engine_state, stack, "raw")?,
|
||||
insecure: call.has_flag(engine_state, stack, "insecure")?,
|
||||
user: call.get_flag(engine_state, stack, "user")?,
|
||||
password: call.get_flag(engine_state, stack, "password")?,
|
||||
timeout: call.get_flag(engine_state, stack, "max-time")?,
|
||||
full: call.has_flag("full"),
|
||||
allow_errors: call.has_flag("allow-errors"),
|
||||
full: call.has_flag(engine_state, stack, "full")?,
|
||||
allow_errors: call.has_flag(engine_state, stack, "allow-errors")?,
|
||||
redirect: call.get_flag(engine_state, stack, "redirect-mode")?,
|
||||
};
|
||||
|
||||
|
@ -160,13 +160,13 @@ fn run_post(
|
||||
headers: call.get_flag(engine_state, stack, "headers")?,
|
||||
data: call.req(engine_state, stack, 1)?,
|
||||
content_type: call.get_flag(engine_state, stack, "content-type")?,
|
||||
raw: call.has_flag("raw"),
|
||||
insecure: call.has_flag("insecure"),
|
||||
raw: call.has_flag(engine_state, stack, "raw")?,
|
||||
insecure: call.has_flag(engine_state, stack, "insecure")?,
|
||||
user: call.get_flag(engine_state, stack, "user")?,
|
||||
password: call.get_flag(engine_state, stack, "password")?,
|
||||
timeout: call.get_flag(engine_state, stack, "max-time")?,
|
||||
full: call.has_flag("full"),
|
||||
allow_errors: call.has_flag("allow-errors"),
|
||||
full: call.has_flag(engine_state, stack, "full")?,
|
||||
allow_errors: call.has_flag(engine_state, stack, "allow-errors")?,
|
||||
redirect: call.get_flag(engine_state, stack, "redirect-mode")?,
|
||||
};
|
||||
|
||||
|
@ -160,13 +160,13 @@ fn run_put(
|
||||
headers: call.get_flag(engine_state, stack, "headers")?,
|
||||
data: call.req(engine_state, stack, 1)?,
|
||||
content_type: call.get_flag(engine_state, stack, "content-type")?,
|
||||
raw: call.has_flag("raw"),
|
||||
insecure: call.has_flag("insecure"),
|
||||
raw: call.has_flag(engine_state, stack, "raw")?,
|
||||
insecure: call.has_flag(engine_state, stack, "insecure")?,
|
||||
user: call.get_flag(engine_state, stack, "user")?,
|
||||
password: call.get_flag(engine_state, stack, "password")?,
|
||||
timeout: call.get_flag(engine_state, stack, "max-time")?,
|
||||
full: call.has_flag("full"),
|
||||
allow_errors: call.has_flag("allow-errors"),
|
||||
full: call.has_flag(engine_state, stack, "full")?,
|
||||
allow_errors: call.has_flag(engine_state, stack, "allow-errors")?,
|
||||
redirect: call.get_flag(engine_state, stack, "redirect-mode")?,
|
||||
};
|
||||
|
||||
|
@ -53,7 +53,7 @@ impl Command for SubCommand {
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let cell_paths: Vec<CellPath> = call.rest(engine_state, stack, 0)?;
|
||||
let args = CellPathOnlyArgs::from(cell_paths);
|
||||
if call.has_flag("all") {
|
||||
if call.has_flag(engine_state, stack, "all")? {
|
||||
operate(
|
||||
action_all,
|
||||
args,
|
||||
|
@ -1,6 +1,7 @@
|
||||
use std::path::Path;
|
||||
|
||||
use nu_engine::env::{current_dir_str, current_dir_str_const};
|
||||
use nu_engine::CallExt;
|
||||
use nu_path::{canonicalize_with, expand_path_with};
|
||||
use nu_protocol::ast::Call;
|
||||
use nu_protocol::engine::{EngineState, Stack, StateWorkingSet};
|
||||
@ -61,9 +62,9 @@ impl Command for SubCommand {
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let head = call.head;
|
||||
let args = Arguments {
|
||||
strict: call.has_flag("strict"),
|
||||
strict: call.has_flag(engine_state, stack, "strict")?,
|
||||
cwd: current_dir_str(engine_state, stack)?,
|
||||
not_follow_symlink: call.has_flag("no-symlink"),
|
||||
not_follow_symlink: call.has_flag(engine_state, stack, "no-symlink")?,
|
||||
};
|
||||
// This doesn't match explicit nulls
|
||||
if matches!(input, PipelineData::Empty) {
|
||||
@ -83,9 +84,9 @@ impl Command for SubCommand {
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let head = call.head;
|
||||
let args = Arguments {
|
||||
strict: call.has_flag("strict"),
|
||||
strict: call.has_flag_const(working_set, "strict")?,
|
||||
cwd: current_dir_str_const(working_set)?,
|
||||
not_follow_symlink: call.has_flag("no-symlink"),
|
||||
not_follow_symlink: call.has_flag_const(working_set, "no-symlink")?,
|
||||
};
|
||||
// This doesn't match explicit nulls
|
||||
if matches!(input, PipelineData::Empty) {
|
||||
|
@ -653,9 +653,9 @@ Operating system commands:
|
||||
call: &Call,
|
||||
_input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let list: bool = call.has_flag("list");
|
||||
let escape: bool = call.has_flag("escape");
|
||||
let osc: bool = call.has_flag("osc");
|
||||
let list: bool = call.has_flag(engine_state, stack, "list")?;
|
||||
let escape: bool = call.has_flag(engine_state, stack, "escape")?;
|
||||
let osc: bool = call.has_flag(engine_state, stack, "osc")?;
|
||||
let use_ansi_coloring = engine_state.get_config().use_ansi_coloring;
|
||||
|
||||
if list {
|
||||
|
@ -98,8 +98,8 @@ impl Command for Du {
|
||||
|
||||
let args = DuArgs {
|
||||
path: call.opt(engine_state, stack, 0)?,
|
||||
all: call.has_flag("all"),
|
||||
deref: call.has_flag("deref"),
|
||||
all: call.has_flag(engine_state, stack, "all")?,
|
||||
deref: call.has_flag(engine_state, stack, "deref")?,
|
||||
exclude: call.get_flag(engine_state, stack, "exclude")?,
|
||||
max_depth,
|
||||
min_size,
|
||||
|
@ -65,7 +65,7 @@ impl Command for Input {
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let prompt: Option<String> = call.opt(engine_state, stack, 0)?;
|
||||
let bytes_until: Option<String> = call.get_flag(engine_state, stack, "bytes-until-any")?;
|
||||
let suppress_output = call.has_flag("suppress-output");
|
||||
let suppress_output = call.has_flag(engine_state, stack, "suppress-output")?;
|
||||
let numchar: Option<Spanned<i64>> = call.get_flag(engine_state, stack, "numchar")?;
|
||||
let numchar: Spanned<i64> = numchar.unwrap_or(Spanned {
|
||||
item: i64::MAX,
|
||||
|
@ -85,7 +85,7 @@ There are 4 `key_type` variants:
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let head = call.head;
|
||||
let event_type_filter = get_event_type_filter(engine_state, stack, call, head)?;
|
||||
let add_raw = call.has_flag("raw");
|
||||
let add_raw = call.has_flag(engine_state, stack, "raw")?;
|
||||
|
||||
terminal::enable_raw_mode()?;
|
||||
let console_state = event_type_filter.enable_events()?;
|
||||
|
@ -78,6 +78,8 @@ impl Command for InputList {
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let head = call.head;
|
||||
let prompt: Option<String> = call.opt(engine_state, stack, 0)?;
|
||||
let multi = call.has_flag(engine_state, stack, "multi")?;
|
||||
let fuzzy = call.has_flag(engine_state, stack, "fuzzy")?;
|
||||
|
||||
let options: Vec<Options> = match input {
|
||||
PipelineData::Value(Value::Range { .. }, ..)
|
||||
@ -105,7 +107,7 @@ impl Command for InputList {
|
||||
});
|
||||
}
|
||||
|
||||
if call.has_flag("multi") && call.has_flag("fuzzy") {
|
||||
if multi && fuzzy {
|
||||
return Err(ShellError::TypeMismatch {
|
||||
err_message: "Fuzzy search is not supported for multi select".to_string(),
|
||||
span: head,
|
||||
@ -118,7 +120,7 @@ impl Command for InputList {
|
||||
// ..Default::default()
|
||||
// };
|
||||
|
||||
let ans: InteractMode = if call.has_flag("multi") {
|
||||
let ans: InteractMode = if multi {
|
||||
let multi_select = MultiSelect::new(); //::with_theme(&theme);
|
||||
|
||||
InteractMode::Multi(
|
||||
@ -134,7 +136,7 @@ impl Command for InputList {
|
||||
msg: format!("{}: {}", INTERACT_ERROR, err),
|
||||
})?,
|
||||
)
|
||||
} else if call.has_flag("fuzzy") {
|
||||
} else if fuzzy {
|
||||
let fuzzy_select = FuzzySelect::new(); //::with_theme(&theme);
|
||||
|
||||
InteractMode::Single(
|
||||
|
@ -1,3 +1,4 @@
|
||||
use nu_engine::CallExt;
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EngineState, Stack},
|
||||
@ -40,14 +41,14 @@ impl Command for IsTerminal {
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
_engine_state: &EngineState,
|
||||
_stack: &mut Stack,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
_input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let stdin = call.has_flag("stdin");
|
||||
let stdout = call.has_flag("stdout");
|
||||
let stderr = call.has_flag("stderr");
|
||||
let stdin = call.has_flag(engine_state, stack, "stdin")?;
|
||||
let stdout = call.has_flag(engine_state, stack, "stdout")?;
|
||||
let stderr = call.has_flag(engine_state, stack, "stderr")?;
|
||||
|
||||
let is_terminal = match (stdin, stdout, stderr) {
|
||||
(true, false, false) => std::io::stdin().is_terminal(),
|
||||
|
@ -58,9 +58,9 @@ impl Command for Kill {
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let pid: i64 = call.req(engine_state, stack, 0)?;
|
||||
let rest: Vec<i64> = call.rest(engine_state, stack, 1)?;
|
||||
let force: bool = call.has_flag("force");
|
||||
let force: bool = call.has_flag(engine_state, stack, "force")?;
|
||||
let signal: Option<Spanned<i64>> = call.get_flag(engine_state, stack, "signal")?;
|
||||
let quiet: bool = call.has_flag("quiet");
|
||||
let quiet: bool = call.has_flag(engine_state, stack, "quiet")?;
|
||||
|
||||
let mut cmd = if cfg!(windows) {
|
||||
let mut cmd = CommandSys::new("taskkill");
|
||||
|
@ -267,12 +267,17 @@ fn limit_to_value(limit: rlim_t, multiplier: rlim_t, span: Span) -> Result<Value
|
||||
}
|
||||
|
||||
/// Get maximum length of all flag descriptions
|
||||
fn max_desc_len(call: &Call, print_all: bool) -> usize {
|
||||
fn max_desc_len(
|
||||
call: &Call,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
print_all: bool,
|
||||
) -> Result<usize, ShellError> {
|
||||
let mut desc_len = 0;
|
||||
let mut unit_len = 0;
|
||||
|
||||
for res in RESOURCE_ARRAY.iter() {
|
||||
if !print_all && !call.has_flag(res.name) {
|
||||
if !print_all && !call.has_flag(engine_state, stack, res.name)? {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -288,7 +293,7 @@ fn max_desc_len(call: &Call, print_all: bool) -> usize {
|
||||
}
|
||||
|
||||
// desc.len() + unit.len() + '-X)'.len()
|
||||
desc_len + unit_len + 3
|
||||
Ok(desc_len + unit_len + 3)
|
||||
}
|
||||
|
||||
/// Fill `ResourceInfo` to the record entry
|
||||
@ -359,18 +364,20 @@ fn set_limits(
|
||||
/// Print limits
|
||||
fn print_limits(
|
||||
call: &Call,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
print_all: bool,
|
||||
soft: bool,
|
||||
hard: bool,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let mut output = Vec::new();
|
||||
let mut print_default_limit = true;
|
||||
let max_len = max_desc_len(call, print_all);
|
||||
let max_len = max_desc_len(call, engine_state, stack, print_all)?;
|
||||
|
||||
for res in RESOURCE_ARRAY.iter() {
|
||||
if !print_all {
|
||||
// Print specified limit.
|
||||
if !call.has_flag(res.name) {
|
||||
if !call.has_flag(engine_state, stack, res.name)? {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@ -527,9 +534,9 @@ impl Command for ULimit {
|
||||
call: &Call,
|
||||
_input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let mut soft = call.has_flag("soft");
|
||||
let mut hard = call.has_flag("hard");
|
||||
let all = call.has_flag("all");
|
||||
let mut soft = call.has_flag(engine_state, stack, "soft")?;
|
||||
let mut hard = call.has_flag(engine_state, stack, "hard")?;
|
||||
let all = call.has_flag(engine_state, stack, "all")?;
|
||||
|
||||
if !hard && !soft {
|
||||
// Set both hard and soft limits if neither was specified.
|
||||
@ -541,7 +548,7 @@ impl Command for ULimit {
|
||||
let mut set_default_limit = true;
|
||||
|
||||
for res in RESOURCE_ARRAY.iter() {
|
||||
if call.has_flag(res.name) {
|
||||
if call.has_flag(engine_state, stack, res.name)? {
|
||||
set_limits(&limit_value, res, soft, hard, call.head)?;
|
||||
|
||||
if set_default_limit {
|
||||
@ -558,7 +565,7 @@ impl Command for ULimit {
|
||||
|
||||
Ok(PipelineData::Empty)
|
||||
} else {
|
||||
print_limits(call, all, soft, hard)
|
||||
print_limits(call, engine_state, stack, all, soft, hard)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -229,7 +229,7 @@ impl Command for Char {
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let call_span = call.head;
|
||||
// handle -l flag
|
||||
if call.has_flag("list") {
|
||||
if call.has_flag(engine_state, stack, "list")? {
|
||||
return Ok(CHAR_MAP
|
||||
.iter()
|
||||
.map(move |(name, s)| {
|
||||
@ -251,7 +251,7 @@ impl Command for Char {
|
||||
.into_pipeline_data(engine_state.ctrlc.clone()));
|
||||
}
|
||||
// handle -u flag
|
||||
if call.has_flag("integer") {
|
||||
if call.has_flag(engine_state, stack, "integer")? {
|
||||
let args: Vec<i64> = call.rest(engine_state, stack, 0)?;
|
||||
if args.is_empty() {
|
||||
return Err(ShellError::MissingParameter {
|
||||
@ -268,7 +268,7 @@ impl Command for Char {
|
||||
multi_byte.push(integer_to_unicode_char(arg, span)?)
|
||||
}
|
||||
Ok(Value::string(multi_byte, call_span).into_pipeline_data())
|
||||
} else if call.has_flag("unicode") {
|
||||
} else if call.has_flag(engine_state, stack, "unicode")? {
|
||||
let args: Vec<String> = call.rest(engine_state, stack, 0)?;
|
||||
if args.is_empty() {
|
||||
return Err(ShellError::MissingParameter {
|
||||
|
@ -103,7 +103,7 @@ fn detect_columns(
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let name_span = call.head;
|
||||
let num_rows_to_skip: Option<usize> = call.get_flag(engine_state, stack, "skip")?;
|
||||
let noheader = call.has_flag("no-headers");
|
||||
let noheader = call.has_flag(engine_state, stack, "no-headers")?;
|
||||
let range: Option<Range> = call.get_flag(engine_state, stack, "combine-columns")?;
|
||||
let ctrlc = engine_state.ctrlc.clone();
|
||||
let config = engine_state.get_config();
|
||||
|
@ -46,7 +46,7 @@ pub fn operate(
|
||||
let head = call.head;
|
||||
let character_set: Option<Spanned<String>> =
|
||||
call.get_flag(engine_state, stack, "character-set")?;
|
||||
let binary = call.has_flag("binary");
|
||||
let binary = call.has_flag(engine_state, stack, "binary")?;
|
||||
let cell_paths: Vec<CellPath> = call.rest(engine_state, stack, 0)?;
|
||||
let cell_paths = (!cell_paths.is_empty()).then_some(cell_paths);
|
||||
|
||||
|
@ -83,7 +83,7 @@ documentation link at https://docs.rs/encoding_rs/latest/encoding_rs/#statics"#
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let head = call.head;
|
||||
let encoding: Spanned<String> = call.req(engine_state, stack, 0)?;
|
||||
let ignore_errors = call.has_flag("ignore-errors");
|
||||
let ignore_errors = call.has_flag(engine_state, stack, "ignore-errors")?;
|
||||
|
||||
match input {
|
||||
PipelineData::ExternalStream { stdout: None, .. } => Ok(PipelineData::empty()),
|
||||
|
@ -53,7 +53,7 @@ impl Command for FormatDate {
|
||||
input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let head = call.head;
|
||||
if call.has_flag("list") {
|
||||
if call.has_flag(engine_state, stack, "list")? {
|
||||
return Ok(PipelineData::Value(
|
||||
generate_strftime_list(head, false),
|
||||
None,
|
||||
|
@ -10,26 +10,35 @@ pub use char_::Char;
|
||||
pub use detect_columns::*;
|
||||
pub use encode_decode::*;
|
||||
pub use format::*;
|
||||
use nu_engine::CallExt;
|
||||
pub use parse::*;
|
||||
pub use split::*;
|
||||
pub use str_::*;
|
||||
|
||||
use nu_protocol::{ast::Call, ShellError};
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{EngineState, Stack, StateWorkingSet},
|
||||
ShellError,
|
||||
};
|
||||
|
||||
// For handling the grapheme_cluster related flags on some commands.
|
||||
// This ensures the error messages are consistent.
|
||||
pub fn grapheme_flags(call: &Call) -> Result<bool, ShellError> {
|
||||
let g_flag = call.has_flag("grapheme-clusters");
|
||||
pub fn grapheme_flags(
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
) -> Result<bool, ShellError> {
|
||||
let g_flag = call.has_flag(engine_state, stack, "grapheme-clusters")?;
|
||||
// Check for the other flags and produce errors if they exist.
|
||||
// Note that Nushell already prevents nonexistent flags from being used with commands,
|
||||
// so this function can be reused for both the --utf-8-bytes commands and the --code-points commands.
|
||||
if g_flag && call.has_flag("utf-8-bytes") {
|
||||
if g_flag && call.has_flag(engine_state, stack, "utf-8-bytes")? {
|
||||
Err(ShellError::IncompatibleParametersSingle {
|
||||
msg: "Incompatible flags: --grapheme-clusters (-g) and --utf-8-bytes (-b)".to_string(),
|
||||
span: call.head,
|
||||
})?
|
||||
}
|
||||
if g_flag && call.has_flag("code-points") {
|
||||
if g_flag && call.has_flag(engine_state, stack, "code-points")? {
|
||||
Err(ShellError::IncompatibleParametersSingle {
|
||||
msg: "Incompatible flags: --grapheme-clusters (-g) and --utf-8-bytes (-b)".to_string(),
|
||||
span: call.head,
|
||||
@ -38,3 +47,24 @@ pub fn grapheme_flags(call: &Call) -> Result<bool, ShellError> {
|
||||
// Grapheme cluster usage is decided by the non-default -g flag
|
||||
Ok(g_flag)
|
||||
}
|
||||
|
||||
// Const version of grapheme_flags
|
||||
pub fn grapheme_flags_const(
|
||||
working_set: &StateWorkingSet,
|
||||
call: &Call,
|
||||
) -> Result<bool, ShellError> {
|
||||
let g_flag = call.has_flag_const(working_set, "grapheme-clusters")?;
|
||||
if g_flag && call.has_flag_const(working_set, "utf-8-bytes")? {
|
||||
Err(ShellError::IncompatibleParametersSingle {
|
||||
msg: "Incompatible flags: --grapheme-clusters (-g) and --utf-8-bytes (-b)".to_string(),
|
||||
span: call.head,
|
||||
})?
|
||||
}
|
||||
if g_flag && call.has_flag_const(working_set, "code-points")? {
|
||||
Err(ShellError::IncompatibleParametersSingle {
|
||||
msg: "Incompatible flags: --grapheme-clusters (-g) and --utf-8-bytes (-b)".to_string(),
|
||||
span: call.head,
|
||||
})?
|
||||
}
|
||||
Ok(g_flag)
|
||||
}
|
||||
|
@ -122,7 +122,7 @@ fn operate(
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let head = call.head;
|
||||
let pattern: Spanned<String> = call.req(engine_state, stack, 0)?;
|
||||
let regex: bool = call.has_flag("regex");
|
||||
let regex: bool = call.has_flag(engine_state, stack, "regex")?;
|
||||
let ctrlc = engine_state.ctrlc.clone();
|
||||
|
||||
let pattern_item = pattern.item;
|
||||
|
@ -95,22 +95,23 @@ impl Command for SubCommand {
|
||||
fn run(
|
||||
&self,
|
||||
engine_state: &EngineState,
|
||||
_stack: &mut Stack,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
split_chars(engine_state, call, input)
|
||||
split_chars(engine_state, stack, call, input)
|
||||
}
|
||||
}
|
||||
|
||||
fn split_chars(
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let span = call.head;
|
||||
|
||||
let graphemes = grapheme_flags(call)?;
|
||||
let graphemes = grapheme_flags(engine_state, stack, call)?;
|
||||
input.map(
|
||||
move |x| split_chars_helper(&x, span, graphemes),
|
||||
engine_state.ctrlc.clone(),
|
||||
|
@ -119,9 +119,9 @@ fn split_column(
|
||||
let name_span = call.head;
|
||||
let separator: Spanned<String> = call.req(engine_state, stack, 0)?;
|
||||
let rest: Vec<Spanned<String>> = call.rest(engine_state, stack, 1)?;
|
||||
let collapse_empty = call.has_flag("collapse-empty");
|
||||
let collapse_empty = call.has_flag(engine_state, stack, "collapse-empty")?;
|
||||
|
||||
let regex = if call.has_flag("regex") {
|
||||
let regex = if call.has_flag(engine_state, stack, "regex")? {
|
||||
Regex::new(&separator.item)
|
||||
} else {
|
||||
let escaped = regex::escape(&separator.item);
|
||||
|
@ -202,7 +202,7 @@ fn split_list(
|
||||
let mut returned_list = Vec::new();
|
||||
|
||||
let iter = input.into_interruptible_iter(engine_state.ctrlc.clone());
|
||||
let matcher = Matcher::new(call.has_flag("regex"), separator)?;
|
||||
let matcher = Matcher::new(call.has_flag(engine_state, stack, "regex")?, separator)?;
|
||||
for val in iter {
|
||||
if matcher.compare(&val)? {
|
||||
if !temp_list.is_empty() {
|
||||
|
@ -123,7 +123,7 @@ fn split_row(
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let name_span = call.head;
|
||||
let separator: Spanned<String> = call.req(engine_state, stack, 0)?;
|
||||
let regex = if call.has_flag("regex") {
|
||||
let regex = if call.has_flag(engine_state, stack, "regex")? {
|
||||
Regex::new(&separator.item)
|
||||
} else {
|
||||
let escaped = regex::escape(&separator.item);
|
||||
|
@ -118,26 +118,26 @@ fn split_words(
|
||||
input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let span = call.head;
|
||||
// let ignore_hyphenated = call.has_flag("ignore-hyphenated");
|
||||
// let ignore_apostrophes = call.has_flag("ignore-apostrophes");
|
||||
// let ignore_punctuation = call.has_flag("ignore-punctuation");
|
||||
// let ignore_hyphenated = call.has_flag(engine_state, stack, "ignore-hyphenated")?;
|
||||
// let ignore_apostrophes = call.has_flag(engine_state, stack, "ignore-apostrophes")?;
|
||||
// let ignore_punctuation = call.has_flag(engine_state, stack, "ignore-punctuation")?;
|
||||
let word_length: Option<usize> = call.get_flag(engine_state, stack, "min-word-length")?;
|
||||
|
||||
if word_length.is_none() {
|
||||
if call.has_flag("grapheme-clusters") {
|
||||
if call.has_flag(engine_state, stack, "grapheme-clusters")? {
|
||||
return Err(ShellError::IncompatibleParametersSingle {
|
||||
msg: "--grapheme-clusters (-g) requires --min-word-length (-l)".to_string(),
|
||||
span,
|
||||
});
|
||||
}
|
||||
if call.has_flag("utf-8-bytes") {
|
||||
if call.has_flag(engine_state, stack, "utf-8-bytes")? {
|
||||
return Err(ShellError::IncompatibleParametersSingle {
|
||||
msg: "--utf-8-bytes (-b) requires --min-word-length (-l)".to_string(),
|
||||
span,
|
||||
});
|
||||
}
|
||||
}
|
||||
let graphemes = grapheme_flags(call)?;
|
||||
let graphemes = grapheme_flags(engine_state, stack, call)?;
|
||||
|
||||
input.map(
|
||||
move |x| split_words_helper(&x, word_length, span, graphemes),
|
||||
|
@ -70,8 +70,8 @@ impl Command for SubCommand {
|
||||
let args = Arguments {
|
||||
substring: call.req::<String>(engine_state, stack, 0)?,
|
||||
cell_paths,
|
||||
case_insensitive: call.has_flag("ignore-case"),
|
||||
not_contain: call.has_flag("not"),
|
||||
case_insensitive: call.has_flag(engine_state, stack, "ignore-case")?,
|
||||
not_contain: call.has_flag(engine_state, stack, "not")?,
|
||||
};
|
||||
operate(action, args, input, call.head, engine_state.ctrlc.clone())
|
||||
}
|
||||
|
@ -66,7 +66,7 @@ impl Command for SubCommand {
|
||||
let args = Arguments {
|
||||
substring: call.req::<String>(engine_state, stack, 0)?,
|
||||
cell_paths,
|
||||
case_insensitive: call.has_flag("ignore-case"),
|
||||
case_insensitive: call.has_flag(engine_state, stack, "ignore-case")?,
|
||||
};
|
||||
operate(action, args, input, call.head, engine_state.ctrlc.clone())
|
||||
}
|
||||
|
@ -1,3 +1,4 @@
|
||||
use nu_engine::CallExt;
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EngineState, Stack},
|
||||
@ -186,7 +187,7 @@ impl Command for SubCommand {
|
||||
fn run(
|
||||
&self,
|
||||
engine_state: &EngineState,
|
||||
_stack: &mut Stack,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
@ -194,7 +195,7 @@ impl Command for SubCommand {
|
||||
if matches!(input, PipelineData::Empty) {
|
||||
return Err(ShellError::PipelineEmpty { dst_span: span });
|
||||
}
|
||||
let is_path = call.has_flag("path");
|
||||
let is_path = call.has_flag(engine_state, stack, "path")?;
|
||||
input.map(
|
||||
move |v| {
|
||||
let value_span = v.span();
|
||||
|
@ -91,9 +91,9 @@ impl Command for SubCommand {
|
||||
let args = Arguments {
|
||||
substring: substring.item,
|
||||
range: call.get_flag(engine_state, stack, "range")?,
|
||||
end: call.has_flag("end"),
|
||||
end: call.has_flag(engine_state, stack, "end")?,
|
||||
cell_paths,
|
||||
graphemes: grapheme_flags(call)?,
|
||||
graphemes: grapheme_flags(engine_state, stack, call)?,
|
||||
};
|
||||
operate(action, args, input, call.head, engine_state.ctrlc.clone())
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
use crate::grapheme_flags;
|
||||
use crate::grapheme_flags_const;
|
||||
use nu_cmd_base::input_handler::{operate, CmdArgument};
|
||||
use nu_engine::CallExt;
|
||||
use nu_protocol::ast::Call;
|
||||
@ -74,7 +75,13 @@ impl Command for SubCommand {
|
||||
input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let cell_paths: Vec<CellPath> = call.rest(engine_state, stack, 0)?;
|
||||
run(cell_paths, engine_state, call, input)
|
||||
run(
|
||||
cell_paths,
|
||||
engine_state,
|
||||
call,
|
||||
input,
|
||||
grapheme_flags(engine_state, stack, call)?,
|
||||
)
|
||||
}
|
||||
|
||||
fn run_const(
|
||||
@ -84,7 +91,13 @@ impl Command for SubCommand {
|
||||
input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let cell_paths: Vec<CellPath> = call.rest_const(working_set, 0)?;
|
||||
run(cell_paths, working_set.permanent(), call, input)
|
||||
run(
|
||||
cell_paths,
|
||||
working_set.permanent(),
|
||||
call,
|
||||
input,
|
||||
grapheme_flags_const(working_set, call)?,
|
||||
)
|
||||
}
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
@ -116,10 +129,11 @@ fn run(
|
||||
engine_state: &EngineState,
|
||||
call: &Call,
|
||||
input: PipelineData,
|
||||
graphemes: bool,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let args = Arguments {
|
||||
cell_paths: (!cell_paths.is_empty()).then_some(cell_paths),
|
||||
graphemes: grapheme_flags(call)?,
|
||||
graphemes,
|
||||
};
|
||||
operate(action, args, input, call.head, engine_state.ctrlc.clone())
|
||||
}
|
||||
|
@ -90,12 +90,13 @@ impl Command for SubCommand {
|
||||
let replace: Spanned<String> = call.req(engine_state, stack, 1)?;
|
||||
let cell_paths: Vec<CellPath> = call.rest(engine_state, stack, 2)?;
|
||||
let cell_paths = (!cell_paths.is_empty()).then_some(cell_paths);
|
||||
let literal_replace = call.has_flag("no-expand");
|
||||
let no_regex = !call.has_flag("regex") && !call.has_flag("multiline");
|
||||
let multiline = call.has_flag("multiline");
|
||||
let literal_replace = call.has_flag(engine_state, stack, "no-expand")?;
|
||||
let no_regex = !call.has_flag(engine_state, stack, "regex")?
|
||||
&& !call.has_flag(engine_state, stack, "multiline")?;
|
||||
let multiline = call.has_flag(engine_state, stack, "multiline")?;
|
||||
|
||||
let args = Arguments {
|
||||
all: call.has_flag("all"),
|
||||
all: call.has_flag(engine_state, stack, "all")?,
|
||||
find,
|
||||
replace,
|
||||
cell_paths,
|
||||
|
@ -69,7 +69,7 @@ impl Command for SubCommand {
|
||||
let args = Arguments {
|
||||
substring: substring.item,
|
||||
cell_paths,
|
||||
case_insensitive: call.has_flag("ignore-case"),
|
||||
case_insensitive: call.has_flag(engine_state, stack, "ignore-case")?,
|
||||
};
|
||||
operate(action, args, input, call.head, engine_state.ctrlc.clone())
|
||||
}
|
||||
|
@ -102,7 +102,7 @@ impl Command for SubCommand {
|
||||
let args = Arguments {
|
||||
indexes,
|
||||
cell_paths,
|
||||
graphemes: grapheme_flags(call)?,
|
||||
graphemes: grapheme_flags(engine_state, stack, call)?,
|
||||
};
|
||||
operate(action, args, input, call.head, engine_state.ctrlc.clone())
|
||||
}
|
||||
|
@ -107,8 +107,8 @@ impl Command for SubCommand {
|
||||
Some(_) => ActionMode::Local,
|
||||
};
|
||||
|
||||
let left = call.has_flag("left");
|
||||
let right = call.has_flag("right");
|
||||
let left = call.has_flag(engine_state, stack, "left")?;
|
||||
let right = call.has_flag(engine_state, stack, "right")?;
|
||||
let trim_side = match (left, right) {
|
||||
(true, true) => TrimSide::Both,
|
||||
(true, false) => TrimSide::Left,
|
||||
|
@ -43,9 +43,9 @@ impl Command for NuCheck {
|
||||
input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let path: Option<Spanned<String>> = call.opt(engine_state, stack, 0)?;
|
||||
let is_module = call.has_flag("as-module");
|
||||
let is_debug = call.has_flag("debug");
|
||||
let is_all = call.has_flag("all");
|
||||
let is_module = call.has_flag(engine_state, stack, "as-module")?;
|
||||
let is_debug = call.has_flag(engine_state, stack, "debug")?;
|
||||
let is_all = call.has_flag(engine_state, stack, "all")?;
|
||||
let config = engine_state.get_config();
|
||||
let mut contents = vec![];
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
#[cfg(windows)]
|
||||
use itertools::Itertools;
|
||||
use nu_engine::CallExt;
|
||||
#[cfg(all(
|
||||
unix,
|
||||
not(target_os = "macos"),
|
||||
@ -54,11 +55,11 @@ impl Command for Ps {
|
||||
fn run(
|
||||
&self,
|
||||
engine_state: &EngineState,
|
||||
_stack: &mut Stack,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
_input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
run_ps(engine_state, call)
|
||||
run_ps(engine_state, stack, call)
|
||||
}
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
@ -92,10 +93,14 @@ impl Command for Ps {
|
||||
}
|
||||
}
|
||||
|
||||
fn run_ps(engine_state: &EngineState, call: &Call) -> Result<PipelineData, ShellError> {
|
||||
fn run_ps(
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let mut output = vec![];
|
||||
let span = call.head;
|
||||
let long = call.has_flag("long");
|
||||
let long = call.has_flag(engine_state, stack, "long")?;
|
||||
|
||||
for proc in nu_system::collect_proc(Duration::from_millis(100), false) {
|
||||
let mut record = Record::new();
|
||||
|
@ -88,13 +88,13 @@ fn registry_query(
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let call_span = call.head;
|
||||
|
||||
let skip_expand = call.has_flag("no-expand");
|
||||
let skip_expand = call.has_flag(engine_state, stack, "no-expand")?;
|
||||
|
||||
let registry_key: Spanned<String> = call.req(engine_state, stack, 0)?;
|
||||
let registry_key_span = ®istry_key.clone().span;
|
||||
let registry_value: Option<Spanned<String>> = call.opt(engine_state, stack, 1)?;
|
||||
|
||||
let reg_hive = get_reg_hive(call)?;
|
||||
let reg_hive = get_reg_hive(engine_state, stack, call)?;
|
||||
let reg_key = reg_hive.open_subkey(registry_key.item)?;
|
||||
|
||||
if registry_value.is_none() {
|
||||
@ -144,14 +144,22 @@ fn registry_query(
|
||||
}
|
||||
}
|
||||
|
||||
fn get_reg_hive(call: &Call) -> Result<RegKey, ShellError> {
|
||||
let flags: Vec<_> = [
|
||||
fn get_reg_hive(
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
) -> Result<RegKey, ShellError> {
|
||||
let flags = [
|
||||
"hkcr", "hkcu", "hklm", "hku", "hkpd", "hkpt", "hkpnls", "hkcc", "hkdd", "hkculs",
|
||||
]
|
||||
.iter()
|
||||
.copied()
|
||||
.filter(|flag| call.has_flag(flag))
|
||||
.collect();
|
||||
.filter_map(|flag| match call.has_flag(engine_state, stack, flag) {
|
||||
Ok(true) => Some(Ok(flag)),
|
||||
Ok(false) => None,
|
||||
Err(e) => Some(Err(e)),
|
||||
})
|
||||
.collect::<Result<Vec<_>, ShellError>>()?;
|
||||
if flags.len() > 1 {
|
||||
return Err(ShellError::GenericError {
|
||||
error: "Only one registry key can be specified".into(),
|
||||
|
@ -60,10 +60,10 @@ impl Command for External {
|
||||
call: &Call,
|
||||
input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let redirect_stdout = call.has_flag("redirect-stdout");
|
||||
let redirect_stderr = call.has_flag("redirect-stderr");
|
||||
let redirect_combine = call.has_flag("redirect-combine");
|
||||
let trim_end_newline = call.has_flag("trim-end-newline");
|
||||
let redirect_stdout = call.has_flag(engine_state, stack, "redirect-stdout")?;
|
||||
let redirect_stderr = call.has_flag(engine_state, stack, "redirect-stderr")?;
|
||||
let redirect_combine = call.has_flag(engine_state, stack, "redirect-combine")?;
|
||||
let trim_end_newline = call.has_flag(engine_state, stack, "trim-end-newline")?;
|
||||
|
||||
if redirect_combine && (redirect_stdout || redirect_stderr) {
|
||||
return Err(ShellError::ExternalCommand {
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user