From a911b2125675de4c8b28c7591da008b117af3c53 Mon Sep 17 00:00:00 2001 From: JT <547158+jntrnr@users.noreply.github.com> Date: Sat, 5 Feb 2022 21:03:06 -0500 Subject: [PATCH] Switch more commands to redirecting blocks (#956) --- crates/nu-command/src/core_commands/for_.rs | 18 +++-- crates/nu-command/src/filters/each.rs | 25 +++++-- crates/nu-command/src/filters/each_group.rs | 4 +- crates/nu-command/src/filters/par_each.rs | 39 +++++++++-- crates/nu-command/src/filters/where_.rs | 10 ++- crates/nu-engine/src/eval.rs | 74 +++++++++++++++++++++ crates/nu-engine/src/lib.rs | 3 +- 7 files changed, 151 insertions(+), 22 deletions(-) diff --git a/crates/nu-command/src/core_commands/for_.rs b/crates/nu-command/src/core_commands/for_.rs index 620a374d2..a686f297c 100644 --- a/crates/nu-command/src/core_commands/for_.rs +++ b/crates/nu-command/src/core_commands/for_.rs @@ -1,4 +1,4 @@ -use nu_engine::{eval_block, eval_expression, CallExt}; +use nu_engine::{eval_block_with_redirect, eval_expression, CallExt}; use nu_protocol::ast::Call; use nu_protocol::engine::{CaptureBlock, Command, EngineState, Stack}; use nu_protocol::{ @@ -99,7 +99,12 @@ impl Command for For { ); //let block = engine_state.get_block(block_id); - match eval_block(&engine_state, &mut stack, &block, PipelineData::new(head)) { + match eval_block_with_redirect( + &engine_state, + &mut stack, + &block, + PipelineData::new(head), + ) { Ok(pipeline_data) => pipeline_data.into_value(head), Err(error) => Value::Error { error }, } @@ -131,7 +136,12 @@ impl Command for For { ); //let block = engine_state.get_block(block_id); - match eval_block(&engine_state, &mut stack, &block, PipelineData::new(head)) { + match eval_block_with_redirect( + &engine_state, + &mut stack, + &block, + PipelineData::new(head), + ) { Ok(pipeline_data) => pipeline_data.into_value(head), Err(error) => Value::Error { error }, } @@ -140,7 +150,7 @@ impl Command for For { x => { stack.add_var(var_id, x); - eval_block(&engine_state, &mut stack, &block, PipelineData::new(head)) + eval_block_with_redirect(&engine_state, &mut stack, &block, PipelineData::new(head)) } } } diff --git a/crates/nu-command/src/filters/each.rs b/crates/nu-command/src/filters/each.rs index 35ae1048a..2dbddf66d 100644 --- a/crates/nu-command/src/filters/each.rs +++ b/crates/nu-command/src/filters/each.rs @@ -1,4 +1,4 @@ -use nu_engine::{eval_block, CallExt}; +use nu_engine::{eval_block_with_redirect, CallExt}; use nu_protocol::ast::Call; use nu_protocol::engine::{CaptureBlock, Command, EngineState, Stack}; use nu_protocol::{ @@ -105,7 +105,12 @@ impl Command for Each { } } - match eval_block(&engine_state, &mut stack, &block, PipelineData::new(span)) { + match eval_block_with_redirect( + &engine_state, + &mut stack, + &block, + PipelineData::new(span), + ) { Ok(v) => v.into_value(span), Err(error) => Value::Error { error }, } @@ -145,7 +150,12 @@ impl Command for Each { } } - match eval_block(&engine_state, &mut stack, &block, PipelineData::new(span)) { + match eval_block_with_redirect( + &engine_state, + &mut stack, + &block, + PipelineData::new(span), + ) { Ok(v) => v.into_value(span), Err(error) => Value::Error { error }, } @@ -179,7 +189,12 @@ impl Command for Each { } } - match eval_block(&engine_state, &mut stack, &block, PipelineData::new(span))? { + match eval_block_with_redirect( + &engine_state, + &mut stack, + &block, + PipelineData::new(span), + )? { PipelineData::Value( Value::Record { mut cols, mut vals, .. @@ -213,7 +228,7 @@ impl Command for Each { } } - eval_block(&engine_state, &mut stack, &block, PipelineData::new(span)) + eval_block_with_redirect(&engine_state, &mut stack, &block, PipelineData::new(span)) } } } diff --git a/crates/nu-command/src/filters/each_group.rs b/crates/nu-command/src/filters/each_group.rs index 078088815..17e39a91a 100644 --- a/crates/nu-command/src/filters/each_group.rs +++ b/crates/nu-command/src/filters/each_group.rs @@ -1,4 +1,4 @@ -use nu_engine::{eval_block, CallExt}; +use nu_engine::{eval_block_with_redirect, CallExt}; use nu_protocol::ast::Call; use nu_protocol::engine::{CaptureBlock, Command, EngineState, Stack}; use nu_protocol::{ @@ -142,7 +142,7 @@ pub(crate) fn run_block_on_vec( } } - match eval_block(&engine_state, &mut stack, block, PipelineData::new(span)) { + match eval_block_with_redirect(&engine_state, &mut stack, block, PipelineData::new(span)) { Ok(pipeline) => pipeline, Err(error) => Value::Error { error }.into_pipeline_data(), } diff --git a/crates/nu-command/src/filters/par_each.rs b/crates/nu-command/src/filters/par_each.rs index 4308234e2..9b634d3ac 100644 --- a/crates/nu-command/src/filters/par_each.rs +++ b/crates/nu-command/src/filters/par_each.rs @@ -1,4 +1,4 @@ -use nu_engine::{eval_block, CallExt}; +use nu_engine::{eval_block_with_redirect, CallExt}; use nu_protocol::ast::Call; use nu_protocol::engine::{CaptureBlock, Command, EngineState, Stack}; use nu_protocol::{ @@ -87,7 +87,12 @@ impl Command for ParEach { } } - match eval_block(&engine_state, &mut stack, block, PipelineData::new(span)) { + match eval_block_with_redirect( + &engine_state, + &mut stack, + block, + PipelineData::new(span), + ) { Ok(v) => v, Err(error) => Value::Error { error }.into_pipeline_data(), } @@ -128,7 +133,12 @@ impl Command for ParEach { } } - match eval_block(&engine_state, &mut stack, block, PipelineData::new(span)) { + match eval_block_with_redirect( + &engine_state, + &mut stack, + block, + PipelineData::new(span), + ) { Ok(v) => v, Err(error) => Value::Error { error }.into_pipeline_data(), } @@ -168,7 +178,12 @@ impl Command for ParEach { } } - match eval_block(&engine_state, &mut stack, block, PipelineData::new(span)) { + match eval_block_with_redirect( + &engine_state, + &mut stack, + block, + PipelineData::new(span), + ) { Ok(v) => v, Err(error) => Value::Error { error }.into_pipeline_data(), } @@ -213,7 +228,12 @@ impl Command for ParEach { } } - match eval_block(&engine_state, &mut stack, block, PipelineData::new(span)) { + match eval_block_with_redirect( + &engine_state, + &mut stack, + block, + PipelineData::new(span), + ) { Ok(v) => v, Err(error) => Value::Error { error }.into_pipeline_data(), } @@ -250,7 +270,12 @@ impl Command for ParEach { } } - match eval_block(&engine_state, &mut stack, block, PipelineData::new(span))? { + match eval_block_with_redirect( + &engine_state, + &mut stack, + block, + PipelineData::new(span), + )? { PipelineData::Value( Value::Record { mut cols, mut vals, .. @@ -284,7 +309,7 @@ impl Command for ParEach { } } - eval_block(&engine_state, &mut stack, block, PipelineData::new(span)) + eval_block_with_redirect(&engine_state, &mut stack, block, PipelineData::new(span)) } } } diff --git a/crates/nu-command/src/filters/where_.rs b/crates/nu-command/src/filters/where_.rs index b10047c42..99d587f12 100644 --- a/crates/nu-command/src/filters/where_.rs +++ b/crates/nu-command/src/filters/where_.rs @@ -1,4 +1,4 @@ -use nu_engine::{eval_block, CallExt}; +use nu_engine::{eval_block_with_redirect, CallExt}; use nu_protocol::ast::Call; use nu_protocol::engine::{CaptureBlock, Command, EngineState, Stack}; use nu_protocol::{Category, PipelineData, Signature, SyntaxShape}; @@ -47,8 +47,12 @@ impl Command for Where { stack.add_var(*var_id, value.clone()); } } - let result = - eval_block(&engine_state, &mut stack, &block, PipelineData::new(span)); + let result = eval_block_with_redirect( + &engine_state, + &mut stack, + &block, + PipelineData::new(span), + ); match result { Ok(result) => result.into_value(span).is_true(), diff --git a/crates/nu-engine/src/eval.rs b/crates/nu-engine/src/eval.rs index c827ebf34..68d0bd5ab 100644 --- a/crates/nu-engine/src/eval.rs +++ b/crates/nu-engine/src/eval.rs @@ -546,6 +546,80 @@ pub fn eval_block( Ok(input) } +pub fn eval_block_with_redirect( + engine_state: &EngineState, + stack: &mut Stack, + block: &Block, + mut input: PipelineData, +) -> Result { + let num_stmts = block.stmts.len(); + for (stmt_idx, stmt) in block.stmts.iter().enumerate() { + if let Statement::Pipeline(pipeline) = stmt { + for elem in pipeline.expressions.iter() { + input = eval_expression_with_input(engine_state, stack, elem, input, false)? + } + } + + if stmt_idx < (num_stmts) - 1 { + match input { + PipelineData::Value(Value::Nothing { .. }, ..) => {} + _ => { + // Drain the input to the screen via tabular output + let config = stack.get_config().unwrap_or_default(); + + match engine_state.find_decl("table".as_bytes()) { + Some(decl_id) => { + let table = engine_state.get_decl(decl_id).run( + engine_state, + stack, + &Call::new(Span::new(0, 0)), + input, + )?; + + for item in table { + let stdout = std::io::stdout(); + + if let Value::Error { error } = item { + return Err(error); + } + + let mut out = item.into_string("\n", &config); + out.push('\n'); + + match stdout.lock().write_all(out.as_bytes()) { + Ok(_) => (), + Err(err) => eprintln!("{}", err), + }; + } + } + None => { + for item in input { + let stdout = std::io::stdout(); + + if let Value::Error { error } = item { + return Err(error); + } + + let mut out = item.into_string("\n", &config); + out.push('\n'); + + match stdout.lock().write_all(out.as_bytes()) { + Ok(_) => (), + Err(err) => eprintln!("{}", err), + }; + } + } + }; + } + } + + input = PipelineData::new(Span { start: 0, end: 0 }) + } + } + + Ok(input) +} + pub fn eval_subexpression( engine_state: &EngineState, stack: &mut Stack, diff --git a/crates/nu-engine/src/lib.rs b/crates/nu-engine/src/lib.rs index f43b780d0..9de7dae38 100644 --- a/crates/nu-engine/src/lib.rs +++ b/crates/nu-engine/src/lib.rs @@ -10,6 +10,7 @@ pub use column::get_columns; pub use documentation::{generate_docs, get_brief_help, get_documentation, get_full_help}; pub use env::*; pub use eval::{ - eval_block, eval_expression, eval_expression_with_input, eval_operator, eval_subexpression, + eval_block, eval_block_with_redirect, eval_expression, eval_expression_with_input, + eval_operator, eval_subexpression, }; pub use glob_from::glob_from;