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
This commit is contained in:
zc he 2025-01-29 19:54:12 +08:00 committed by GitHub
parent 03bb144150
commit 08b5d5cce5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 28 additions and 25 deletions

View File

@ -41,25 +41,28 @@ impl Completer for DotNuCompletion {
let mut is_current_folder = false; let mut is_current_folder = false;
// Fetch the lib dirs // Fetch the lib dirs
let lib_dirs: Vec<String> = if let Some(lib_dirs) = working_set.get_env_var("NU_LIB_DIRS") { let lib_dirs: Vec<String> = working_set
lib_dirs .find_variable(b"$NU_LIB_DIRS")
.as_list() .and_then(|vid| working_set.get_variable(vid).const_val.as_ref())
.into_iter() .or(working_set.get_env_var("NU_LIB_DIRS"))
.flat_map(|it| { .map(|lib_dirs| {
it.iter().map(|x| { lib_dirs
x.to_path() .as_list()
.expect("internal error: failed to convert lib path") .into_iter()
.flat_map(|it| {
it.iter().map(|x| {
x.to_path()
.expect("internal error: failed to convert lib path")
})
}) })
}) .map(|it| {
.map(|it| { it.into_os_string()
it.into_os_string() .into_string()
.into_string() .expect("internal error: failed to convert OS path")
.expect("internal error: failed to convert OS path") })
}) .collect()
.collect() })
} else { .unwrap_or_default();
vec![]
};
// Check if the base_dir is a folder // Check if the base_dir is a folder
// rsplit_once removes the separator // rsplit_once removes the separator

View File

@ -1159,7 +1159,7 @@ fn setup_history(
/// Setup Reedline keybindingds based on the provided config /// Setup Reedline keybindingds based on the provided config
/// ///
fn setup_keybindings(engine_state: &EngineState, line_editor: Reedline) -> Reedline { 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 { Ok(keybindings) => match keybindings {
KeybindingsMode::Emacs(keybindings) => { KeybindingsMode::Emacs(keybindings) => {
let edit_mode = Box::new(Emacs::new(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); report_shell_error(engine_state, &e);
line_editor line_editor
} }
}; }
} }
/// ///

View File

@ -132,7 +132,7 @@ fn gather_env_vars(
working_set.error(err); working_set.error(err);
} }
if working_set.parse_errors.first().is_some() { if !working_set.parse_errors.is_empty() {
report_capture_error( report_capture_error(
engine_state, engine_state,
&String::from_utf8_lossy(contents), &String::from_utf8_lossy(contents),
@ -176,7 +176,7 @@ fn gather_env_vars(
working_set.error(err); working_set.error(err);
} }
if working_set.parse_errors.first().is_some() { if !working_set.parse_errors.is_empty() {
report_capture_error( report_capture_error(
engine_state, engine_state,
&String::from_utf8_lossy(contents), &String::from_utf8_lossy(contents),

View File

@ -282,7 +282,7 @@ fn try_find_id_in_use(
id: Option<&Id>, id: Option<&Id>,
) -> Option<(Id, Span)> { ) -> Option<(Id, Span)> {
let call_name = working_set.get_span_contents(call.head); 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; return None;
} }
// TODO: for keyword `hide`, the decl/var is already hidden in working_set, // 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 { if let Some(pos) = location {
// first argument of `use` should always be module name // first argument of `use` should always be module name
// while it is optional in `hide` // 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); 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..)? call.arguments.get(1..)?
} else { } else {
call.arguments.as_slice() call.arguments.as_slice()