diff --git a/crates/nu-cli/src/completions/variable_completions.rs b/crates/nu-cli/src/completions/variable_completions.rs index 2eb5b4381..3173d4289 100644 --- a/crates/nu-cli/src/completions/variable_completions.rs +++ b/crates/nu-cli/src/completions/variable_completions.rs @@ -1,5 +1,5 @@ use crate::completions::{Completer, CompletionOptions}; -use nu_engine::eval_variable; +use nu_engine::{column::get_columns, eval_variable}; use nu_protocol::{ engine::{EngineState, Stack, StateWorkingSet}, Span, Value, @@ -267,7 +267,19 @@ fn nested_suggestions( output } + Value::List { vals, span: _ } => { + for column_name in get_columns(vals.iter()) { + output.push(Suggestion { + value: column_name, + description: None, + extra: None, + span: current_span, + append_whitespace: false, + }); + } + output + } _ => output, } } @@ -295,6 +307,38 @@ fn recursive_value(val: Value, sublevels: Vec>) -> Value { span: Span::unknown(), }; } + Value::LazyRecord { val, span: _ } => { + for col in val.column_names() { + if col.as_bytes().to_vec() == next_sublevel { + return recursive_value( + val.get_column_value(col).unwrap_or_default(), + sublevels.into_iter().skip(1).collect(), + ); + } + } + + // Current sublevel value not found + return Value::Nothing { + span: Span::unknown(), + }; + } + Value::List { vals, span } => { + for col in get_columns(vals.iter()) { + if col.as_bytes().to_vec() == next_sublevel { + return recursive_value( + Value::List { vals, span } + .get_data_by_key(&col) + .unwrap_or_default(), + sublevels.into_iter().skip(1).collect(), + ); + } + } + + // Current sublevel value not found + return Value::Nothing { + span: Span::unknown(), + }; + } _ => return val, } } diff --git a/crates/nu-cli/tests/completions.rs b/crates/nu-cli/tests/completions.rs index e98469841..d6608975f 100644 --- a/crates/nu-cli/tests/completions.rs +++ b/crates/nu-cli/tests/completions.rs @@ -556,6 +556,100 @@ fn variables_completions() { // Match results match_suggestions(expected, suggestions); + // Test completions for $nu.os-info + let suggestions = completer.complete("$nu.os-info.", 12); + assert_eq!(4, suggestions.len()); + let expected: Vec = vec![ + "arch".into(), + "family".into(), + "kernel_version".into(), + "name".into(), + ]; + // Match results + match_suggestions(expected, suggestions); + + // Test completions for $nu.scope + let suggestions = completer.complete("$nu.scope.", 10); + assert_eq!(5, suggestions.len()); + let expected: Vec = vec![ + "aliases".into(), + "commands".into(), + "engine_state".into(), + "modules".into(), + "vars".into(), + ]; + // Match results + match_suggestions(expected, suggestions); + + // Test completions for $nu.scope.commands + let suggestions = completer.complete("$nu.scope.commands.", 19); + assert_eq!(15, suggestions.len()); + let expected: Vec = vec![ + "category".into(), + "creates_scope".into(), + "examples".into(), + "extra_usage".into(), + "is_builtin".into(), + "is_custom".into(), + "is_extern".into(), + "is_keyword".into(), + "is_plugin".into(), + "is_sub".into(), + "module_name".into(), + "name".into(), + "search_terms".into(), + "signatures".into(), + "usage".into(), + ]; + // Match results + match_suggestions(expected, suggestions); + + // Test completions for $nu.scope.commands.signatures + let suggestions = completer.complete("$nu.scope.commands.signatures.", 30); + assert_eq!(17, suggestions.len()); + let expected: Vec = vec![ + "any".into(), + "binary".into(), + "bool".into(), + "datetime".into(), + "duration".into(), + "filesize".into(), + "int".into(), + "list".into(), + "list".into(), + "list".into(), + "list".into(), + "nothing".into(), + "number".into(), + "range".into(), + "record".into(), + "string".into(), + "table".into(), + ]; + // Match results + match_suggestions(expected, suggestions); + + // Test completions for $nu.scope.engine_state + let suggestions = completer.complete("$nu.scope.engine_state.", 23); + assert_eq!(6, suggestions.len()); + let expected: Vec = vec![ + "num_blocks".into(), + "num_decls".into(), + "num_env_vars".into(), + "num_modules".into(), + "num_vars".into(), + "source_bytes".into(), + ]; + // Match results + match_suggestions(expected, suggestions); + + // Test completions for $nu.scope.vars + let suggestions = completer.complete("$nu.scope.vars.", 15); + assert_eq!(3, suggestions.len()); + let expected: Vec = vec!["name".into(), "type".into(), "value".into()]; + // Match results + match_suggestions(expected, suggestions); + // Test completions for custom var let suggestions = completer.complete("$actor.", 7);