diff --git a/crates/nu-cli/src/commands/format.rs b/crates/nu-cli/src/commands/format.rs index d7220cad11..45f29d315e 100644 --- a/crates/nu-cli/src/commands/format.rs +++ b/crates/nu-cli/src/commands/format.rs @@ -1,10 +1,10 @@ use crate::commands::WholeStreamCommand; use crate::context::CommandRegistry; +use crate::evaluate::evaluate_baseline_expr; use crate::prelude::*; use nu_errors::ShellError; -use nu_protocol::{ColumnPath, ReturnSuccess, Signature, SyntaxShape, UntaggedValue, Value}; +use nu_protocol::{ReturnSuccess, Signature, SyntaxShape, UntaggedValue}; use nu_source::Tagged; -use nu_value_ext::{as_column_path, get_data_by_column_path}; use std::borrow::Borrow; pub struct Format; @@ -54,6 +54,7 @@ fn format_command( ) -> Result { let registry = registry.clone(); let stream = async_stream! { + let scope = args.call_info.scope.clone(); let (FormatArgs { pattern }, mut input) = args.process(®istry).await?; let pattern_tag = pattern.tag.clone(); @@ -61,44 +62,32 @@ fn format_command( let commands = format_pattern; while let Some(value) = input.next().await { - match value { - value - @ - Value { - value: UntaggedValue::Row(_), - .. - } => { - let mut output = String::new(); + let scope = scope.clone().set_it(value); + let mut output = String::new(); - for command in &commands { - match command { - FormatCommand::Text(s) => { - output.push_str(&s); - } - FormatCommand::Column(c) => { - let key = to_column_path(&c, &pattern_tag)?; + for command in &commands { + match command { + FormatCommand::Text(s) => { + output.push_str(&s); + } + FormatCommand::Column(c) => { + // FIXME: use the correct spans + let full_column_path = nu_parser::parse_full_column_path(&(c.to_string()).spanned(Span::unknown()), ®istry); - let fetcher = get_data_by_column_path( - &value, - &key, - Box::new(move |(_, _, error)| error), - ); + let result = evaluate_baseline_expr(&full_column_path.0, ®istry, &scope).await; - if let Ok(c) = fetcher { - output - .push_str(&value::format_leaf(c.borrow()).plain_string(100_000)) - } - // That column doesn't match, so don't emit anything - } + if let Ok(c) = result { + output + .push_str(&value::format_leaf(c.borrow()).plain_string(100_000)) + } else { + // That column doesn't match, so don't emit anything } } - - yield ReturnSuccess::value( - UntaggedValue::string(output).into_untagged_value()) } - _ => yield ReturnSuccess::value( - UntaggedValue::string(String::new()).into_untagged_value()), - }; + } + + yield ReturnSuccess::value( + UntaggedValue::string(output).into_untagged_value()) } }; @@ -150,30 +139,6 @@ fn format(input: &str) -> Vec { output } -fn to_column_path( - path_members: &str, - tag: impl Into, -) -> Result, ShellError> { - let tag = tag.into(); - - as_column_path( - &UntaggedValue::Table( - path_members - .split('.') - .map(|x| { - let member = match x.parse::() { - Ok(v) => UntaggedValue::int(v), - Err(_) => UntaggedValue::string(x), - }; - - member.into_value(&tag) - }) - .collect(), - ) - .into_value(&tag), - ) -} - #[cfg(test)] mod tests { use super::Format; diff --git a/crates/nu-cli/src/evaluate/evaluator.rs b/crates/nu-cli/src/evaluate/evaluator.rs index ea4bc22817..e3df8c8b0f 100644 --- a/crates/nu-cli/src/evaluate/evaluator.rs +++ b/crates/nu-cli/src/evaluate/evaluator.rs @@ -192,7 +192,7 @@ async fn evaluate_invocation( let mut context = Context::basic()?; context.registry = registry.clone(); - let input = InputStream::one(scope.it.clone()); + let input = InputStream::empty(); let result = run_block(&block, &mut context, input, &scope.clone()).await?; diff --git a/crates/nu-cli/tests/commands/format.rs b/crates/nu-cli/tests/commands/format.rs index eb44805517..d827781fd8 100644 --- a/crates/nu-cli/tests/commands/format.rs +++ b/crates/nu-cli/tests/commands/format.rs @@ -28,3 +28,17 @@ fn given_fields_can_be_column_paths() { assert_eq!(actual.out, "nu is a new type of shell"); } + +#[test] +fn can_use_variables() { + let actual = nu!( + cwd: "tests/fixtures/formats", pipeline( + r#" + open cargo_sample.toml + | format "{$it.package.name} is {$it.package.description}" + | echo $it + "# + )); + + assert_eq!(actual.out, "nu is a new type of shell"); +} diff --git a/crates/nu-parser/src/lib.rs b/crates/nu-parser/src/lib.rs index cc940c6f66..c6f2f672e8 100644 --- a/crates/nu-parser/src/lib.rs +++ b/crates/nu-parser/src/lib.rs @@ -5,7 +5,7 @@ mod shapes; mod signature; pub use crate::lite_parse::{lite_parse, LiteBlock}; -pub use crate::parse::{classify_block, garbage}; +pub use crate::parse::{classify_block, garbage, parse_full_column_path}; pub use crate::path::expand_ndots; pub use crate::shapes::shapes; pub use crate::signature::{Signature, SignatureRegistry}; diff --git a/crates/nu-parser/src/parse.rs b/crates/nu-parser/src/parse.rs index 45cb38d26b..aeebe937f9 100644 --- a/crates/nu-parser/src/parse.rs +++ b/crates/nu-parser/src/parse.rs @@ -73,7 +73,7 @@ fn parse_simple_column_path(lite_arg: &Spanned) -> (SpannedExpression, O } /// Parses a column path, adding in the preceding reference to $it if it's elided -fn parse_full_column_path( +pub fn parse_full_column_path( lite_arg: &Spanned, registry: &dyn SignatureRegistry, ) -> (SpannedExpression, Option) {