From 08b5d5cce5ddbb6efa2d5e6bf8755a63b6f77b5f Mon Sep 17 00:00:00 2001 From: zc he Date: Wed, 29 Jan 2025 19:54:12 +0800 Subject: [PATCH] fix(completion): `DotNuCompletion` now completes nu scripts in const `$NU_LIB_DIRS` (#14955) # Description For nu scripts completion with command `use`/`overlay use`/`source-env`, it now supports `nu --include-path`. Also fixes some irrelevant clippy complaints. # User-Facing Changes # Tests + Formatting # After Submitting --- .../src/completions/dotnu_completions.rs | 39 ++++++++++--------- crates/nu-cli/src/repl.rs | 4 +- crates/nu-cli/src/util.rs | 4 +- crates/nu-lsp/src/ast.rs | 6 +-- 4 files changed, 28 insertions(+), 25 deletions(-) diff --git a/crates/nu-cli/src/completions/dotnu_completions.rs b/crates/nu-cli/src/completions/dotnu_completions.rs index b8134404d3..51fcd525fb 100644 --- a/crates/nu-cli/src/completions/dotnu_completions.rs +++ b/crates/nu-cli/src/completions/dotnu_completions.rs @@ -41,25 +41,28 @@ impl Completer for DotNuCompletion { let mut is_current_folder = false; // Fetch the lib dirs - let lib_dirs: Vec = if let Some(lib_dirs) = working_set.get_env_var("NU_LIB_DIRS") { - lib_dirs - .as_list() - .into_iter() - .flat_map(|it| { - it.iter().map(|x| { - x.to_path() - .expect("internal error: failed to convert lib path") + let lib_dirs: Vec = working_set + .find_variable(b"$NU_LIB_DIRS") + .and_then(|vid| working_set.get_variable(vid).const_val.as_ref()) + .or(working_set.get_env_var("NU_LIB_DIRS")) + .map(|lib_dirs| { + lib_dirs + .as_list() + .into_iter() + .flat_map(|it| { + it.iter().map(|x| { + x.to_path() + .expect("internal error: failed to convert lib path") + }) }) - }) - .map(|it| { - it.into_os_string() - .into_string() - .expect("internal error: failed to convert OS path") - }) - .collect() - } else { - vec![] - }; + .map(|it| { + it.into_os_string() + .into_string() + .expect("internal error: failed to convert OS path") + }) + .collect() + }) + .unwrap_or_default(); // Check if the base_dir is a folder // rsplit_once removes the separator diff --git a/crates/nu-cli/src/repl.rs b/crates/nu-cli/src/repl.rs index 72da95d449..a64ecbcefe 100644 --- a/crates/nu-cli/src/repl.rs +++ b/crates/nu-cli/src/repl.rs @@ -1159,7 +1159,7 @@ fn setup_history( /// Setup Reedline keybindingds based on the provided config /// fn setup_keybindings(engine_state: &EngineState, line_editor: Reedline) -> Reedline { - return match create_keybindings(engine_state.get_config()) { + match create_keybindings(engine_state.get_config()) { Ok(keybindings) => match keybindings { KeybindingsMode::Emacs(keybindings) => { let edit_mode = Box::new(Emacs::new(keybindings)); @@ -1177,7 +1177,7 @@ fn setup_keybindings(engine_state: &EngineState, line_editor: Reedline) -> Reedl report_shell_error(engine_state, &e); line_editor } - }; + } } /// diff --git a/crates/nu-cli/src/util.rs b/crates/nu-cli/src/util.rs index 6b0bade8c6..727a8290ed 100644 --- a/crates/nu-cli/src/util.rs +++ b/crates/nu-cli/src/util.rs @@ -132,7 +132,7 @@ fn gather_env_vars( working_set.error(err); } - if working_set.parse_errors.first().is_some() { + if !working_set.parse_errors.is_empty() { report_capture_error( engine_state, &String::from_utf8_lossy(contents), @@ -176,7 +176,7 @@ fn gather_env_vars( working_set.error(err); } - if working_set.parse_errors.first().is_some() { + if !working_set.parse_errors.is_empty() { report_capture_error( engine_state, &String::from_utf8_lossy(contents), diff --git a/crates/nu-lsp/src/ast.rs b/crates/nu-lsp/src/ast.rs index 200988e9ef..511a25ca6b 100644 --- a/crates/nu-lsp/src/ast.rs +++ b/crates/nu-lsp/src/ast.rs @@ -282,7 +282,7 @@ fn try_find_id_in_use( id: Option<&Id>, ) -> Option<(Id, Span)> { let call_name = working_set.get_span_contents(call.head); - if call_name != b"use" && call_name != b"hide" { + if call_name != b"use" && call_name != b"export use" && call_name != b"hide" { return None; } // TODO: for keyword `hide`, the decl/var is already hidden in working_set, @@ -318,7 +318,7 @@ fn try_find_id_in_use( if let Some(pos) = location { // first argument of `use` should always be module name // while it is optional in `hide` - if span.contains(*pos) && call_name == b"use" { + if span.contains(*pos) && call_name != b"hide" { return get_matched_module_id(working_set, span, id); } } @@ -338,7 +338,7 @@ fn try_find_id_in_use( }) }; - let arguments = if call_name == b"use" { + let arguments = if call_name != b"hide" { call.arguments.get(1..)? } else { call.arguments.as_slice()