From 19c3570cf981715b4fc719d42fcf24098b14eaee Mon Sep 17 00:00:00 2001 From: Simon Goller Date: Fri, 1 Apr 2022 20:52:32 +0200 Subject: [PATCH] Allow open to work with 'from ...' block commands (#5049) * Remove panic from BlockCommands run function Instead of panicing, the run method now returns an error to prevent nushell from unexpected termination. * Add ability to open command to run with blocks The open command tries to parse the content of the file if there is a command called 'from (file ending)'. This works fine if the command was 'built in' because the run method doesn't fail in this case. It did fail on a BlockCommand, though. This change will first probe if the command contains a block and evaluate it, if this is the case. If there is no block, it will run the command the same way as before. * Add test open files with BlockCommands * Update open.rs * Adjust file type on open with BlockCommand parser Co-authored-by: JT <547158+jntrnr@users.noreply.github.com> --- crates/nu-command/src/filesystem/open.rs | 17 ++++++++++------- crates/nu-command/tests/commands/open.rs | 17 +++++++++++++++++ crates/nu-protocol/src/signature.rs | 5 ++++- .../fixtures/formats/sample.blockcommandparser | 2 ++ 4 files changed, 33 insertions(+), 8 deletions(-) create mode 100644 tests/fixtures/formats/sample.blockcommandparser diff --git a/crates/nu-command/src/filesystem/open.rs b/crates/nu-command/src/filesystem/open.rs index c54261df54..fc9c4fd392 100644 --- a/crates/nu-command/src/filesystem/open.rs +++ b/crates/nu-command/src/filesystem/open.rs @@ -1,4 +1,4 @@ -use nu_engine::{get_full_help, CallExt}; +use nu_engine::{eval_block, get_full_help, CallExt}; use nu_protocol::ast::Call; use nu_protocol::engine::{Command, EngineState, Stack}; use nu_protocol::{ @@ -141,12 +141,15 @@ impl Command for Open { if let Some(ext) = ext { match engine_state.find_decl(format!("from {}", ext).as_bytes()) { - Some(converter_id) => engine_state.get_decl(converter_id).run( - engine_state, - stack, - &Call::new(arg_span), - output, - ), + Some(converter_id) => { + let decl = engine_state.get_decl(converter_id); + if let Some(block_id) = decl.get_block_id() { + let block = engine_state.get_block(block_id); + eval_block(engine_state, stack, block, output, false, false) + } else { + decl.run(engine_state, stack, &Call::new(arg_span), output) + } + } None => Ok(output), } } else { diff --git a/crates/nu-command/tests/commands/open.rs b/crates/nu-command/tests/commands/open.rs index 9efc2e04c6..2240f55866 100644 --- a/crates/nu-command/tests/commands/open.rs +++ b/crates/nu-command/tests/commands/open.rs @@ -260,3 +260,20 @@ fn open_dir_is_ls() { assert_eq!(actual.out, "3"); }) } + +#[test] +fn test_open_block_command() { + let actual = nu!( + cwd: "tests/fixtures/formats", + r#" + def "from blockcommandparser" [] { lines | split column ",|," } + let values = (open sample.blockcommandparser) + echo ($values | get column1 | get 0) + echo ($values | get column2 | get 0) + echo ($values | get column1 | get 1) + echo ($values | get column2 | get 1) + "# + ); + + assert_eq!(actual.out, "abcd") +} diff --git a/crates/nu-protocol/src/signature.rs b/crates/nu-protocol/src/signature.rs index f65ecc9dcc..92d2cc0c71 100644 --- a/crates/nu-protocol/src/signature.rs +++ b/crates/nu-protocol/src/signature.rs @@ -8,6 +8,7 @@ use crate::engine::EngineState; use crate::engine::Stack; use crate::BlockId; use crate::PipelineData; +use crate::ShellError; use crate::SyntaxShape; use crate::VarId; @@ -548,7 +549,9 @@ impl Command for BlockCommand { _call: &Call, _input: PipelineData, ) -> Result { - panic!("Internal error: can't run custom command with 'run', use block_id"); + Err(ShellError::UnlabeledError( + "Internal error: can't run custom command with 'run', use block_id".to_string(), + )) } fn get_block_id(&self) -> Option { diff --git a/tests/fixtures/formats/sample.blockcommandparser b/tests/fixtures/formats/sample.blockcommandparser new file mode 100644 index 0000000000..d33414ec4c --- /dev/null +++ b/tests/fixtures/formats/sample.blockcommandparser @@ -0,0 +1,2 @@ +a,|,b +c,|,d