diff --git a/crates/nu-cmd-lang/src/core_commands/hide.rs b/crates/nu-cmd-lang/src/core_commands/hide.rs index 8524f26b41..8270272d89 100644 --- a/crates/nu-cmd-lang/src/core_commands/hide.rs +++ b/crates/nu-cmd-lang/src/core_commands/hide.rs @@ -16,7 +16,7 @@ impl Command for Hide { .optional( "members", SyntaxShape::Any, - "Which members of the module to import.", + "Which members of the module to hide.", ) .category(Category::Core) } diff --git a/crates/nu-cmd-lang/src/core_commands/overlay/list.rs b/crates/nu-cmd-lang/src/core_commands/overlay/list.rs index d646d63acb..fd50d78701 100644 --- a/crates/nu-cmd-lang/src/core_commands/overlay/list.rs +++ b/crates/nu-cmd-lang/src/core_commands/overlay/list.rs @@ -9,42 +9,96 @@ impl Command for OverlayList { } fn description(&self) -> &str { - "List all active overlays." + "List all overlays with their active status." } fn signature(&self) -> nu_protocol::Signature { Signature::build("overlay list") .category(Category::Core) - .input_output_types(vec![(Type::Nothing, Type::List(Box::new(Type::String)))]) + .input_output_types(vec![( + Type::Nothing, + Type::Table( + vec![ + ("name".to_string(), Type::String), + ("active".to_string(), Type::Bool), + ] + .into(), + ), + )]) } fn extra_description(&self) -> &str { - "The overlays are listed in the order they were activated." + "The overlays are listed in the order they were activated. Hidden overlays are listed first, followed by active overlays listed in the order that they were activated. `last` command will always give the top active overlay" } fn run( &self, - _engine_state: &EngineState, + engine_state: &EngineState, stack: &mut Stack, call: &Call, _input: PipelineData, ) -> Result { - let active_overlays_engine: Vec = stack + // get active overlay iterator + let active_overlays = stack .active_overlays .iter() - .map(|s| Value::string(s, call.head)) + .map(|overlay| (overlay.clone(), true)); + + // Get all overlay names from engine state + let output_rows: Vec = engine_state + .scope + .overlays + .iter() + .filter_map(|(name, _)| { + let name = String::from_utf8_lossy(name).to_string(); + if stack + .active_overlays + .iter() + .any(|active_name| active_name == &name) + { + None + } else { + Some((name, false)) + } + }) + .chain(active_overlays) + .map(|(name, active)| { + Value::record( + record! { + "name" => Value::string(name.to_owned(), call.head), + "active" => Value::bool(active, call.head), + }, + call.head, + ) + }) .collect(); - Ok(Value::list(active_overlays_engine, call.head).into_pipeline_data()) + Ok(Value::list(output_rows, call.head).into_pipeline_data()) } fn examples(&self) -> Vec { - vec![Example { - description: "Get the last activated overlay", - example: r#"module spam { export def foo [] { "foo" } } + vec![ + Example { + description: "List all overlays with their active status", + example: r#"module spam { export def foo [] { "foo" } } overlay use spam - overlay list | last"#, - result: Some(Value::test_string("spam")), - }] + overlay list"#, + result: Some(Value::test_list(vec![Value::test_record(record! { + "name" => Value::test_string("spam"), + "active" => Value::test_bool(true), + })])), + }, + Example { + description: "Get overlay status after hiding", + example: r#"module spam { export def foo [] { "foo" } } + overlay use spam + overlay hide spam + overlay list | where name == "spam""#, + result: Some(Value::test_list(vec![Value::test_record(record! { + "name" => Value::test_string("spam"), + "active" => Value::test_bool(false), + })])), + }, + ] } } diff --git a/crates/nu-cmd-lang/src/core_commands/overlay/use_.rs b/crates/nu-cmd-lang/src/core_commands/overlay/use_.rs index 1558d1e1dc..99dc55695a 100644 --- a/crates/nu-cmd-lang/src/core_commands/overlay/use_.rs +++ b/crates/nu-cmd-lang/src/core_commands/overlay/use_.rs @@ -66,8 +66,8 @@ impl Command for OverlayUse { return Ok(PipelineData::empty()); } - let mut name_arg: Spanned = call.req(engine_state, caller_stack, 0)?; - name_arg.item = trim_quotes_str(&name_arg.item).to_string(); + let name_arg: Spanned = call.req(engine_state, caller_stack, 0)?; + let name_arg_item = trim_quotes_str(&name_arg.item); let maybe_origin_module_id: Option = if let Some(overlay_expr) = call.get_parser_info(caller_stack, "overlay_expr") { @@ -91,11 +91,11 @@ impl Command for OverlayUse { let overlay_name = if let Some(name) = call.opt(engine_state, caller_stack, 1)? { name } else if engine_state - .find_overlay(name_arg.item.as_bytes()) + .find_overlay(name_arg_item.as_bytes()) .is_some() { - name_arg.item.clone() - } else if let Some(os_str) = Path::new(&name_arg.item).file_stem() { + name_arg_item.to_string() + } else if let Some(os_str) = Path::new(name_arg_item).file_stem() { if let Some(name) = os_str.to_str() { name.to_string() } else { @@ -105,7 +105,7 @@ impl Command for OverlayUse { } } else { return Err(ShellError::OverlayNotFoundAtRuntime { - overlay_name: name_arg.item, + overlay_name: (name_arg_item.to_string()), span: name_arg.span, }); }; @@ -122,7 +122,7 @@ impl Command for OverlayUse { // Evaluate the export-env block (if any) and keep its environment if let Some(block_id) = module.env_block { let maybe_file_path_or_dir = find_in_dirs_env( - &name_arg.item, + name_arg_item, engine_state, caller_stack, get_dirs_var_from_call(caller_stack, call), diff --git a/tests/overlays/mod.rs b/tests/overlays/mod.rs index b879409a74..6dc678acaa 100644 --- a/tests/overlays/mod.rs +++ b/tests/overlays/mod.rs @@ -198,7 +198,7 @@ fn new_overlay_from_const_name() { let inp = &[ "const mod = 'spam'", "overlay new $mod", - "overlay list | last", + "overlay list | last | get name", ]; let actual = nu!(&inp.join("; ")); @@ -212,7 +212,7 @@ fn hide_overlay_from_const_name() { "const mod = 'spam'", "overlay new $mod", "overlay hide $mod", - "overlay list | str join ' '", + "overlay list | where active == true | get name | str join ' '", ]; let actual = nu!(&inp.join("; ")); @@ -410,7 +410,7 @@ fn hide_overlay_scoped_env() { #[test] fn list_default_overlay() { - let inp = &["overlay list | last"]; + let inp = &["overlay list | last | get name"]; let actual = nu!(&inp.join("; ")); let actual_repl = nu!(nu_repl_code(inp)); @@ -424,7 +424,7 @@ fn list_last_overlay() { let inp = &[ r#"module spam { export def foo [] { "foo" } }"#, "overlay use spam", - "overlay list | last", + "overlay list | last | get name", ]; let actual = nu!(&inp.join("; ")); @@ -439,7 +439,7 @@ fn list_overlay_scoped() { let inp = &[ r#"module spam { export def foo [] { "foo" } }"#, "overlay use spam", - "do { overlay list | last }", + "do { overlay list | last | get name }", ]; let actual = nu!(&inp.join("; ")); @@ -695,7 +695,7 @@ fn reset_overrides() { #[test] fn overlay_new() { - let inp = &["overlay new spam", "overlay list | last"]; + let inp = &["overlay new spam", "overlay list | last | get name"]; let actual = nu!(&inp.join("; ")); let actual_repl = nu!(nu_repl_code(inp)); @@ -1080,7 +1080,7 @@ fn overlay_use_find_scoped_module() { module spam { } overlay use spam - overlay list | last + overlay list | last | get name } "; @@ -1196,7 +1196,7 @@ fn overlay_trim_single_quote() { let inp = &[ r#"module spam { export def foo [] { "foo" } }"#, "overlay use 'spam'", - "overlay list | last ", + "overlay list | last | get name", ]; let actual = nu!(&inp.join("; ")); @@ -1227,7 +1227,7 @@ fn overlay_trim_double_quote() { let inp = &[ r#"module spam { export def foo [] { "foo" } }"#, r#"overlay use "spam" "#, - "overlay list | last ", + "overlay list | last | get name", ]; let actual = nu!(&inp.join("; ")); @@ -1428,7 +1428,7 @@ fn alias_overlay_use_2() { "module spam { export alias b = overlay use inner }", "use spam", "spam b", - "overlay list | get 1", + "overlay list | get 1.name", ]; let actual = nu!(&inp.join("; ")); @@ -1447,7 +1447,7 @@ fn alias_overlay_use_3() { "module spam { export alias b = overlay use inner }", "use spam b", "b", - "overlay list | get 1", + "overlay list | get 1.name", ]; let actual = nu!(&inp.join("; ")); @@ -1465,7 +1465,7 @@ fn alias_overlay_new() { "alias on = overlay new", "on spam", "on eggs", - "overlay list | last", + "overlay list | last | get name", ]; let actual = nu!(&inp.join("; "));