From 68c2729991e52cb115af42d8fe0a6b9150977470 Mon Sep 17 00:00:00 2001 From: Darren Schroeder <343840+fdncred@users.noreply.github.com> Date: Wed, 18 Dec 2024 06:41:50 -0600 Subject: [PATCH] add `view blocks` command (#14610) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # Description This PR is meant to add another nushell introspection/debug command, `view blocks`. This command shows what is in the EngineState's memory that is parsed and stored as blocks. Blocks may continue to grow as you use the repl.   ![image](https://github.com/user-attachments/assets/8a19fd56-ef15-4993-9700-a51eb8eaec7f) # User-Facing Changes # Tests + Formatting # After Submitting --- crates/nu-command/src/debug/mod.rs | 2 + crates/nu-command/src/debug/view_blocks.rs | 71 ++++++++++++++++++++++ crates/nu-command/src/default_context.rs | 1 + 3 files changed, 74 insertions(+) create mode 100644 crates/nu-command/src/debug/view_blocks.rs diff --git a/crates/nu-command/src/debug/mod.rs b/crates/nu-command/src/debug/mod.rs index aabb20883dc..50ffa46b9aa 100644 --- a/crates/nu-command/src/debug/mod.rs +++ b/crates/nu-command/src/debug/mod.rs @@ -10,6 +10,7 @@ mod metadata_set; mod profile; mod timeit; mod view; +mod view_blocks; mod view_files; mod view_ir; mod view_source; @@ -27,6 +28,7 @@ pub use metadata_set::MetadataSet; pub use profile::DebugProfile; pub use timeit::TimeIt; pub use view::View; +pub use view_blocks::ViewBlocks; pub use view_files::ViewFiles; pub use view_ir::ViewIr; pub use view_source::ViewSource; diff --git a/crates/nu-command/src/debug/view_blocks.rs b/crates/nu-command/src/debug/view_blocks.rs new file mode 100644 index 00000000000..a2f2f4b04a5 --- /dev/null +++ b/crates/nu-command/src/debug/view_blocks.rs @@ -0,0 +1,71 @@ +use nu_engine::command_prelude::*; + +#[derive(Clone)] +pub struct ViewBlocks; + +impl Command for ViewBlocks { + fn name(&self) -> &str { + "view blocks" + } + + fn description(&self) -> &str { + "View the blocks registered in nushell's EngineState memory." + } + + fn extra_description(&self) -> &str { + "These are blocks parsed and loaded at runtime as well as any blocks that accumulate in the repl." + } + + fn signature(&self) -> nu_protocol::Signature { + Signature::build("view blocks") + .input_output_types(vec![( + Type::Nothing, + Type::Table( + [ + ("block_id".into(), Type::Int), + ("content".into(), Type::String), + ("start".into(), Type::Int), + ("end".into(), Type::Int), + ] + .into(), + ), + )]) + .category(Category::Debug) + } + + fn run( + &self, + engine_state: &EngineState, + _stack: &mut Stack, + call: &Call, + _input: PipelineData, + ) -> Result { + let mut records = vec![]; + + for block_id in 0..engine_state.num_blocks() { + let block = engine_state.get_block(nu_protocol::BlockId::new(block_id)); + + if let Some(span) = block.span { + let contents_bytes = engine_state.get_span_contents(span); + let contents_string = String::from_utf8_lossy(contents_bytes); + let cur_rec = record! { + "block_id" => Value::int(block_id as i64, span), + "content" => Value::string(contents_string.trim().to_string(), span), + "start" => Value::int(span.start as i64, span), + "end" => Value::int(span.end as i64, span), + }; + records.push(Value::record(cur_rec, span)); + } + } + + Ok(Value::list(records, call.head).into_pipeline_data()) + } + + fn examples(&self) -> Vec { + vec![Example { + description: "View the blocks registered in Nushell's EngineState memory", + example: r#"view blocks"#, + result: None, + }] + } +} diff --git a/crates/nu-command/src/default_context.rs b/crates/nu-command/src/default_context.rs index 84abe6a6434..3612c963c8f 100644 --- a/crates/nu-command/src/default_context.rs +++ b/crates/nu-command/src/default_context.rs @@ -161,6 +161,7 @@ pub fn add_shell_command_context(mut engine_state: EngineState) -> EngineState { MetadataSet, TimeIt, View, + ViewBlocks, ViewFiles, ViewIr, ViewSource,