From d60eff89d65dbeb147b9b6f59aef42eb563245d7 Mon Sep 17 00:00:00 2001 From: Darren Schroeder <343840+fdncred@users.noreply.github.com> Date: Wed, 25 Mar 2026 18:36:00 -0500 Subject: [PATCH] allow formatting of things like `ls | where type == dir` inside of def --- src/formatting.rs | 59 +++++++++++++++++++++++++---- tests/fixtures/expected/issue101.nu | 3 ++ tests/fixtures/input/issue101.nu | 1 + tests/ground_truth.rs | 1 + 4 files changed, 57 insertions(+), 7 deletions(-) create mode 100644 tests/fixtures/expected/issue101.nu create mode 100644 tests/fixtures/input/issue101.nu diff --git a/src/formatting.rs b/src/formatting.rs index 7fff267..eb45927 100644 --- a/src/formatting.rs +++ b/src/formatting.rs @@ -12,8 +12,8 @@ use nu_protocol::{ MatchPattern, PathMember, Pattern, Pipeline, PipelineElement, PipelineRedirection, RecordItem, RedirectionTarget, }, - engine::{EngineState, StateWorkingSet}, - Completion, Signature, Span, SyntaxShape, + engine::{Call, Command, CommandType as NuCommandType, EngineState, Stack, StateWorkingSet}, + Category, Completion, PipelineData, ShellError, Signature, Span, SyntaxShape, }; use nu_utils::NuCow; @@ -24,9 +24,57 @@ const DEF_COMMANDS: &[&str] = &["def", "def-env", "export def"]; const EXTERN_COMMANDS: &[&str] = &["extern", "export extern"]; const LET_COMMANDS: &[&str] = &["let", "let-env", "mut", "const"]; +#[derive(Clone)] +struct WhereKeyword; + +impl Command for WhereKeyword { + fn name(&self) -> &str { + "where" + } + + fn signature(&self) -> Signature { + Signature::build("where") + .required( + "condition", + SyntaxShape::RowCondition, + "filter row condition or closure", + ) + .category(Category::Filters) + } + + fn description(&self) -> &str { + "filter values of an input list based on a condition" + } + + fn command_type(&self) -> NuCommandType { + NuCommandType::Keyword + } + + fn run( + &self, + _engine_state: &EngineState, + _stack: &mut Stack, + _call: &Call, + input: PipelineData, + ) -> Result { + Ok(input) + } +} + /// Get the default engine state with built-in commands fn get_engine_state() -> EngineState { - nu_cmd_lang::create_default_context() + let mut engine_state = nu_cmd_lang::create_default_context(); + let delta = { + let mut working_set = StateWorkingSet::new(&engine_state); + working_set.add_decl(Box::new(WhereKeyword)); + working_set.render() + }; + + if let Err(err) = engine_state.merge_delta(delta) { + debug!("failed to merge formatter context: {err:?}"); + } + + engine_state } /// The main formatter context that tracks indentation and other state @@ -374,10 +422,7 @@ impl<'a> Formatter<'a> { self.format_full_cell_path(full_path); } - Expr::RowCondition(block_id) => { - let block = self.working_set.get_block(*block_id); - self.format_block(block); - } + Expr::RowCondition(_) => self.write_expr_span(expr), Expr::Keyword(keyword) => { self.write_span(keyword.span); diff --git a/tests/fixtures/expected/issue101.nu b/tests/fixtures/expected/issue101.nu new file mode 100644 index 0000000..c738b4b --- /dev/null +++ b/tests/fixtures/expected/issue101.nu @@ -0,0 +1,3 @@ +def foo [] { + ls | where type == "dir" +} diff --git a/tests/fixtures/input/issue101.nu b/tests/fixtures/input/issue101.nu new file mode 100644 index 0000000..b5a58fb --- /dev/null +++ b/tests/fixtures/input/issue101.nu @@ -0,0 +1 @@ +def foo [] { ls | where type == "dir" } diff --git a/tests/ground_truth.rs b/tests/ground_truth.rs index 360be8b..3fb5b66 100644 --- a/tests/ground_truth.rs +++ b/tests/ground_truth.rs @@ -807,4 +807,5 @@ issue_fixture_tests!( ("issue95", issue95_test, idempotency_issue95_test), ("issue97", issue97_test, idempotency_issue97_test), ("issue100", issue100_test, idempotency_issue100_test), + ("issue101", issue101_test, idempotency_issue101_test), );