diff --git a/crates/nu-cli/src/commands/commandline.rs b/crates/nu-cli/src/commands/commandline.rs index 91083539b306..4c39d10e4473 100644 --- a/crates/nu-cli/src/commands/commandline.rs +++ b/crates/nu-cli/src/commands/commandline.rs @@ -71,7 +71,7 @@ impl Command for Commandline { if let Some(cmd) = call.opt::(engine_state, stack, 0)? { let mut repl = engine_state.repl_state.lock().expect("repl state mutex"); - if call.has_flag("cursor") { + if call.has_flag(engine_state, stack, "cursor")? { let cmd_str = cmd.as_string()?; match cmd_str.parse::() { Ok(n) => { @@ -96,9 +96,9 @@ impl Command for Commandline { }) } } - } else if call.has_flag("append") { + } else if call.has_flag(engine_state, stack, "append")? { repl.buffer.push_str(&cmd.as_string()?); - } else if call.has_flag("insert") { + } else if call.has_flag(engine_state, stack, "insert")? { let cmd_str = cmd.as_string()?; let cursor_pos = repl.cursor_pos; repl.buffer.insert_str(cursor_pos, &cmd_str); @@ -110,10 +110,10 @@ impl Command for Commandline { Ok(Value::nothing(call.head).into_pipeline_data()) } else { let mut repl = engine_state.repl_state.lock().expect("repl state mutex"); - if call.has_flag("cursor-end") { + if call.has_flag(engine_state, stack, "cursor-end")? { repl.cursor_pos = repl.buffer.graphemes(true).count(); Ok(Value::nothing(call.head).into_pipeline_data()) - } else if call.has_flag("cursor") { + } else if call.has_flag(engine_state, stack, "cursor")? { let char_pos = repl .buffer .grapheme_indices(true) diff --git a/crates/nu-cli/src/commands/history/history_.rs b/crates/nu-cli/src/commands/history/history_.rs index c4d15a9548d4..200760b52f99 100644 --- a/crates/nu-cli/src/commands/history/history_.rs +++ b/crates/nu-cli/src/commands/history/history_.rs @@ -1,3 +1,4 @@ +use nu_engine::CallExt; use nu_protocol::ast::Call; use nu_protocol::engine::{Command, EngineState, Stack}; use nu_protocol::{ @@ -40,7 +41,7 @@ impl Command for History { fn run( &self, engine_state: &EngineState, - _stack: &mut Stack, + stack: &mut Stack, call: &Call, _input: PipelineData, ) -> Result { @@ -48,8 +49,8 @@ impl Command for History { // todo for sqlite history this command should be an alias to `open ~/.config/nushell/history.sqlite3 | get history` if let Some(config_path) = nu_path::config_dir() { - let clear = call.has_flag("clear"); - let long = call.has_flag("long"); + let clear = call.has_flag(engine_state, stack, "clear")?; + let long = call.has_flag(engine_state, stack, "long")?; let ctrlc = engine_state.ctrlc.clone(); let mut history_path = config_path; diff --git a/crates/nu-cli/src/print.rs b/crates/nu-cli/src/print.rs index f5eb6e4215f4..b213780ded55 100644 --- a/crates/nu-cli/src/print.rs +++ b/crates/nu-cli/src/print.rs @@ -54,8 +54,8 @@ Since this command has no output, there is no point in piping it with other comm input: PipelineData, ) -> Result { let args: Vec = call.rest(engine_state, stack, 0)?; - let no_newline = call.has_flag("no-newline"); - let to_stderr = call.has_flag("stderr"); + let no_newline = call.has_flag(engine_state, stack, "no-newline")?; + let to_stderr = call.has_flag(engine_state, stack, "stderr")?; // This will allow for easy printing of pipelines as well if !args.is_empty() { diff --git a/crates/nu-cmd-dataframe/src/dataframe/eager/append.rs b/crates/nu-cmd-dataframe/src/dataframe/eager/append.rs index ac079d43a418..9c7d7b99c2fa 100644 --- a/crates/nu-cmd-dataframe/src/dataframe/eager/append.rs +++ b/crates/nu-cmd-dataframe/src/dataframe/eager/append.rs @@ -110,7 +110,7 @@ fn command( ) -> Result { let other: Value = call.req(engine_state, stack, 0)?; - let axis = if call.has_flag("col") { + let axis = if call.has_flag(engine_state, stack, "col")? { Axis::Column } else { Axis::Row diff --git a/crates/nu-cmd-dataframe/src/dataframe/eager/drop_duplicates.rs b/crates/nu-cmd-dataframe/src/dataframe/eager/drop_duplicates.rs index 9128059125ef..3c440658497d 100644 --- a/crates/nu-cmd-dataframe/src/dataframe/eager/drop_duplicates.rs +++ b/crates/nu-cmd-dataframe/src/dataframe/eager/drop_duplicates.rs @@ -92,7 +92,7 @@ fn command( let subset_slice = subset.as_ref().map(|cols| &cols[..]); - let keep_strategy = if call.has_flag("last") { + let keep_strategy = if call.has_flag(engine_state, stack, "last")? { UniqueKeepStrategy::Last } else { UniqueKeepStrategy::First diff --git a/crates/nu-cmd-dataframe/src/dataframe/eager/dummies.rs b/crates/nu-cmd-dataframe/src/dataframe/eager/dummies.rs index 1a1264d999e7..f4fb542f1a15 100644 --- a/crates/nu-cmd-dataframe/src/dataframe/eager/dummies.rs +++ b/crates/nu-cmd-dataframe/src/dataframe/eager/dummies.rs @@ -1,4 +1,5 @@ use super::super::values::NuDataFrame; +use nu_engine::CallExt; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, @@ -78,12 +79,12 @@ impl Command for Dummies { } fn command( - _engine_state: &EngineState, - _stack: &mut Stack, + engine_state: &EngineState, + stack: &mut Stack, call: &Call, input: PipelineData, ) -> Result { - let drop_first: bool = call.has_flag("drop-first"); + let drop_first: bool = call.has_flag(engine_state, stack, "drop-first")?; let df = NuDataFrame::try_from_pipeline(input, call.head)?; df.as_ref() diff --git a/crates/nu-cmd-dataframe/src/dataframe/eager/open.rs b/crates/nu-cmd-dataframe/src/dataframe/eager/open.rs index ed4db7161c8a..29638b828956 100644 --- a/crates/nu-cmd-dataframe/src/dataframe/eager/open.rs +++ b/crates/nu-cmd-dataframe/src/dataframe/eager/open.rs @@ -139,7 +139,7 @@ fn from_parquet( stack: &mut Stack, call: &Call, ) -> Result { - if call.has_flag("lazy") { + if call.has_flag(engine_state, stack, "lazy")? { let file: String = call.req(engine_state, stack, 0)?; let args = ScanArgsParquet { n_rows: None, @@ -238,7 +238,7 @@ fn from_ipc( stack: &mut Stack, call: &Call, ) -> Result { - if call.has_flag("lazy") { + if call.has_flag(engine_state, stack, "lazy")? { let file: String = call.req(engine_state, stack, 0)?; let args = ScanArgsIpc { n_rows: None, @@ -363,12 +363,12 @@ fn from_csv( call: &Call, ) -> Result { let delimiter: Option> = call.get_flag(engine_state, stack, "delimiter")?; - let no_header: bool = call.has_flag("no-header"); + let no_header: bool = call.has_flag(engine_state, stack, "no-header")?; let infer_schema: Option = call.get_flag(engine_state, stack, "infer-schema")?; let skip_rows: Option = call.get_flag(engine_state, stack, "skip-rows")?; let columns: Option> = call.get_flag(engine_state, stack, "columns")?; - if call.has_flag("lazy") { + if call.has_flag(engine_state, stack, "lazy")? { let file: String = call.req(engine_state, stack, 0)?; let csv_reader = LazyCsvReader::new(file); diff --git a/crates/nu-cmd-dataframe/src/dataframe/eager/sample.rs b/crates/nu-cmd-dataframe/src/dataframe/eager/sample.rs index acb5575411f6..67c0e6a0dc1d 100644 --- a/crates/nu-cmd-dataframe/src/dataframe/eager/sample.rs +++ b/crates/nu-cmd-dataframe/src/dataframe/eager/sample.rs @@ -88,8 +88,8 @@ fn command( let seed: Option = call .get_flag::(engine_state, stack, "seed")? .map(|val| val as u64); - let replace: bool = call.has_flag("replace"); - let shuffle: bool = call.has_flag("shuffle"); + let replace: bool = call.has_flag(engine_state, stack, "replace")?; + let shuffle: bool = call.has_flag(engine_state, stack, "shuffle")?; let df = NuDataFrame::try_from_pipeline(input, call.head)?; diff --git a/crates/nu-cmd-dataframe/src/dataframe/eager/to_csv.rs b/crates/nu-cmd-dataframe/src/dataframe/eager/to_csv.rs index aff9d0429b8d..55f86bcea564 100644 --- a/crates/nu-cmd-dataframe/src/dataframe/eager/to_csv.rs +++ b/crates/nu-cmd-dataframe/src/dataframe/eager/to_csv.rs @@ -70,7 +70,7 @@ fn command( ) -> Result { let file_name: Spanned = call.req(engine_state, stack, 0)?; let delimiter: Option> = call.get_flag(engine_state, stack, "delimiter")?; - let no_header: bool = call.has_flag("no-header"); + let no_header: bool = call.has_flag(engine_state, stack, "no-header")?; let mut df = NuDataFrame::try_from_pipeline(input, call.head)?; diff --git a/crates/nu-cmd-dataframe/src/dataframe/eager/to_nu.rs b/crates/nu-cmd-dataframe/src/dataframe/eager/to_nu.rs index 2d34a6b220f5..cf4cde260f6d 100644 --- a/crates/nu-cmd-dataframe/src/dataframe/eager/to_nu.rs +++ b/crates/nu-cmd-dataframe/src/dataframe/eager/to_nu.rs @@ -100,7 +100,7 @@ fn dataframe_command( input: Value, ) -> Result { let rows: Option = call.get_flag(engine_state, stack, "rows")?; - let tail: bool = call.has_flag("tail"); + let tail: bool = call.has_flag(engine_state, stack, "tail")?; let df = NuDataFrame::try_from_value(input)?; diff --git a/crates/nu-cmd-dataframe/src/dataframe/lazy/join.rs b/crates/nu-cmd-dataframe/src/dataframe/lazy/join.rs index e51cc84ad7d0..956a81000fbe 100644 --- a/crates/nu-cmd-dataframe/src/dataframe/lazy/join.rs +++ b/crates/nu-cmd-dataframe/src/dataframe/lazy/join.rs @@ -171,9 +171,9 @@ impl Command for LazyJoin { call: &Call, input: PipelineData, ) -> Result { - let left = call.has_flag("left"); - let outer = call.has_flag("outer"); - let cross = call.has_flag("cross"); + let left = call.has_flag(engine_state, stack, "left")?; + let outer = call.has_flag(engine_state, stack, "outer")?; + let cross = call.has_flag(engine_state, stack, "cross")?; let how = if left { JoinType::Left diff --git a/crates/nu-cmd-dataframe/src/dataframe/lazy/sort_by_expr.rs b/crates/nu-cmd-dataframe/src/dataframe/lazy/sort_by_expr.rs index a45c66498b52..bd14b7a416a4 100644 --- a/crates/nu-cmd-dataframe/src/dataframe/lazy/sort_by_expr.rs +++ b/crates/nu-cmd-dataframe/src/dataframe/lazy/sort_by_expr.rs @@ -107,8 +107,8 @@ impl Command for LazySortBy { let vals: Vec = call.rest(engine_state, stack, 0)?; let value = Value::list(vals, call.head); let expressions = NuExpression::extract_exprs(value)?; - let nulls_last = call.has_flag("nulls-last"); - let maintain_order = call.has_flag("maintain-order"); + let nulls_last = call.has_flag(engine_state, stack, "nulls-last")?; + let maintain_order = call.has_flag(engine_state, stack, "maintain-order")?; let reverse: Option> = call.get_flag(engine_state, stack, "reverse")?; let reverse = match reverse { diff --git a/crates/nu-cmd-dataframe/src/dataframe/series/cumulative.rs b/crates/nu-cmd-dataframe/src/dataframe/series/cumulative.rs index c8da52105990..0fa262a56abd 100644 --- a/crates/nu-cmd-dataframe/src/dataframe/series/cumulative.rs +++ b/crates/nu-cmd-dataframe/src/dataframe/series/cumulative.rs @@ -103,7 +103,7 @@ fn command( input: PipelineData, ) -> Result { let cum_type: Spanned = call.req(engine_state, stack, 0)?; - let reverse = call.has_flag("reverse"); + let reverse = call.has_flag(engine_state, stack, "reverse")?; let df = NuDataFrame::try_from_pipeline(input, call.head)?; let series = df.as_series(call.head)?; diff --git a/crates/nu-cmd-dataframe/src/dataframe/series/date/as_date.rs b/crates/nu-cmd-dataframe/src/dataframe/series/date/as_date.rs index e277a38606fe..3d3a55269fbc 100644 --- a/crates/nu-cmd-dataframe/src/dataframe/series/date/as_date.rs +++ b/crates/nu-cmd-dataframe/src/dataframe/series/date/as_date.rs @@ -64,7 +64,7 @@ fn command( input: PipelineData, ) -> Result { let format: String = call.req(engine_state, stack, 0)?; - let not_exact = call.has_flag("not-exact"); + let not_exact = call.has_flag(engine_state, stack, "not-exact")?; let df = NuDataFrame::try_from_pipeline(input, call.head)?; let series = df.as_series(call.head)?; diff --git a/crates/nu-cmd-dataframe/src/dataframe/series/date/as_datetime.rs b/crates/nu-cmd-dataframe/src/dataframe/series/date/as_datetime.rs index a9cc67b2c5f2..5622a5b83d97 100644 --- a/crates/nu-cmd-dataframe/src/dataframe/series/date/as_datetime.rs +++ b/crates/nu-cmd-dataframe/src/dataframe/series/date/as_datetime.rs @@ -128,7 +128,7 @@ fn command( input: PipelineData, ) -> Result { let format: String = call.req(engine_state, stack, 0)?; - let not_exact = call.has_flag("not-exact"); + let not_exact = call.has_flag(engine_state, stack, "not-exact")?; let df = NuDataFrame::try_from_pipeline(input, call.head)?; let series = df.as_series(call.head)?; diff --git a/crates/nu-cmd-dataframe/src/dataframe/series/indexes/arg_sort.rs b/crates/nu-cmd-dataframe/src/dataframe/series/indexes/arg_sort.rs index 5fcf69b12595..4707ea6eee9d 100644 --- a/crates/nu-cmd-dataframe/src/dataframe/series/indexes/arg_sort.rs +++ b/crates/nu-cmd-dataframe/src/dataframe/series/indexes/arg_sort.rs @@ -1,5 +1,6 @@ use super::super::super::values::{Column, NuDataFrame}; +use nu_engine::CallExt; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, @@ -92,18 +93,18 @@ impl Command for ArgSort { } fn command( - _engine_state: &EngineState, - _stack: &mut Stack, + engine_state: &EngineState, + stack: &mut Stack, call: &Call, input: PipelineData, ) -> Result { let df = NuDataFrame::try_from_pipeline(input, call.head)?; let sort_options = SortOptions { - descending: call.has_flag("reverse"), - nulls_last: call.has_flag("nulls-last"), + descending: call.has_flag(engine_state, stack, "reverse")?, + nulls_last: call.has_flag(engine_state, stack, "nulls-last")?, multithreaded: true, - maintain_order: call.has_flag("maintain-order"), + maintain_order: call.has_flag(engine_state, stack, "maintain-order")?, }; let mut res = df diff --git a/crates/nu-cmd-dataframe/src/dataframe/series/unique.rs b/crates/nu-cmd-dataframe/src/dataframe/series/unique.rs index 3622cc59e4d9..df40e8fa4c62 100644 --- a/crates/nu-cmd-dataframe/src/dataframe/series/unique.rs +++ b/crates/nu-cmd-dataframe/src/dataframe/series/unique.rs @@ -114,8 +114,8 @@ fn command_lazy( call: &Call, lazy: NuLazyFrame, ) -> Result { - let last = call.has_flag("last"); - let maintain = call.has_flag("maintain-order"); + let last = call.has_flag(engine_state, stack, "last")?; + let maintain = call.has_flag(engine_state, stack, "maintain-order")?; let subset: Option = call.get_flag(engine_state, stack, "subset")?; let subset = match subset { diff --git a/crates/nu-cmd-extra/src/extra/bits/not.rs b/crates/nu-cmd-extra/src/extra/bits/not.rs index 82d822e9aeaf..24d11167909f 100644 --- a/crates/nu-cmd-extra/src/extra/bits/not.rs +++ b/crates/nu-cmd-extra/src/extra/bits/not.rs @@ -54,7 +54,7 @@ impl Command for BitsNot { input: PipelineData, ) -> Result { let head = call.head; - let signed = call.has_flag("signed"); + let signed = call.has_flag(engine_state, stack, "signed")?; let number_bytes: Option> = call.get_flag(engine_state, stack, "number-bytes")?; let bytes_len = get_number_bytes(number_bytes.as_ref()); diff --git a/crates/nu-cmd-extra/src/extra/bits/rotate_left.rs b/crates/nu-cmd-extra/src/extra/bits/rotate_left.rs index aaf260394656..10d8696572db 100644 --- a/crates/nu-cmd-extra/src/extra/bits/rotate_left.rs +++ b/crates/nu-cmd-extra/src/extra/bits/rotate_left.rs @@ -57,7 +57,7 @@ impl Command for BitsRol { ) -> Result { let head = call.head; let bits: usize = call.req(engine_state, stack, 0)?; - let signed = call.has_flag("signed"); + let signed = call.has_flag(engine_state, stack, "signed")?; let number_bytes: Option> = call.get_flag(engine_state, stack, "number-bytes")?; let bytes_len = get_number_bytes(number_bytes.as_ref()); diff --git a/crates/nu-cmd-extra/src/extra/bits/rotate_right.rs b/crates/nu-cmd-extra/src/extra/bits/rotate_right.rs index 54472de6199f..13a134d919d5 100644 --- a/crates/nu-cmd-extra/src/extra/bits/rotate_right.rs +++ b/crates/nu-cmd-extra/src/extra/bits/rotate_right.rs @@ -57,7 +57,7 @@ impl Command for BitsRor { ) -> Result { let head = call.head; let bits: usize = call.req(engine_state, stack, 0)?; - let signed = call.has_flag("signed"); + let signed = call.has_flag(engine_state, stack, "signed")?; let number_bytes: Option> = call.get_flag(engine_state, stack, "number-bytes")?; let bytes_len = get_number_bytes(number_bytes.as_ref()); diff --git a/crates/nu-cmd-extra/src/extra/bits/shift_left.rs b/crates/nu-cmd-extra/src/extra/bits/shift_left.rs index 0e8295a074e8..baa2bb3b3f6e 100644 --- a/crates/nu-cmd-extra/src/extra/bits/shift_left.rs +++ b/crates/nu-cmd-extra/src/extra/bits/shift_left.rs @@ -57,7 +57,7 @@ impl Command for BitsShl { ) -> Result { let head = call.head; let bits: usize = call.req(engine_state, stack, 0)?; - let signed = call.has_flag("signed"); + let signed = call.has_flag(engine_state, stack, "signed")?; let number_bytes: Option> = call.get_flag(engine_state, stack, "number-bytes")?; let bytes_len = get_number_bytes(number_bytes.as_ref()); diff --git a/crates/nu-cmd-extra/src/extra/bits/shift_right.rs b/crates/nu-cmd-extra/src/extra/bits/shift_right.rs index c1c59b7a2cfc..b4625e56b21b 100644 --- a/crates/nu-cmd-extra/src/extra/bits/shift_right.rs +++ b/crates/nu-cmd-extra/src/extra/bits/shift_right.rs @@ -57,7 +57,7 @@ impl Command for BitsShr { ) -> Result { let head = call.head; let bits: usize = call.req(engine_state, stack, 0)?; - let signed = call.has_flag("signed"); + let signed = call.has_flag(engine_state, stack, "signed")?; let number_bytes: Option> = call.get_flag(engine_state, stack, "number-bytes")?; let bytes_len = get_number_bytes(number_bytes.as_ref()); diff --git a/crates/nu-cmd-extra/src/extra/filters/roll/roll_left.rs b/crates/nu-cmd-extra/src/extra/filters/roll/roll_left.rs index 9bc76861d1ee..beb6193fd04d 100644 --- a/crates/nu-cmd-extra/src/extra/filters/roll/roll_left.rs +++ b/crates/nu-cmd-extra/src/extra/filters/roll/roll_left.rs @@ -100,7 +100,7 @@ impl Command for RollLeft { let by: Option = call.get_flag(engine_state, stack, "by")?; let metadata = input.metadata(); - let cells_only = call.has_flag("cells-only"); + let cells_only = call.has_flag(engine_state, stack, "cells-only")?; let value = input.into_value(call.head); let rotated_value = horizontal_rotate_value(value, by, cells_only, &HorizontalDirection::Left)?; diff --git a/crates/nu-cmd-extra/src/extra/filters/roll/roll_right.rs b/crates/nu-cmd-extra/src/extra/filters/roll/roll_right.rs index a36cda9c0640..be781519dc20 100644 --- a/crates/nu-cmd-extra/src/extra/filters/roll/roll_right.rs +++ b/crates/nu-cmd-extra/src/extra/filters/roll/roll_right.rs @@ -100,7 +100,7 @@ impl Command for RollRight { let by: Option = call.get_flag(engine_state, stack, "by")?; let metadata = input.metadata(); - let cells_only = call.has_flag("cells-only"); + let cells_only = call.has_flag(engine_state, stack, "cells-only")?; let value = input.into_value(call.head); let rotated_value = horizontal_rotate_value(value, by, cells_only, &HorizontalDirection::Right)?; diff --git a/crates/nu-cmd-extra/src/extra/filters/rotate.rs b/crates/nu-cmd-extra/src/extra/filters/rotate.rs index 29c5c39689f0..dd98a2f07f8e 100644 --- a/crates/nu-cmd-extra/src/extra/filters/rotate.rs +++ b/crates/nu-cmd-extra/src/extra/filters/rotate.rs @@ -167,7 +167,7 @@ pub fn rotate( let mut new_values = vec![]; let mut not_a_record = false; let mut total_rows = values.len(); - let ccw: bool = call.has_flag("ccw"); + let ccw: bool = call.has_flag(engine_state, stack, "ccw")?; if !ccw { values.reverse(); diff --git a/crates/nu-cmd-extra/src/extra/formats/to/html.rs b/crates/nu-cmd-extra/src/extra/formats/to/html.rs index 00da92e1befc..77eee055e96e 100644 --- a/crates/nu-cmd-extra/src/extra/formats/to/html.rs +++ b/crates/nu-cmd-extra/src/extra/formats/to/html.rs @@ -239,11 +239,11 @@ fn to_html( stack: &mut Stack, ) -> Result { let head = call.head; - let html_color = call.has_flag("html-color"); - let no_color = call.has_flag("no-color"); - let dark = call.has_flag("dark"); - let partial = call.has_flag("partial"); - let list = call.has_flag("list"); + let html_color = call.has_flag(engine_state, stack, "html-color")?; + let no_color = call.has_flag(engine_state, stack, "no-color")?; + let dark = call.has_flag(engine_state, stack, "dark")?; + let partial = call.has_flag(engine_state, stack, "partial")?; + let list = call.has_flag(engine_state, stack, "list")?; let theme: Option> = call.get_flag(engine_state, stack, "theme")?; let config = engine_state.get_config(); diff --git a/crates/nu-cmd-extra/src/extra/math/arccos.rs b/crates/nu-cmd-extra/src/extra/math/arccos.rs index ec0dfa89ef21..6477792f2b71 100644 --- a/crates/nu-cmd-extra/src/extra/math/arccos.rs +++ b/crates/nu-cmd-extra/src/extra/math/arccos.rs @@ -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}; @@ -35,12 +36,12 @@ impl Command for SubCommand { fn run( &self, engine_state: &EngineState, - _stack: &mut Stack, + stack: &mut Stack, call: &Call, input: PipelineData, ) -> Result { let head = call.head; - let use_degrees = call.has_flag("degrees"); + let use_degrees = call.has_flag(engine_state, stack, "degrees")?; // This doesn't match explicit nulls if matches!(input, PipelineData::Empty) { return Err(ShellError::PipelineEmpty { dst_span: head }); diff --git a/crates/nu-cmd-extra/src/extra/math/arcsin.rs b/crates/nu-cmd-extra/src/extra/math/arcsin.rs index 766417e8e63e..1cc675c95c6a 100644 --- a/crates/nu-cmd-extra/src/extra/math/arcsin.rs +++ b/crates/nu-cmd-extra/src/extra/math/arcsin.rs @@ -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}; @@ -35,12 +36,12 @@ impl Command for SubCommand { fn run( &self, engine_state: &EngineState, - _stack: &mut Stack, + stack: &mut Stack, call: &Call, input: PipelineData, ) -> Result { let head = call.head; - let use_degrees = call.has_flag("degrees"); + let use_degrees = call.has_flag(engine_state, stack, "degrees")?; // This doesn't match explicit nulls if matches!(input, PipelineData::Empty) { return Err(ShellError::PipelineEmpty { dst_span: head }); diff --git a/crates/nu-cmd-extra/src/extra/math/arctan.rs b/crates/nu-cmd-extra/src/extra/math/arctan.rs index cca6bca71a29..4881989046f5 100644 --- a/crates/nu-cmd-extra/src/extra/math/arctan.rs +++ b/crates/nu-cmd-extra/src/extra/math/arctan.rs @@ -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}; @@ -35,12 +36,12 @@ impl Command for SubCommand { fn run( &self, engine_state: &EngineState, - _stack: &mut Stack, + stack: &mut Stack, call: &Call, input: PipelineData, ) -> Result { let head = call.head; - let use_degrees = call.has_flag("degrees"); + let use_degrees = call.has_flag(engine_state, stack, "degrees")?; // This doesn't match explicit nulls if matches!(input, PipelineData::Empty) { return Err(ShellError::PipelineEmpty { dst_span: head }); diff --git a/crates/nu-cmd-extra/src/extra/math/cos.rs b/crates/nu-cmd-extra/src/extra/math/cos.rs index 2a45e6383b8f..91868078ce11 100644 --- a/crates/nu-cmd-extra/src/extra/math/cos.rs +++ b/crates/nu-cmd-extra/src/extra/math/cos.rs @@ -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}; @@ -34,12 +35,12 @@ impl Command for SubCommand { fn run( &self, engine_state: &EngineState, - _stack: &mut Stack, + stack: &mut Stack, call: &Call, input: PipelineData, ) -> Result { let head = call.head; - let use_degrees = call.has_flag("degrees"); + let use_degrees = call.has_flag(engine_state, stack, "degrees")?; // This doesn't match explicit nulls if matches!(input, PipelineData::Empty) { return Err(ShellError::PipelineEmpty { dst_span: head }); diff --git a/crates/nu-cmd-extra/src/extra/math/sin.rs b/crates/nu-cmd-extra/src/extra/math/sin.rs index 25dcadf3d829..4aaf3e1df67b 100644 --- a/crates/nu-cmd-extra/src/extra/math/sin.rs +++ b/crates/nu-cmd-extra/src/extra/math/sin.rs @@ -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}; @@ -34,12 +35,12 @@ impl Command for SubCommand { fn run( &self, engine_state: &EngineState, - _stack: &mut Stack, + stack: &mut Stack, call: &Call, input: PipelineData, ) -> Result { let head = call.head; - let use_degrees = call.has_flag("degrees"); + let use_degrees = call.has_flag(engine_state, stack, "degrees")?; // This doesn't match explicit nulls if matches!(input, PipelineData::Empty) { return Err(ShellError::PipelineEmpty { dst_span: head }); diff --git a/crates/nu-cmd-extra/src/extra/math/tan.rs b/crates/nu-cmd-extra/src/extra/math/tan.rs index b073ef831d88..16befaa11a48 100644 --- a/crates/nu-cmd-extra/src/extra/math/tan.rs +++ b/crates/nu-cmd-extra/src/extra/math/tan.rs @@ -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}; @@ -34,12 +35,12 @@ impl Command for SubCommand { fn run( &self, engine_state: &EngineState, - _stack: &mut Stack, + stack: &mut Stack, call: &Call, input: PipelineData, ) -> Result { let head = call.head; - let use_degrees = call.has_flag("degrees"); + let use_degrees = call.has_flag(engine_state, stack, "degrees")?; // This doesn't match explicit nulls if matches!(input, PipelineData::Empty) { return Err(ShellError::PipelineEmpty { dst_span: head }); diff --git a/crates/nu-cmd-lang/src/core_commands/collect.rs b/crates/nu-cmd-lang/src/core_commands/collect.rs index ee91fd741fdb..3c1e71e32218 100644 --- a/crates/nu-cmd-lang/src/core_commands/collect.rs +++ b/crates/nu-cmd-lang/src/core_commands/collect.rs @@ -67,7 +67,7 @@ impl Command for Collect { ) .map(|x| x.set_metadata(metadata)); - if call.has_flag("keep-env") { + if call.has_flag(engine_state, stack, "keep-env")? { redirect_env(engine_state, stack, &stack_captures); // for when we support `data | let x = $in;` // remove the variables added earlier diff --git a/crates/nu-cmd-lang/src/core_commands/describe.rs b/crates/nu-cmd-lang/src/core_commands/describe.rs index ceffcadbd9c0..50993bf575e8 100644 --- a/crates/nu-cmd-lang/src/core_commands/describe.rs +++ b/crates/nu-cmd-lang/src/core_commands/describe.rs @@ -1,3 +1,4 @@ +use nu_engine::CallExt; use nu_protocol::{ ast::Call, engine::{Closure, Command, EngineState, Stack, StateWorkingSet}, @@ -44,20 +45,30 @@ impl Command for Describe { fn run( &self, engine_state: &EngineState, - _stack: &mut Stack, + stack: &mut Stack, call: &Call, input: PipelineData, ) -> Result { - run(Some(engine_state), call, input) + let options = Options { + no_collect: call.has_flag(engine_state, stack, "no-collect")?, + detailed: call.has_flag(engine_state, stack, "detailed")?, + collect_lazyrecords: call.has_flag(engine_state, stack, "collect-lazyrecords")?, + }; + run(Some(engine_state), call, input, options) } fn run_const( &self, - _working_set: &StateWorkingSet, + working_set: &StateWorkingSet, call: &Call, input: PipelineData, ) -> Result { - run(None, call, input) + let options = Options { + no_collect: call.has_flag_const(working_set, "no-collect")?, + detailed: call.has_flag_const(working_set, "detailed")?, + collect_lazyrecords: call.has_flag_const(working_set, "collect-lazyrecords")?, + }; + run(None, call, input, options) } fn examples(&self) -> Vec { @@ -148,15 +159,21 @@ impl Command for Describe { } } +#[derive(Clone, Copy)] +struct Options { + no_collect: bool, + detailed: bool, + collect_lazyrecords: bool, +} + fn run( engine_state: Option<&EngineState>, call: &Call, input: PipelineData, + options: Options, ) -> Result { let metadata = input.metadata().clone().map(Box::new); let head = call.head; - let no_collect: bool = call.has_flag("no-collect"); - let detailed = call.has_flag("detailed"); let description: Value = match input { PipelineData::ExternalStream { @@ -165,7 +182,7 @@ fn run( ref exit_code, .. } => { - if detailed { + if options.detailed { Value::record( record!( "type" => Value::string("stream", head), @@ -212,23 +229,23 @@ fn run( } } PipelineData::ListStream(_, _) => { - if detailed { + if options.detailed { Value::record( record!( "type" => Value::string("stream", head), "origin" => Value::string("nushell", head), "subtype" => { - if no_collect { + if options.no_collect { Value::string("any", head) } else { - describe_value(input.into_value(head), head, engine_state, call)? + describe_value(input.into_value(head), head, engine_state, call, options)? } }, "metadata" => metadata_to_value(metadata, head), ), head, ) - } else if no_collect { + } else if options.no_collect { Value::string("stream", head) } else { let value = input.into_value(head); @@ -242,13 +259,13 @@ fn run( } _ => { let value = input.into_value(head); - if !detailed { + if !options.detailed { match value { Value::CustomValue { val, .. } => Value::string(val.value_string(), head), _ => Value::string(value.get_type().to_string(), head), } } else { - describe_value(value, head, engine_state, call)? + describe_value(value, head, engine_state, call, options)? } } }; @@ -273,12 +290,13 @@ fn describe_value( head: nu_protocol::Span, engine_state: Option<&EngineState>, call: &Call, + options: Options, ) -> Result { Ok(match value { Value::CustomValue { val, internal_span } => Value::record( record!( "type" => Value::string("custom", head), - "subtype" => run(engine_state,call, val.to_base_value(internal_span)?.into_pipeline_data())?.into_value(head), + "subtype" => run(engine_state,call, val.to_base_value(internal_span)?.into_pipeline_data(), options)?.into_value(head), ), head, ), @@ -303,6 +321,7 @@ fn describe_value( head, engine_state, call, + options, )?); } @@ -321,7 +340,7 @@ fn describe_value( "length" => Value::int(vals.len() as i64, head), "values" => Value::list(vals.into_iter().map(|v| Ok(compact_primitive_description( - describe_value(v, head, engine_state, call)? + describe_value(v, head, engine_state, call, options)? )) ) .collect::, ShellError>>()?, head), @@ -381,16 +400,15 @@ fn describe_value( head, ), Value::LazyRecord { val, .. } => { - let collect_lazyrecords: bool = call.has_flag("collect-lazyrecords"); let mut record = Record::new(); record.push("type", Value::string("record", head)); record.push("lazy", Value::bool(true, head)); - if collect_lazyrecords { + if options.collect_lazyrecords { let collected = val.collect()?; if let Value::Record { mut val, .. } = - describe_value(collected, head, engine_state, call)? + describe_value(collected, head, engine_state, call, options)? { record.push("length", Value::int(val.len() as i64, head)); for (_k, v) in val.iter_mut() { @@ -399,6 +417,7 @@ fn describe_value( head, engine_state, call, + options, )?); } diff --git a/crates/nu-cmd-lang/src/core_commands/do_.rs b/crates/nu-cmd-lang/src/core_commands/do_.rs index b91ab911255d..dc36a764d1fb 100644 --- a/crates/nu-cmd-lang/src/core_commands/do_.rs +++ b/crates/nu-cmd-lang/src/core_commands/do_.rs @@ -70,11 +70,13 @@ impl Command for Do { ) -> Result { let block: Closure = call.req(engine_state, caller_stack, 0)?; let rest: Vec = call.rest(engine_state, caller_stack, 1)?; - let ignore_all_errors = call.has_flag("ignore-errors"); - let ignore_shell_errors = ignore_all_errors || call.has_flag("ignore-shell-errors"); - let ignore_program_errors = ignore_all_errors || call.has_flag("ignore-program-errors"); - let capture_errors = call.has_flag("capture-errors"); - let has_env = call.has_flag("env"); + let ignore_all_errors = call.has_flag(engine_state, caller_stack, "ignore-errors")?; + let ignore_shell_errors = ignore_all_errors + || call.has_flag(engine_state, caller_stack, "ignore-shell-errors")?; + let ignore_program_errors = ignore_all_errors + || call.has_flag(engine_state, caller_stack, "ignore-program-errors")?; + let capture_errors = call.has_flag(engine_state, caller_stack, "capture-errors")?; + let has_env = call.has_flag(engine_state, caller_stack, "env")?; let mut callee_stack = caller_stack.captures_to_stack(block.captures); let block = engine_state.get_block(block.block_id); diff --git a/crates/nu-cmd-lang/src/core_commands/error_make.rs b/crates/nu-cmd-lang/src/core_commands/error_make.rs index 11eeeea06d15..bd68392c5c0e 100644 --- a/crates/nu-cmd-lang/src/core_commands/error_make.rs +++ b/crates/nu-cmd-lang/src/core_commands/error_make.rs @@ -46,7 +46,7 @@ impl Command for ErrorMake { ) -> Result { let arg: Value = call.req(engine_state, stack, 0)?; - let throw_span = if call.has_flag("unspanned") { + let throw_span = if call.has_flag(engine_state, stack, "unspanned")? { None } else { Some(call.head) diff --git a/crates/nu-cmd-lang/src/core_commands/for_.rs b/crates/nu-cmd-lang/src/core_commands/for_.rs index 130e17079821..149309e94cc6 100644 --- a/crates/nu-cmd-lang/src/core_commands/for_.rs +++ b/crates/nu-cmd-lang/src/core_commands/for_.rs @@ -74,7 +74,7 @@ impl Command for For { let block: Block = call.req(engine_state, stack, 2)?; - let numbered = call.has_flag("numbered"); + let numbered = call.has_flag(engine_state, stack, "numbered")?; let ctrlc = engine_state.ctrlc.clone(); let engine_state = engine_state.clone(); diff --git a/crates/nu-cmd-lang/src/core_commands/hide_env.rs b/crates/nu-cmd-lang/src/core_commands/hide_env.rs index 91f331b2a77e..4cbc50c877ff 100644 --- a/crates/nu-cmd-lang/src/core_commands/hide_env.rs +++ b/crates/nu-cmd-lang/src/core_commands/hide_env.rs @@ -42,7 +42,7 @@ impl Command for HideEnv { _input: PipelineData, ) -> Result { let env_var_names: Vec> = call.rest(engine_state, stack, 0)?; - let ignore_errors = call.has_flag("ignore-errors"); + let ignore_errors = call.has_flag(engine_state, stack, "ignore-errors")?; for name in env_var_names { if !stack.remove_env_var(engine_state, &name.item) && !ignore_errors { diff --git a/crates/nu-command/src/bytes/add.rs b/crates/nu-command/src/bytes/add.rs index a5a68d74e71d..30c4231ace9a 100644 --- a/crates/nu-command/src/bytes/add.rs +++ b/crates/nu-command/src/bytes/add.rs @@ -75,7 +75,7 @@ impl Command for BytesAdd { let cell_paths: Vec = call.rest(engine_state, stack, 1)?; let cell_paths = (!cell_paths.is_empty()).then_some(cell_paths); let index: Option = 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, diff --git a/crates/nu-command/src/bytes/build_.rs b/crates/nu-command/src/bytes/build_.rs index 99ea3cac9a9e..ef7c76240890 100644 --- a/crates/nu-command/src/bytes/build_.rs +++ b/crates/nu-command/src/bytes/build_.rs @@ -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::{ diff --git a/crates/nu-command/src/bytes/index_of.rs b/crates/nu-command/src/bytes/index_of.rs index be49523a345e..711aa3e3d354 100644 --- a/crates/nu-command/src/bytes/index_of.rs +++ b/crates/nu-command/src/bytes/index_of.rs @@ -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()) diff --git a/crates/nu-command/src/bytes/remove.rs b/crates/nu-command/src/bytes/remove.rs index b89b0c8879de..1404a69ddb5c 100644 --- a/crates/nu-command/src/bytes/remove.rs +++ b/crates/nu-command/src/bytes/remove.rs @@ -74,9 +74,9 @@ impl Command for BytesRemove { let pattern_to_remove: Vec = 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()) diff --git a/crates/nu-command/src/bytes/replace.rs b/crates/nu-command/src/bytes/replace.rs index 3483bbaba78d..e90b138bab8b 100644 --- a/crates/nu-command/src/bytes/replace.rs +++ b/crates/nu-command/src/bytes/replace.rs @@ -76,7 +76,7 @@ impl Command for BytesReplace { find: find.item, replace: call.req::>(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()) diff --git a/crates/nu-command/src/conversions/into/binary.rs b/crates/nu-command/src/conversions/into/binary.rs index 5b8fa87e29a3..2c349b943d4b 100644 --- a/crates/nu-command/src/conversions/into/binary.rs +++ b/crates/nu-command/src/conversions/into/binary.rs @@ -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()) } diff --git a/crates/nu-command/src/conversions/into/datetime.rs b/crates/nu-command/src/conversions/into/datetime.rs index 8efc7185968b..057a8f1e732f 100644 --- a/crates/nu-command/src/conversions/into/datetime.rs +++ b/crates/nu-command/src/conversions/into/datetime.rs @@ -116,9 +116,9 @@ impl Command for SubCommand { call: &Call, input: PipelineData, ) -> Result { - 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)?; diff --git a/crates/nu-command/src/conversions/into/string.rs b/crates/nu-command/src/conversions/into/string.rs index 5d39446d7ac2..f4e671840af7 100644 --- a/crates/nu-command/src/conversions/into/string.rs +++ b/crates/nu-command/src/conversions/into/string.rs @@ -11,7 +11,6 @@ use num_format::ToFormattedString; struct Arguments { decimals_value: Option, - decimals: bool, cell_paths: Option>, config: Config, } @@ -148,11 +147,10 @@ fn string_helper( call: &Call, input: PipelineData, ) -> Result { - let decimals = call.has_flag("decimals"); let head = call.head; let decimals_value: Option = 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) diff --git a/crates/nu-command/src/debug/ast.rs b/crates/nu-command/src/debug/ast.rs index 335c1a782bf4..f829cb972c01 100644 --- a/crates/nu-command/src/debug/ast.rs +++ b/crates/nu-command/src/debug/ast.rs @@ -41,8 +41,8 @@ impl Command for Ast { _input: PipelineData, ) -> Result { let pipeline: Spanned = 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(); diff --git a/crates/nu-command/src/debug/debug_.rs b/crates/nu-command/src/debug/debug_.rs index 10c5dccba656..30ee82141001 100644 --- a/crates/nu-command/src/debug/debug_.rs +++ b/crates/nu-command/src/debug/debug_.rs @@ -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 { 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? diff --git a/crates/nu-command/src/env/config/config_env.rs b/crates/nu-command/src/env/config/config_env.rs index d2b6bd12092f..75c9c11a846c 100644 --- a/crates/nu-command/src/env/config/config_env.rs +++ b/crates/nu-command/src/env/config/config_env.rs @@ -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 { // `--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()); } diff --git a/crates/nu-command/src/env/config/config_nu.rs b/crates/nu-command/src/env/config/config_nu.rs index 95a68cd49582..c5d16c369fe6 100644 --- a/crates/nu-command/src/env/config/config_nu.rs +++ b/crates/nu-command/src/env/config/config_nu.rs @@ -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 { // `--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()); } diff --git a/crates/nu-command/src/env/config/config_reset.rs b/crates/nu-command/src/env/config/config_reset.rs index 34bf7636a92a..42ddd2c75960 100644 --- a/crates/nu-command/src/env/config/config_reset.rs +++ b/crates/nu-command/src/env/config/config_reset.rs @@ -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 { - 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, diff --git a/crates/nu-command/src/filesystem/cp.rs b/crates/nu-command/src/filesystem/cp.rs index bd32e846df47..d05311584e6a 100644 --- a/crates/nu-command/src/filesystem/cp.rs +++ b/crates/nu-command/src/filesystem/cp.rs @@ -76,11 +76,11 @@ impl Command for Cp { ) -> Result { let src: Spanned = call.req(engine_state, stack, 0)?; let dst: Spanned = 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(); diff --git a/crates/nu-command/src/filesystem/glob.rs b/crates/nu-command/src/filesystem/glob.rs index e090438ced0f..2a0defa05ab6 100644 --- a/crates/nu-command/src/filesystem/glob.rs +++ b/crates/nu-command/src/filesystem/glob.rs @@ -137,9 +137,9 @@ impl Command for Glob { let span = call.head; let glob_pattern: Spanned = 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 = call.get_flag(engine_state, stack, "exclude")?; diff --git a/crates/nu-command/src/filesystem/ls.rs b/crates/nu-command/src/filesystem/ls.rs index 4641a5aeaad6..033497d96db9 100644 --- a/crates/nu-command/src/filesystem/ls.rs +++ b/crates/nu-command/src/filesystem/ls.rs @@ -73,13 +73,13 @@ impl Command for Ls { call: &Call, _input: PipelineData, ) -> Result { - 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)?; diff --git a/crates/nu-command/src/filesystem/mkdir.rs b/crates/nu-command/src/filesystem/mkdir.rs index 361e548a8ecc..ea21794ce69d 100644 --- a/crates/nu-command/src/filesystem/mkdir.rs +++ b/crates/nu-command/src/filesystem/mkdir.rs @@ -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 = VecDeque::new(); if directories.peek().is_none() { diff --git a/crates/nu-command/src/filesystem/mktemp.rs b/crates/nu-command/src/filesystem/mktemp.rs index b1fd4a8159c0..6355204fe321 100644 --- a/crates/nu-command/src/filesystem/mktemp.rs +++ b/crates/nu-command/src/filesystem/mktemp.rs @@ -84,9 +84,9 @@ impl Command for Mktemp { .cloned() .map(|i: Spanned| 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| i.item); diff --git a/crates/nu-command/src/filesystem/mv.rs b/crates/nu-command/src/filesystem/mv.rs index 0e6d39ae6a17..e0c3f6c87083 100644 --- a/crates/nu-command/src/filesystem/mv.rs +++ b/crates/nu-command/src/filesystem/mv.rs @@ -65,10 +65,10 @@ impl Command for Mv { // TODO: handle invalid directory or insufficient permissions when moving let spanned_source: Spanned = call.req(engine_state, stack, 0)?; let spanned_destination: Spanned = 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(); diff --git a/crates/nu-command/src/filesystem/open.rs b/crates/nu-command/src/filesystem/open.rs index 114bd3623c85..847628ab41d2 100644 --- a/crates/nu-command/src/filesystem/open.rs +++ b/crates/nu-command/src/filesystem/open.rs @@ -59,7 +59,7 @@ impl Command for Open { call: &Call, input: PipelineData, ) -> Result { - 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)?; diff --git a/crates/nu-command/src/filesystem/rm.rs b/crates/nu-command/src/filesystem/rm.rs index 17ecb65787bb..929d16f3f0a8 100644 --- a/crates/nu-command/src/filesystem/rm.rs +++ b/crates/nu-command/src/filesystem/rm.rs @@ -124,13 +124,13 @@ fn rm( stack: &mut Stack, call: &Call, ) -> Result { - 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(); diff --git a/crates/nu-command/src/filesystem/save.rs b/crates/nu-command/src/filesystem/save.rs index be87b9b68d3f..555aa0f5bd68 100644 --- a/crates/nu-command/src/filesystem/save.rs +++ b/crates/nu-command/src/filesystem/save.rs @@ -63,10 +63,10 @@ impl Command for Save { call: &Call, input: PipelineData, ) -> Result { - 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), .. diff --git a/crates/nu-command/src/filesystem/touch.rs b/crates/nu-command/src/filesystem/touch.rs index 6411cac6031e..4a13f66c036d 100644 --- a/crates/nu-command/src/filesystem/touch.rs +++ b/crates/nu-command/src/filesystem/touch.rs @@ -67,10 +67,10 @@ impl Command for Touch { call: &Call, _input: PipelineData, ) -> Result { - 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 = call.rest(engine_state, stack, 1)?; diff --git a/crates/nu-command/src/filesystem/ucp.rs b/crates/nu-command/src/filesystem/ucp.rs index 4791db05418c..76481de0c39a 100644 --- a/crates/nu-command/src/filesystem/ucp.rs +++ b/crates/nu-command/src/filesystem/ucp.rs @@ -96,19 +96,19 @@ impl Command for UCp { call: &Call, _input: PipelineData, ) -> Result { - 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 { diff --git a/crates/nu-command/src/filesystem/umkdir.rs b/crates/nu-command/src/filesystem/umkdir.rs index 340ca35c8068..58e1a579b6d9 100644 --- a/crates/nu-command/src/filesystem/umkdir.rs +++ b/crates/nu-command/src/filesystem/umkdir.rs @@ -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 { diff --git a/crates/nu-command/src/filesystem/watch.rs b/crates/nu-command/src/filesystem/watch.rs index 5cb7565d2b9f..c5b36c72f258 100644 --- a/crates/nu-command/src/filesystem/watch.rs +++ b/crates/nu-command/src/filesystem/watch.rs @@ -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> = call.get_flag(engine_state, stack, "debounce-ms")?; diff --git a/crates/nu-command/src/filters/compact.rs b/crates/nu-command/src/filters/compact.rs index 5134a01e5b01..568e22696310 100644 --- a/crates/nu-command/src/filters/compact.rs +++ b/crates/nu-command/src/filters/compact.rs @@ -51,7 +51,7 @@ impl Command for Compact { call: &Call, input: PipelineData, ) -> Result { - let empty = call.has_flag("empty"); + let empty = call.has_flag(engine_state, stack, "empty")?; compact(engine_state, stack, call, input, empty) } diff --git a/crates/nu-command/src/filters/each.rs b/crates/nu-command/src/filters/each.rs index 3d7743821353..eb0767a5a9dd 100644 --- a/crates/nu-command/src/filters/each.rs +++ b/crates/nu-command/src/filters/each.rs @@ -114,7 +114,7 @@ with 'transpose' first."# ) -> Result { 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(); diff --git a/crates/nu-command/src/filters/every.rs b/crates/nu-command/src/filters/every.rs index edd8dc4a010a..4e4d18386793 100644 --- a/crates/nu-command/src/filters/every.rs +++ b/crates/nu-command/src/filters/every.rs @@ -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(); diff --git a/crates/nu-command/src/filters/find.rs b/crates/nu-command/src/filters/find.rs index afc52b9f401a..d7851574678d 100644 --- a/crates/nu-command/src/filters/find.rs +++ b/crates/nu-command/src/filters/find.rs @@ -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 { @@ -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::(&engine_state, stack, 0)?; let lower_terms = terms .iter() diff --git a/crates/nu-command/src/filters/flatten.rs b/crates/nu-command/src/filters/flatten.rs index 3b4fd4292c75..76bad8e5a47a 100644 --- a/crates/nu-command/src/filters/flatten.rs +++ b/crates/nu-command/src/filters/flatten.rs @@ -128,7 +128,7 @@ fn flatten( ) -> Result { let columns: Vec = 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( diff --git a/crates/nu-command/src/filters/get.rs b/crates/nu-command/src/filters/get.rs index 6f6e9433ae60..1748b4cd4337 100644 --- a/crates/nu-command/src/filters/get.rs +++ b/crates/nu-command/src/filters/get.rs @@ -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 = 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(); diff --git a/crates/nu-command/src/filters/group_by.rs b/crates/nu-command/src/filters/group_by.rs index 1ed84543d18b..a53ab925cda8 100644 --- a/crates/nu-command/src/filters/group_by.rs +++ b/crates/nu-command/src/filters/group_by.rs @@ -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) diff --git a/crates/nu-command/src/filters/join.rs b/crates/nu-command/src/filters/join.rs index 31af11f5515a..471f50595dac 100644 --- a/crates/nu-command/src/filters/join.rs +++ b/crates/nu-command/src/filters/join.rs @@ -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 { +fn join_type( + engine_state: &EngineState, + stack: &mut Stack, + call: &Call, +) -> Result { 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), diff --git a/crates/nu-command/src/filters/lines.rs b/crates/nu-command/src/filters/lines.rs index 19f071f7f691..c0e8dd80b099 100644 --- a/crates/nu-command/src/filters/lines.rs +++ b/crates/nu-command/src/filters/lines.rs @@ -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 { 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 = diff --git a/crates/nu-command/src/filters/par_each.rs b/crates/nu-command/src/filters/par_each.rs index 4b0c5c54d76e..94ec3531f110 100644 --- a/crates/nu-command/src/filters/par_each.rs +++ b/crates/nu-command/src/filters/par_each.rs @@ -121,7 +121,7 @@ impl Command for ParEach { let capture_block: Closure = call.req(engine_state, stack, 0)?; let threads: Option = 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(); diff --git a/crates/nu-command/src/filters/reject.rs b/crates/nu-command/src/filters/reject.rs index 586cff934b25..8b1d11019f5a 100644 --- a/crates/nu-command/src/filters/reject.rs +++ b/crates/nu-command/src/filters/reject.rs @@ -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(); diff --git a/crates/nu-command/src/filters/select.rs b/crates/nu-command/src/filters/select.rs index a056ff22e624..30707051ce9d 100644 --- a/crates/nu-command/src/filters/select.rs +++ b/crates/nu-command/src/filters/select.rs @@ -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(); diff --git a/crates/nu-command/src/filters/sort.rs b/crates/nu-command/src/filters/sort.rs index 412d55e41058..1eb5fdfdc796 100644 --- a/crates/nu-command/src/filters/sort.rs +++ b/crates/nu-command/src/filters/sort.rs @@ -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 { - 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()) } diff --git a/crates/nu-command/src/filters/sort_by.rs b/crates/nu-command/src/filters/sort_by.rs index 379baf17033b..6b8d15e139fd 100644 --- a/crates/nu-command/src/filters/sort_by.rs +++ b/crates/nu-command/src/filters/sort_by.rs @@ -85,9 +85,9 @@ impl Command for SortBy { input: PipelineData, ) -> Result { let columns: Vec = 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(); diff --git a/crates/nu-command/src/filters/transpose.rs b/crates/nu-command/src/filters/transpose.rs index 90d8d93fa849..e407e4e1c494 100644 --- a/crates/nu-command/src/filters/transpose.rs +++ b/crates/nu-command/src/filters/transpose.rs @@ -145,11 +145,11 @@ pub fn transpose( ) -> Result { 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)?, }; diff --git a/crates/nu-command/src/filters/uniq.rs b/crates/nu-command/src/filters/uniq.rs index dcf965a0f56a..cce18954223a 100644 --- a/crates/nu-command/src/filters/uniq.rs +++ b/crates/nu-command/src/filters/uniq.rs @@ -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) -> Ve pub fn uniq( engine_state: &EngineState, - _stack: &mut Stack, + stack: &mut Stack, call: &Call, input: Vec, item_mapper: Box ValueCounter>, @@ -255,10 +256,10 @@ pub fn uniq( ) -> Result { 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() diff --git a/crates/nu-command/src/filters/window.rs b/crates/nu-command/src/filters/window.rs index 9338fc495fe7..ae7f4256c021 100644 --- a/crates/nu-command/src/filters/window.rs +++ b/crates/nu-command/src/filters/window.rs @@ -120,7 +120,7 @@ impl Command for Window { let ctrlc = engine_state.ctrlc.clone(); let metadata = input.metadata(); let stride: Option = 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); diff --git a/crates/nu-command/src/formats/from/csv.rs b/crates/nu-command/src/formats/from/csv.rs index be54fd0e86a1..c509fbbcb33f 100644 --- a/crates/nu-command/src/formats/from/csv.rs +++ b/crates/nu-command/src/formats/from/csv.rs @@ -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 { diff --git a/crates/nu-command/src/formats/from/json.rs b/crates/nu-command/src/formats/from/json.rs index 61488f9d8749..d55fa6c09aa1 100644 --- a/crates/nu-command/src/formats/from/json.rs +++ b/crates/nu-command/src/formats/from/json.rs @@ -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 { @@ -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 = string_input .lines() .filter_map(move |x| { diff --git a/crates/nu-command/src/formats/from/ssv.rs b/crates/nu-command/src/formats/from/ssv.rs index 2ac02d759d8a..2fdb40ee8065 100644 --- a/crates/nu-command/src/formats/from/ssv.rs +++ b/crates/nu-command/src/formats/from/ssv.rs @@ -289,8 +289,8 @@ fn from_ssv( ) -> Result { 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> = call.get_flag(engine_state, stack, "minimum-spaces")?; diff --git a/crates/nu-command/src/formats/from/tsv.rs b/crates/nu-command/src/formats/from/tsv.rs index 280c40a570fe..fb9c0533f400 100644 --- a/crates/nu-command/src/formats/from/tsv.rs +++ b/crates/nu-command/src/formats/from/tsv.rs @@ -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 { diff --git a/crates/nu-command/src/formats/from/xml.rs b/crates/nu-command/src/formats/from/xml.rs index 2907c2e36000..3f598f199113 100644 --- a/crates/nu-command/src/formats/from/xml.rs +++ b/crates/nu-command/src/formats/from/xml.rs @@ -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 { 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, diff --git a/crates/nu-command/src/formats/to/csv.rs b/crates/nu-command/src/formats/to/csv.rs index 05da969ded58..1f58690c79ed 100644 --- a/crates/nu-command/src/formats/to/csv.rs +++ b/crates/nu-command/src/formats/to/csv.rs @@ -67,7 +67,7 @@ impl Command for ToCsv { input: PipelineData, ) -> Result { let head = call.head; - let noheaders = call.has_flag("noheaders"); + let noheaders = call.has_flag(engine_state, stack, "noheaders")?; let separator: Option> = call.get_flag(engine_state, stack, "separator")?; let config = engine_state.get_config(); to_csv(input, noheaders, separator, head, config) diff --git a/crates/nu-command/src/formats/to/json.rs b/crates/nu-command/src/formats/to/json.rs index 096651e88c1f..6e561230e0fa 100644 --- a/crates/nu-command/src/formats/to/json.rs +++ b/crates/nu-command/src/formats/to/json.rs @@ -44,8 +44,8 @@ impl Command for ToJson { call: &Call, input: PipelineData, ) -> Result { - 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 diff --git a/crates/nu-command/src/formats/to/md.rs b/crates/nu-command/src/formats/to/md.rs index 0b69cd195ec4..d8604ac999a0 100644 --- a/crates/nu-command/src/formats/to/md.rs +++ b/crates/nu-command/src/formats/to/md.rs @@ -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 { 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) } diff --git a/crates/nu-command/src/formats/to/nuon.rs b/crates/nu-command/src/formats/to/nuon.rs index 22036a25f023..fb779bbe3e83 100644 --- a/crates/nu-command/src/formats/to/nuon.rs +++ b/crates/nu-command/src/formats/to/nuon.rs @@ -53,20 +53,18 @@ impl Command for ToNuon { call: &Call, input: PipelineData, ) -> Result { - 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 = call.get_flag(engine_state, stack, "tabs")?; + let indent: Option = 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) diff --git a/crates/nu-command/src/formats/to/tsv.rs b/crates/nu-command/src/formats/to/tsv.rs index a424458a806a..39bc2e4c69ea 100644 --- a/crates/nu-command/src/formats/to/tsv.rs +++ b/crates/nu-command/src/formats/to/tsv.rs @@ -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 { 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) } diff --git a/crates/nu-command/src/generators/cal.rs b/crates/nu-command/src/generators/cal.rs index 4af2dd0a46a0..08c1afd1d82b 100644 --- a/crates/nu-command/src/generators/cal.rs +++ b/crates/nu-command/src/generators/cal.rs @@ -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")?, }; diff --git a/crates/nu-command/src/generators/seq_date.rs b/crates/nu-command/src/generators/seq_date.rs index 518cda52875d..9b4f393723b6 100644 --- a/crates/nu-command/src/generators/seq_date.rs +++ b/crates/nu-command/src/generators/seq_date.rs @@ -129,7 +129,7 @@ impl Command for SeqDate { let end_date: Option> = call.get_flag(engine_state, stack, "end-date")?; let increment: Option> = call.get_flag(engine_state, stack, "increment")?; let days: Option> = 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)), diff --git a/crates/nu-command/src/hash/generic_digest.rs b/crates/nu-command/src/hash/generic_digest.rs index b51104cd569a..7d9c32ea5e53 100644 --- a/crates/nu-command/src/hash/generic_digest.rs +++ b/crates/nu-command/src/hash/generic_digest.rs @@ -87,7 +87,7 @@ where call: &Call, input: PipelineData, ) -> Result { - let binary = call.has_flag("binary"); + let binary = call.has_flag(engine_state, stack, "binary")?; let cell_paths: Vec = call.rest(engine_state, stack, 0)?; let cell_paths = (!cell_paths.is_empty()).then_some(cell_paths); let args = Arguments { binary, cell_paths }; diff --git a/crates/nu-command/src/math/stddev.rs b/crates/nu-command/src/math/stddev.rs index 0350a89334e2..8dffdbf1806f 100644 --- a/crates/nu-command/src/math/stddev.rs +++ b/crates/nu-command/src/math/stddev.rs @@ -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 { - let sample = call.has_flag("sample"); + let sample = call.has_flag(engine_state, stack, "sample")?; run_with_function(call, input, compute_stddev(sample)) } diff --git a/crates/nu-command/src/math/variance.rs b/crates/nu-command/src/math/variance.rs index 09b13934e98c..88f9d8afade0 100644 --- a/crates/nu-command/src/math/variance.rs +++ b/crates/nu-command/src/math/variance.rs @@ -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 { - let sample = call.has_flag("sample"); + let sample = call.has_flag(engine_state, stack, "sample")?; run_with_function(call, input, compute_variance(sample)) } diff --git a/crates/nu-command/src/network/http/delete.rs b/crates/nu-command/src/network/http/delete.rs index 2724ad7e3f59..7a31c7c43267 100644 --- a/crates/nu-command/src/network/http/delete.rs +++ b/crates/nu-command/src/network/http/delete.rs @@ -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")?, }; diff --git a/crates/nu-command/src/network/http/get.rs b/crates/nu-command/src/network/http/get.rs index 7666551f51ab..72dfb05db870 100644 --- a/crates/nu-command/src/network/http/get.rs +++ b/crates/nu-command/src/network/http/get.rs @@ -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) diff --git a/crates/nu-command/src/network/http/head.rs b/crates/nu-command/src/network/http/head.rs index 9d39778be51c..2a097dab33ba 100644 --- a/crates/nu-command/src/network/http/head.rs +++ b/crates/nu-command/src/network/http/head.rs @@ -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")?, diff --git a/crates/nu-command/src/network/http/options.rs b/crates/nu-command/src/network/http/options.rs index 1681c75ef648..2b456d2bb9c1 100644 --- a/crates/nu-command/src/network/http/options.rs +++ b/crates/nu-command/src/network/http/options.rs @@ -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) } diff --git a/crates/nu-command/src/network/http/patch.rs b/crates/nu-command/src/network/http/patch.rs index 29a5c7ce2582..fd8cbd3cea33 100644 --- a/crates/nu-command/src/network/http/patch.rs +++ b/crates/nu-command/src/network/http/patch.rs @@ -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")?, }; diff --git a/crates/nu-command/src/network/http/post.rs b/crates/nu-command/src/network/http/post.rs index f05297e6422e..aac53f8d27a2 100644 --- a/crates/nu-command/src/network/http/post.rs +++ b/crates/nu-command/src/network/http/post.rs @@ -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")?, }; diff --git a/crates/nu-command/src/network/http/put.rs b/crates/nu-command/src/network/http/put.rs index 9eaf7161c84c..58f04ba16986 100644 --- a/crates/nu-command/src/network/http/put.rs +++ b/crates/nu-command/src/network/http/put.rs @@ -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")?, }; diff --git a/crates/nu-command/src/network/url/encode.rs b/crates/nu-command/src/network/url/encode.rs index 24e1a6e9b570..82cd4fa3e2ae 100644 --- a/crates/nu-command/src/network/url/encode.rs +++ b/crates/nu-command/src/network/url/encode.rs @@ -53,7 +53,7 @@ impl Command for SubCommand { ) -> Result { let cell_paths: Vec = 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, diff --git a/crates/nu-command/src/path/expand.rs b/crates/nu-command/src/path/expand.rs index bcd84e573de3..d2c1b7f6cc8e 100644 --- a/crates/nu-command/src/path/expand.rs +++ b/crates/nu-command/src/path/expand.rs @@ -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 { 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 { 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) { diff --git a/crates/nu-command/src/platform/ansi/ansi_.rs b/crates/nu-command/src/platform/ansi/ansi_.rs index bc4be39d6bc7..ad5a4810a6bc 100644 --- a/crates/nu-command/src/platform/ansi/ansi_.rs +++ b/crates/nu-command/src/platform/ansi/ansi_.rs @@ -653,9 +653,9 @@ Operating system commands: call: &Call, _input: PipelineData, ) -> Result { - 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 { diff --git a/crates/nu-command/src/platform/du.rs b/crates/nu-command/src/platform/du.rs index f51b850b2a7f..7c349ac20241 100644 --- a/crates/nu-command/src/platform/du.rs +++ b/crates/nu-command/src/platform/du.rs @@ -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, diff --git a/crates/nu-command/src/platform/input/input_.rs b/crates/nu-command/src/platform/input/input_.rs index 766730c71c3b..50be5fad7e93 100644 --- a/crates/nu-command/src/platform/input/input_.rs +++ b/crates/nu-command/src/platform/input/input_.rs @@ -65,7 +65,7 @@ impl Command for Input { ) -> Result { let prompt: Option = call.opt(engine_state, stack, 0)?; let bytes_until: Option = 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> = call.get_flag(engine_state, stack, "numchar")?; let numchar: Spanned = numchar.unwrap_or(Spanned { item: i64::MAX, diff --git a/crates/nu-command/src/platform/input/input_listen.rs b/crates/nu-command/src/platform/input/input_listen.rs index 1ca68bf7af7b..77f9d4fd73e7 100644 --- a/crates/nu-command/src/platform/input/input_listen.rs +++ b/crates/nu-command/src/platform/input/input_listen.rs @@ -85,7 +85,7 @@ There are 4 `key_type` variants: ) -> Result { 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()?; diff --git a/crates/nu-command/src/platform/input/list.rs b/crates/nu-command/src/platform/input/list.rs index 9ae3f7d5673b..27da987eef48 100644 --- a/crates/nu-command/src/platform/input/list.rs +++ b/crates/nu-command/src/platform/input/list.rs @@ -78,6 +78,8 @@ impl Command for InputList { ) -> Result { let head = call.head; let prompt: Option = 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 = 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( diff --git a/crates/nu-command/src/platform/is_terminal.rs b/crates/nu-command/src/platform/is_terminal.rs index baf7484ea417..bdaf7c2cf815 100644 --- a/crates/nu-command/src/platform/is_terminal.rs +++ b/crates/nu-command/src/platform/is_terminal.rs @@ -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 { - 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(), diff --git a/crates/nu-command/src/platform/kill.rs b/crates/nu-command/src/platform/kill.rs index 3ca9a0530394..23d491f2ff57 100644 --- a/crates/nu-command/src/platform/kill.rs +++ b/crates/nu-command/src/platform/kill.rs @@ -58,9 +58,9 @@ impl Command for Kill { ) -> Result { let pid: i64 = call.req(engine_state, stack, 0)?; let rest: Vec = 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> = 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"); diff --git a/crates/nu-command/src/platform/ulimit.rs b/crates/nu-command/src/platform/ulimit.rs index 41ab3745235e..15cc31c16bbb 100644 --- a/crates/nu-command/src/platform/ulimit.rs +++ b/crates/nu-command/src/platform/ulimit.rs @@ -267,12 +267,17 @@ fn limit_to_value(limit: rlim_t, multiplier: rlim_t, span: Span) -> Result usize { +fn max_desc_len( + call: &Call, + engine_state: &EngineState, + stack: &mut Stack, + print_all: bool, +) -> Result { 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 { 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 { - 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) } } diff --git a/crates/nu-command/src/strings/char_.rs b/crates/nu-command/src/strings/char_.rs index 09e950ec1139..e8913e29e705 100644 --- a/crates/nu-command/src/strings/char_.rs +++ b/crates/nu-command/src/strings/char_.rs @@ -229,7 +229,7 @@ impl Command for Char { ) -> Result { 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 = 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 = call.rest(engine_state, stack, 0)?; if args.is_empty() { return Err(ShellError::MissingParameter { diff --git a/crates/nu-command/src/strings/detect_columns.rs b/crates/nu-command/src/strings/detect_columns.rs index 94d1a50f9e6b..55fc244869a8 100644 --- a/crates/nu-command/src/strings/detect_columns.rs +++ b/crates/nu-command/src/strings/detect_columns.rs @@ -103,7 +103,7 @@ fn detect_columns( ) -> Result { let name_span = call.head; let num_rows_to_skip: Option = 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 = call.get_flag(engine_state, stack, "combine-columns")?; let ctrlc = engine_state.ctrlc.clone(); let config = engine_state.get_config(); diff --git a/crates/nu-command/src/strings/encode_decode/base64.rs b/crates/nu-command/src/strings/encode_decode/base64.rs index 15a4a960f461..0e9276a4099b 100644 --- a/crates/nu-command/src/strings/encode_decode/base64.rs +++ b/crates/nu-command/src/strings/encode_decode/base64.rs @@ -46,7 +46,7 @@ pub fn operate( let head = call.head; let character_set: Option> = 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 = call.rest(engine_state, stack, 0)?; let cell_paths = (!cell_paths.is_empty()).then_some(cell_paths); diff --git a/crates/nu-command/src/strings/encode_decode/encode.rs b/crates/nu-command/src/strings/encode_decode/encode.rs index 75ba64e5f94b..6e41563339f0 100644 --- a/crates/nu-command/src/strings/encode_decode/encode.rs +++ b/crates/nu-command/src/strings/encode_decode/encode.rs @@ -83,7 +83,7 @@ documentation link at https://docs.rs/encoding_rs/latest/encoding_rs/#statics"# ) -> Result { let head = call.head; let encoding: Spanned = 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()), diff --git a/crates/nu-command/src/strings/format/date.rs b/crates/nu-command/src/strings/format/date.rs index 43ed1c688ef7..7fa09ddd5a29 100644 --- a/crates/nu-command/src/strings/format/date.rs +++ b/crates/nu-command/src/strings/format/date.rs @@ -53,7 +53,7 @@ impl Command for FormatDate { input: PipelineData, ) -> Result { 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, diff --git a/crates/nu-command/src/strings/mod.rs b/crates/nu-command/src/strings/mod.rs index c52d68eb357c..4f9f35878b01 100644 --- a/crates/nu-command/src/strings/mod.rs +++ b/crates/nu-command/src/strings/mod.rs @@ -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 { - let g_flag = call.has_flag("grapheme-clusters"); +pub fn grapheme_flags( + engine_state: &EngineState, + stack: &mut Stack, + call: &Call, +) -> Result { + 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 { // 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 { + 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) +} diff --git a/crates/nu-command/src/strings/parse.rs b/crates/nu-command/src/strings/parse.rs index 8719c5ecb6fa..ceaec0fc2bce 100644 --- a/crates/nu-command/src/strings/parse.rs +++ b/crates/nu-command/src/strings/parse.rs @@ -122,7 +122,7 @@ fn operate( ) -> Result { let head = call.head; let pattern: Spanned = 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; diff --git a/crates/nu-command/src/strings/split/chars.rs b/crates/nu-command/src/strings/split/chars.rs index e8948b3ae0d6..76096cca14c1 100644 --- a/crates/nu-command/src/strings/split/chars.rs +++ b/crates/nu-command/src/strings/split/chars.rs @@ -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 { - 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 { 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(), diff --git a/crates/nu-command/src/strings/split/column.rs b/crates/nu-command/src/strings/split/column.rs index db8cd05b2bfc..ec6ca887d2b9 100644 --- a/crates/nu-command/src/strings/split/column.rs +++ b/crates/nu-command/src/strings/split/column.rs @@ -119,9 +119,9 @@ fn split_column( let name_span = call.head; let separator: Spanned = call.req(engine_state, stack, 0)?; let rest: Vec> = 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); diff --git a/crates/nu-command/src/strings/split/list.rs b/crates/nu-command/src/strings/split/list.rs index 195bcb30766c..1065ca9ed614 100644 --- a/crates/nu-command/src/strings/split/list.rs +++ b/crates/nu-command/src/strings/split/list.rs @@ -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() { diff --git a/crates/nu-command/src/strings/split/row.rs b/crates/nu-command/src/strings/split/row.rs index 10ff8326d6ce..298e283cf4d5 100644 --- a/crates/nu-command/src/strings/split/row.rs +++ b/crates/nu-command/src/strings/split/row.rs @@ -123,7 +123,7 @@ fn split_row( ) -> Result { let name_span = call.head; let separator: Spanned = 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); diff --git a/crates/nu-command/src/strings/split/words.rs b/crates/nu-command/src/strings/split/words.rs index a566849c84b9..f3f200116cc5 100644 --- a/crates/nu-command/src/strings/split/words.rs +++ b/crates/nu-command/src/strings/split/words.rs @@ -118,26 +118,26 @@ fn split_words( input: PipelineData, ) -> Result { 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 = 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), diff --git a/crates/nu-command/src/strings/str_/contains.rs b/crates/nu-command/src/strings/str_/contains.rs index 7cb296127bc8..4e56a035be07 100644 --- a/crates/nu-command/src/strings/str_/contains.rs +++ b/crates/nu-command/src/strings/str_/contains.rs @@ -70,8 +70,8 @@ impl Command for SubCommand { let args = Arguments { substring: call.req::(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()) } diff --git a/crates/nu-command/src/strings/str_/ends_with.rs b/crates/nu-command/src/strings/str_/ends_with.rs index 92cffa267ae9..0ea1148141c8 100644 --- a/crates/nu-command/src/strings/str_/ends_with.rs +++ b/crates/nu-command/src/strings/str_/ends_with.rs @@ -66,7 +66,7 @@ impl Command for SubCommand { let args = Arguments { substring: call.req::(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()) } diff --git a/crates/nu-command/src/strings/str_/expand.rs b/crates/nu-command/src/strings/str_/expand.rs index 54377c7c1870..b35039d7426e 100644 --- a/crates/nu-command/src/strings/str_/expand.rs +++ b/crates/nu-command/src/strings/str_/expand.rs @@ -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 { @@ -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(); diff --git a/crates/nu-command/src/strings/str_/index_of.rs b/crates/nu-command/src/strings/str_/index_of.rs index 04d8e36a8ffa..604c1c6b8ad2 100644 --- a/crates/nu-command/src/strings/str_/index_of.rs +++ b/crates/nu-command/src/strings/str_/index_of.rs @@ -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()) } diff --git a/crates/nu-command/src/strings/str_/length.rs b/crates/nu-command/src/strings/str_/length.rs index 83db704ca824..8dccf79410bd 100644 --- a/crates/nu-command/src/strings/str_/length.rs +++ b/crates/nu-command/src/strings/str_/length.rs @@ -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 { let cell_paths: Vec = 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 { let cell_paths: Vec = 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 { @@ -116,10 +129,11 @@ fn run( engine_state: &EngineState, call: &Call, input: PipelineData, + graphemes: bool, ) -> Result { 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()) } diff --git a/crates/nu-command/src/strings/str_/replace.rs b/crates/nu-command/src/strings/str_/replace.rs index 26f06d2830cc..fa617eea9b98 100644 --- a/crates/nu-command/src/strings/str_/replace.rs +++ b/crates/nu-command/src/strings/str_/replace.rs @@ -90,12 +90,13 @@ impl Command for SubCommand { let replace: Spanned = call.req(engine_state, stack, 1)?; let cell_paths: Vec = 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, diff --git a/crates/nu-command/src/strings/str_/starts_with.rs b/crates/nu-command/src/strings/str_/starts_with.rs index c3bfdd7ae9c1..9b0ef9701c04 100644 --- a/crates/nu-command/src/strings/str_/starts_with.rs +++ b/crates/nu-command/src/strings/str_/starts_with.rs @@ -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()) } diff --git a/crates/nu-command/src/strings/str_/substring.rs b/crates/nu-command/src/strings/str_/substring.rs index c5de0cafb9c1..cdff05190f37 100644 --- a/crates/nu-command/src/strings/str_/substring.rs +++ b/crates/nu-command/src/strings/str_/substring.rs @@ -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()) } diff --git a/crates/nu-command/src/strings/str_/trim/trim_.rs b/crates/nu-command/src/strings/str_/trim/trim_.rs index f6ce8a369d72..e23c29d0194f 100644 --- a/crates/nu-command/src/strings/str_/trim/trim_.rs +++ b/crates/nu-command/src/strings/str_/trim/trim_.rs @@ -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, diff --git a/crates/nu-command/src/system/nu_check.rs b/crates/nu-command/src/system/nu_check.rs index b09bae528b34..822f0c53fac2 100644 --- a/crates/nu-command/src/system/nu_check.rs +++ b/crates/nu-command/src/system/nu_check.rs @@ -43,9 +43,9 @@ impl Command for NuCheck { input: PipelineData, ) -> Result { let path: Option> = 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![]; diff --git a/crates/nu-command/src/system/ps.rs b/crates/nu-command/src/system/ps.rs index ab358b40780a..58dccec6ed9b 100644 --- a/crates/nu-command/src/system/ps.rs +++ b/crates/nu-command/src/system/ps.rs @@ -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 { - run_ps(engine_state, call) + run_ps(engine_state, stack, call) } fn examples(&self) -> Vec { @@ -92,10 +93,14 @@ impl Command for Ps { } } -fn run_ps(engine_state: &EngineState, call: &Call) -> Result { +fn run_ps( + engine_state: &EngineState, + stack: &mut Stack, + call: &Call, +) -> Result { 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(); diff --git a/crates/nu-command/src/system/registry_query.rs b/crates/nu-command/src/system/registry_query.rs index 13ccd7935579..63534e9c2b02 100644 --- a/crates/nu-command/src/system/registry_query.rs +++ b/crates/nu-command/src/system/registry_query.rs @@ -88,13 +88,13 @@ fn registry_query( ) -> Result { 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 = call.req(engine_state, stack, 0)?; let registry_key_span = ®istry_key.clone().span; let registry_value: Option> = 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 { - let flags: Vec<_> = [ +fn get_reg_hive( + engine_state: &EngineState, + stack: &mut Stack, + call: &Call, +) -> Result { + 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::, ShellError>>()?; if flags.len() > 1 { return Err(ShellError::GenericError { error: "Only one registry key can be specified".into(), diff --git a/crates/nu-command/src/system/run_external.rs b/crates/nu-command/src/system/run_external.rs index 90b9b85d837c..7f56efc48769 100644 --- a/crates/nu-command/src/system/run_external.rs +++ b/crates/nu-command/src/system/run_external.rs @@ -60,10 +60,10 @@ impl Command for External { call: &Call, input: PipelineData, ) -> Result { - 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 { diff --git a/crates/nu-command/src/system/which_.rs b/crates/nu-command/src/system/which_.rs index 83887208bff9..4d4fdcd32bb6 100644 --- a/crates/nu-command/src/system/which_.rs +++ b/crates/nu-command/src/system/which_.rs @@ -226,7 +226,7 @@ fn which( ) -> Result { let which_args = WhichArgs { applications: call.rest(engine_state, stack, 0)?, - all: call.has_flag("all"), + all: call.has_flag(engine_state, stack, "all")?, }; let ctrlc = engine_state.ctrlc.clone(); diff --git a/crates/nu-command/src/viewers/griddle.rs b/crates/nu-command/src/viewers/griddle.rs index 447eba1976a2..4ab00e89a4c7 100644 --- a/crates/nu-command/src/viewers/griddle.rs +++ b/crates/nu-command/src/viewers/griddle.rs @@ -64,7 +64,7 @@ prints out the list properly."# input: PipelineData, ) -> Result { let width_param: Option = call.get_flag(engine_state, stack, "width")?; - let color_param: bool = call.has_flag("color"); + let color_param: bool = call.has_flag(engine_state, stack, "color")?; let separator_param: Option = call.get_flag(engine_state, stack, "separator")?; let config = engine_state.get_config(); let env_str = match stack.get_env_var(engine_state, "LS_COLORS") { diff --git a/crates/nu-command/src/viewers/table.rs b/crates/nu-command/src/viewers/table.rs index 44fee9aca547..b83d9b079e02 100644 --- a/crates/nu-command/src/viewers/table.rs +++ b/crates/nu-command/src/viewers/table.rs @@ -122,7 +122,7 @@ impl Command for Table { call: &Call, input: PipelineData, ) -> Result { - let list_themes: bool = call.has_flag("list"); + let list_themes: bool = call.has_flag(engine_state, stack, "list")?; // if list argument is present we just need to return a list of supported table themes if list_themes { let val = Value::list(supported_table_modes(), Span::test_data()); @@ -248,10 +248,10 @@ fn parse_table_config( stack: &mut Stack, ) -> Result { let width_param: Option = call.get_flag(state, stack, "width")?; - let expand: bool = call.has_flag("expand"); + let expand: bool = call.has_flag(state, stack, "expand")?; let expand_limit: Option = call.get_flag(state, stack, "expand-deep")?; - let collapse: bool = call.has_flag("collapse"); - let flatten: bool = call.has_flag("flatten"); + let collapse: bool = call.has_flag(state, stack, "collapse")?; + let flatten: bool = call.has_flag(state, stack, "flatten")?; let flatten_separator: Option = call.get_flag(state, stack, "flatten-separator")?; let abbrivation: Option = call .get_flag(state, stack, "abbreviated")? diff --git a/crates/nu-command/tests/commands/ls.rs b/crates/nu-command/tests/commands/ls.rs index e5064f6a15cf..02588dccac81 100644 --- a/crates/nu-command/tests/commands/ls.rs +++ b/crates/nu-command/tests/commands/ls.rs @@ -655,3 +655,47 @@ fn list_unknown_flag() { .err .contains("Available flags: --help(-h), --all(-a),")); } + +#[test] +fn list_flag_false() { + // Check that ls flags respect explicit values + Playground::setup("ls_test_false_flag", |dirs, sandbox| { + sandbox.with_files(vec![ + EmptyFile(".hidden"), + EmptyFile("normal"), + EmptyFile("another_normal"), + ]); + + // TODO Remove this cfg value when we have an OS-agnostic way + // of creating hidden files using the playground. + #[cfg(unix)] + { + let actual = nu!( + cwd: dirs.test(), pipeline( + " + ls --all=false | length + " + )); + + assert_eq!(actual.out, "2"); + } + + let actual = nu!( + cwd: dirs.test(), pipeline( + " + ls --long=false | columns | length + " + )); + + assert_eq!(actual.out, "4"); + + let actual = nu!( + cwd: dirs.test(), pipeline( + " + ls --full-paths=false | get name | any { $in =~ / } + " + )); + + assert_eq!(actual.out, "false"); + }) +} diff --git a/crates/nu-engine/src/call_ext.rs b/crates/nu-engine/src/call_ext.rs index c8d2dc32155e..3e8c77ca0ed8 100644 --- a/crates/nu-engine/src/call_ext.rs +++ b/crates/nu-engine/src/call_ext.rs @@ -1,23 +1,24 @@ use nu_protocol::{ - ast::{Call, Expression}, - engine::{EngineState, Stack, StateWorkingSet}, - eval_const::eval_constant, + ast::Call, + engine::{EngineState, Stack}, FromValue, ShellError, Value, }; use crate::eval_expression; pub trait CallExt { - fn get_flag( + /// Check if a boolean flag is set (i.e. `--bool` or `--bool=true`) + fn has_flag( &self, engine_state: &EngineState, stack: &mut Stack, - name: &str, - ) -> Result, ShellError>; + flag_name: &str, + ) -> Result; - fn get_flag_const( + fn get_flag( &self, - working_set: &StateWorkingSet, + engine_state: &EngineState, + stack: &mut Stack, name: &str, ) -> Result, ShellError>; @@ -28,16 +29,6 @@ pub trait CallExt { starting_pos: usize, ) -> Result, ShellError>; - fn rest_const( - &self, - working_set: &StateWorkingSet, - starting_pos: usize, - ) -> Result, ShellError>; - - fn rest_iter_flattened(&self, start: usize, eval: F) -> Result, ShellError> - where - F: FnMut(&Expression) -> Result; - fn opt( &self, engine_state: &EngineState, @@ -52,12 +43,6 @@ pub trait CallExt { pos: usize, ) -> Result; - fn req_const( - &self, - working_set: &StateWorkingSet, - pos: usize, - ) -> Result; - fn req_parser_info( &self, engine_state: &EngineState, @@ -67,27 +52,43 @@ pub trait CallExt { } impl CallExt for Call { - fn get_flag( + fn has_flag( &self, engine_state: &EngineState, stack: &mut Stack, - name: &str, - ) -> Result, ShellError> { - if let Some(expr) = self.get_flag_expr(name) { - let result = eval_expression(engine_state, stack, expr)?; - FromValue::from_value(result).map(Some) - } else { - Ok(None) + flag_name: &str, + ) -> Result { + for name in self.named_iter() { + if flag_name == name.0.item { + return if let Some(expr) = &name.2 { + // Check --flag=false + let result = eval_expression(engine_state, stack, expr)?; + match result { + Value::Bool { val, .. } => Ok(val), + _ => Err(ShellError::CantConvert { + to_type: "bool".into(), + from_type: result.get_type().to_string(), + span: result.span(), + help: Some("".into()), + }), + } + } else { + Ok(true) + }; + } } + + Ok(false) } - fn get_flag_const( + fn get_flag( &self, - working_set: &StateWorkingSet, + engine_state: &EngineState, + stack: &mut Stack, name: &str, ) -> Result, ShellError> { if let Some(expr) = self.get_flag_expr(name) { - let result = eval_constant(working_set, expr)?; + let result = eval_expression(engine_state, stack, expr)?; FromValue::from_value(result).map(Some) } else { Ok(None) @@ -111,43 +112,6 @@ impl CallExt for Call { Ok(output) } - fn rest_const( - &self, - working_set: &StateWorkingSet, - starting_pos: usize, - ) -> Result, ShellError> { - let mut output = vec![]; - - for result in - self.rest_iter_flattened(starting_pos, |expr| eval_constant(working_set, expr))? - { - output.push(FromValue::from_value(result)?); - } - - Ok(output) - } - - fn rest_iter_flattened(&self, start: usize, mut eval: F) -> Result, ShellError> - where - F: FnMut(&Expression) -> Result, - { - let mut output = Vec::new(); - - for (expr, spread) in self.rest_iter(start) { - let result = eval(expr)?; - if spread { - match result { - Value::List { mut vals, .. } => output.append(&mut vals), - _ => return Err(ShellError::CannotSpreadAsList { span: expr.span }), - } - } else { - output.push(result); - } - } - - Ok(output) - } - fn opt( &self, engine_state: &EngineState, @@ -181,24 +145,6 @@ impl CallExt for Call { } } - fn req_const( - &self, - working_set: &StateWorkingSet, - pos: usize, - ) -> Result { - if let Some(expr) = self.positional_nth(pos) { - let result = eval_constant(working_set, expr)?; - FromValue::from_value(result) - } else if self.positional_len() == 0 { - Err(ShellError::AccessEmptyContent { span: self.head }) - } else { - Err(ShellError::AccessBeyondEnd { - max_idx: self.positional_len() - 1, - span: self.head, - }) - } - } - fn req_parser_info( &self, engine_state: &EngineState, diff --git a/crates/nu-engine/src/eval.rs b/crates/nu-engine/src/eval.rs index adfc2a795ae6..b405e3ed31b7 100644 --- a/crates/nu-engine/src/eval.rs +++ b/crates/nu-engine/src/eval.rs @@ -1,4 +1,4 @@ -use crate::{call_ext::CallExt, current_dir_str, get_full_help}; +use crate::{current_dir_str, get_full_help}; use nu_path::expand_path_with; use nu_protocol::{ ast::{ diff --git a/crates/nu-explore/src/explore.rs b/crates/nu-explore/src/explore.rs index ade3ee42e7d6..0e3331b86e3b 100644 --- a/crates/nu-explore/src/explore.rs +++ b/crates/nu-explore/src/explore.rs @@ -64,9 +64,9 @@ impl Command for Explore { input: PipelineData, ) -> Result { let show_head: bool = call.get_flag(engine_state, stack, "head")?.unwrap_or(true); - let show_index: bool = call.has_flag("index"); - let is_reverse: bool = call.has_flag("reverse"); - let peek_value: bool = call.has_flag("peek"); + let show_index: bool = call.has_flag(engine_state, stack, "index")?; + let is_reverse: bool = call.has_flag(engine_state, stack, "reverse")?; + let peek_value: bool = call.has_flag(engine_state, stack, "peek")?; let ctrlc = engine_state.ctrlc.clone(); let nu_config = engine_state.get_config(); diff --git a/crates/nu-parser/src/parse_keywords.rs b/crates/nu-parser/src/parse_keywords.rs index 1c7eee261ac4..657b667a15c1 100644 --- a/crates/nu-parser/src/parse_keywords.rs +++ b/crates/nu-parser/src/parse_keywords.rs @@ -280,7 +280,12 @@ pub fn parse_for(working_set: &mut StateWorkingSet, spans: &[Span]) -> Expressio let starting_error_count = working_set.parse_errors.len(); check_call(working_set, call_span, &sig, &call); - if starting_error_count != working_set.parse_errors.len() || call.has_flag("help") { + + let Ok(is_help) = has_flag_wrapped(working_set, &call, "help") else { + return garbage(spans[0]); + }; + + if starting_error_count != working_set.parse_errors.len() || is_help { return Expression { expr: Expr::Call(call), span: call_span, @@ -464,7 +469,12 @@ pub fn parse_def( let starting_error_count = working_set.parse_errors.len(); check_call(working_set, call_span, &sig, &call); working_set.parse_errors.append(&mut new_errors); - if starting_error_count != working_set.parse_errors.len() || call.has_flag("help") { + + let Ok(is_help) = has_flag_wrapped(working_set, &call, "help") else { + return (garbage_pipeline(spans), None); + }; + + if starting_error_count != working_set.parse_errors.len() || is_help { return ( Pipeline::from_vec(vec![Expression { expr: Expr::Call(call), @@ -480,8 +490,12 @@ pub fn parse_def( } }; - let has_env = call.has_flag("env"); - let has_wrapped = call.has_flag("wrapped"); + let Ok(has_env) = has_flag_wrapped(working_set, &call, "env") else { + return (garbage_pipeline(spans), None); + }; + let Ok(has_wrapped) = has_flag_wrapped(working_set, &call, "wrapped") else { + return (garbage_pipeline(spans), None); + }; // All positional arguments must be in the call positional vector by this point let name_expr = call.positional_nth(0).expect("def call already checked"); @@ -870,7 +884,9 @@ pub fn parse_alias( .parse_errors .truncate(original_starting_error_count); - let has_help_flag = alias_call.has_flag("help"); + let Ok(has_help_flag) = has_flag_wrapped(working_set, &alias_call, "help") else { + return garbage_pipeline(spans); + }; let alias_pipeline = Pipeline::from_vec(vec![Expression { expr: Expr::Call(alias_call.clone()), @@ -1122,7 +1138,12 @@ pub fn parse_export_in_block( let starting_error_count = working_set.parse_errors.len(); check_call(working_set, call_span, &decl.signature(), &call); - if starting_error_count != working_set.parse_errors.len() || call.has_flag("help") { + + let Ok(is_help) = has_flag_wrapped(working_set, &call, "help") else { + return garbage_pipeline(&lite_command.parts); + }; + + if starting_error_count != working_set.parse_errors.len() || is_help { return Pipeline::from_vec(vec![Expression { expr: Expr::Call(call), span: call_span, @@ -1606,7 +1627,12 @@ pub fn parse_export_env( let starting_error_count = working_set.parse_errors.len(); check_call(working_set, call_span, &decl.signature(), &call); - if starting_error_count != working_set.parse_errors.len() || call.has_flag("help") { + + let Ok(is_help) = has_flag_wrapped(working_set, &call, "help") else { + return (garbage_pipeline(spans), None); + }; + + if starting_error_count != working_set.parse_errors.len() || is_help { return ( Pipeline::from_vec(vec![Expression { expr: Expr::Call(call), @@ -2092,7 +2118,12 @@ pub fn parse_module( let starting_error_count = working_set.parse_errors.len(); check_call(working_set, call_span, &decl.signature(), &call); - if starting_error_count != working_set.parse_errors.len() || call.has_flag("help") { + + let Ok(is_help) = has_flag_wrapped(working_set, &call, "help") else { + return (garbage_pipeline(spans), None); + }; + + if starting_error_count != working_set.parse_errors.len() || is_help { return ( Pipeline::from_vec(vec![Expression { expr: Expr::Call(call), @@ -2284,7 +2315,12 @@ pub fn parse_use(working_set: &mut StateWorkingSet, spans: &[Span]) -> (Pipeline let starting_error_count = working_set.parse_errors.len(); check_call(working_set, call_span, &decl.signature(), &call); - if starting_error_count != working_set.parse_errors.len() || call.has_flag("help") { + + let Ok(is_help) = has_flag_wrapped(working_set, &call, "help") else { + return (garbage_pipeline(spans), vec![]); + }; + + if starting_error_count != working_set.parse_errors.len() || is_help { return ( Pipeline::from_vec(vec![Expression { expr: Expr::Call(call), @@ -2466,7 +2502,12 @@ pub fn parse_hide(working_set: &mut StateWorkingSet, spans: &[Span]) -> Pipeline let starting_error_count = working_set.parse_errors.len(); check_call(working_set, call_span, &decl.signature(), &call); - if starting_error_count != working_set.parse_errors.len() || call.has_flag("help") { + + let Ok(is_help) = has_flag_wrapped(working_set, &call, "help") else { + return garbage_pipeline(spans); + }; + + if starting_error_count != working_set.parse_errors.len() || is_help { return Pipeline::from_vec(vec![Expression { expr: Expr::Call(call), span: call_span, @@ -2724,8 +2765,12 @@ pub fn parse_overlay_use(working_set: &mut StateWorkingSet, call: Box) -> None }; - let has_prefix = call.has_flag("prefix"); - let do_reload = call.has_flag("reload"); + let Ok(has_prefix) = has_flag_wrapped(working_set, &call, "prefix") else { + return garbage_pipeline(&[call_span]); + }; + let Ok(do_reload) = has_flag_wrapped(working_set, &call, "reload") else { + return garbage_pipeline(&[call_span]); + }; let pipeline = Pipeline::from_vec(vec![Expression { expr: Expr::Call(call.clone()), @@ -2911,7 +2956,9 @@ pub fn parse_overlay_hide(working_set: &mut StateWorkingSet, call: Box) -> ) }; - let keep_custom = call.has_flag("keep-custom"); + let Ok(keep_custom) = has_flag_wrapped(working_set, &call, "keep-custom") else { + return garbage_pipeline(&[call_span]); + }; let pipeline = Pipeline::from_vec(vec![Expression { expr: Expr::Call(call), @@ -3327,7 +3374,11 @@ pub fn parse_source(working_set: &mut StateWorkingSet, spans: &[Span]) -> Pipeli let ParsedInternalCall { call, output } = parse_internal_call(working_set, spans[0], &spans[1..], decl_id); - if call.has_flag("help") { + let Ok(is_help) = has_flag_wrapped(working_set, &call, "help") else { + return garbage_pipeline(spans); + }; + + if is_help { return Pipeline::from_vec(vec![Expression { expr: Expr::Call(call), span: span(spans), @@ -3460,7 +3511,12 @@ pub fn parse_where_expr(working_set: &mut StateWorkingSet, spans: &[Span]) -> Ex let starting_error_count = working_set.parse_errors.len(); check_call(working_set, call_span, &decl.signature(), &call); - if starting_error_count != working_set.parse_errors.len() || call.has_flag("help") { + + let Ok(is_help) = has_flag_wrapped(working_set, &call, "help") else { + return garbage(span(spans)); + }; + + if starting_error_count != working_set.parse_errors.len() || is_help { return Expression { expr: Expr::Call(call), span: call_span, @@ -3530,7 +3586,12 @@ pub fn parse_register(working_set: &mut StateWorkingSet, spans: &[Span]) -> Pipe let starting_error_count = working_set.parse_errors.len(); check_call(working_set, call_span, &decl.signature(), &call); - if starting_error_count != working_set.parse_errors.len() || call.has_flag("help") { + + let Ok(is_help) = has_flag_wrapped(working_set, &call, "help") else { + return garbage_pipeline(spans); + }; + + if starting_error_count != working_set.parse_errors.len() || is_help { return Pipeline::from_vec(vec![Expression { expr: Expr::Call(call), span: call_span, @@ -3852,3 +3913,14 @@ fn detect_params_in_name( None } } + +/// Run has_flag_const and and push possible error to working_set +fn has_flag_wrapped( + working_set: &mut StateWorkingSet, + call: &Call, + name: &str, +) -> Result { + call.has_flag_const(working_set, name).map_err(|err| { + working_set.error(err.wrap(working_set, call.span())); + }) +} diff --git a/crates/nu-plugin/src/protocol/evaluated_call.rs b/crates/nu-plugin/src/protocol/evaluated_call.rs index cf968deb8834..52b4c3031f13 100644 --- a/crates/nu-plugin/src/protocol/evaluated_call.rs +++ b/crates/nu-plugin/src/protocol/evaluated_call.rs @@ -1,4 +1,4 @@ -use nu_engine::{eval_expression, CallExt}; +use nu_engine::eval_expression; use nu_protocol::{ ast::Call, engine::{EngineState, Stack}, diff --git a/crates/nu-protocol/src/ast/call.rs b/crates/nu-protocol/src/ast/call.rs index f3f19667a53a..db2250bccf12 100644 --- a/crates/nu-protocol/src/ast/call.rs +++ b/crates/nu-protocol/src/ast/call.rs @@ -3,7 +3,10 @@ use std::collections::HashMap; use serde::{Deserialize, Serialize}; use super::Expression; -use crate::{DeclId, Span, Spanned}; +use crate::{ + engine::StateWorkingSet, eval_const::eval_constant, DeclId, FromValue, ShellError, Span, + Spanned, Value, +}; #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] pub enum Argument { @@ -201,34 +204,126 @@ impl Call { self.parser_info.insert(name, val) } - pub fn has_flag(&self, flag_name: &str) -> bool { + pub fn get_flag_expr(&self, flag_name: &str) -> Option<&Expression> { for name in self.named_iter() { if flag_name == name.0.item { - return true; + return name.2.as_ref(); } } - false + None } - pub fn get_flag_expr(&self, flag_name: &str) -> Option<&Expression> { + pub fn get_named_arg(&self, flag_name: &str) -> Option> { for name in self.named_iter() { if flag_name == name.0.item { - return name.2.as_ref(); + return Some(name.0.clone()); } } None } - pub fn get_named_arg(&self, flag_name: &str) -> Option> { + /// Check if a boolean flag is set (i.e. `--bool` or `--bool=true`) + /// evaluating the expression after = as a constant command + pub fn has_flag_const( + &self, + working_set: &StateWorkingSet, + flag_name: &str, + ) -> Result { for name in self.named_iter() { if flag_name == name.0.item { - return Some(name.0.clone()); + return if let Some(expr) = &name.2 { + // Check --flag=false + let result = eval_constant(working_set, expr)?; + match result { + Value::Bool { val, .. } => Ok(val), + _ => Err(ShellError::CantConvert { + to_type: "bool".into(), + from_type: result.get_type().to_string(), + span: result.span(), + help: Some("".into()), + }), + } + } else { + Ok(true) + }; } } - None + Ok(false) + } + + pub fn get_flag_const( + &self, + working_set: &StateWorkingSet, + name: &str, + ) -> Result, ShellError> { + if let Some(expr) = self.get_flag_expr(name) { + let result = eval_constant(working_set, expr)?; + FromValue::from_value(result).map(Some) + } else { + Ok(None) + } + } + + pub fn rest_const( + &self, + working_set: &StateWorkingSet, + starting_pos: usize, + ) -> Result, ShellError> { + let mut output = vec![]; + + for result in + self.rest_iter_flattened(starting_pos, |expr| eval_constant(working_set, expr))? + { + output.push(FromValue::from_value(result)?); + } + + Ok(output) + } + + pub fn rest_iter_flattened( + &self, + start: usize, + mut eval: F, + ) -> Result, ShellError> + where + F: FnMut(&Expression) -> Result, + { + let mut output = Vec::new(); + + for (expr, spread) in self.rest_iter(start) { + let result = eval(expr)?; + if spread { + match result { + Value::List { mut vals, .. } => output.append(&mut vals), + _ => return Err(ShellError::CannotSpreadAsList { span: expr.span }), + } + } else { + output.push(result); + } + } + + Ok(output) + } + + pub fn req_const( + &self, + working_set: &StateWorkingSet, + pos: usize, + ) -> Result { + if let Some(expr) = self.positional_nth(pos) { + let result = eval_constant(working_set, expr)?; + FromValue::from_value(result) + } else if self.positional_len() == 0 { + Err(ShellError::AccessEmptyContent { span: self.head }) + } else { + Err(ShellError::AccessBeyondEnd { + max_idx: self.positional_len() - 1, + span: self.head, + }) + } } pub fn span(&self) -> Span { diff --git a/src/command.rs b/src/command.rs index 81f44db2e6b8..f94655cd60a4 100644 --- a/src/command.rs +++ b/src/command.rs @@ -108,7 +108,7 @@ pub(crate) fn parse_commandline_args( call.get_flag(engine_state, &mut stack, "table-mode")?; // ide flags - let lsp = call.has_flag("lsp"); + let lsp = call.has_flag(engine_state, &mut stack, "lsp")?; let include_path = call.get_flag_expr("include-path"); let ide_goto_def: Option = call.get_flag(engine_state, &mut stack, "ide-goto-def")?; @@ -150,7 +150,7 @@ pub(crate) fn parse_commandline_args( let execute = extract_contents(execute)?; let include_path = extract_contents(include_path)?; - let help = call.has_flag("help"); + let help = call.has_flag(engine_state, &mut stack, "help")?; if help { let full_help = get_full_help( @@ -166,7 +166,7 @@ pub(crate) fn parse_commandline_args( std::process::exit(0); } - if call.has_flag("version") { + if call.has_flag(engine_state, &mut stack, "version")? { let version = env!("CARGO_PKG_VERSION").to_string(); let _ = std::panic::catch_unwind(move || { stdout_write_all_and_flush(format!("{version}\n"))