From 7271ad7909445ad714063b0dedd4b6719b0a4f59 Mon Sep 17 00:00:00 2001 From: Ian Manske Date: Thu, 9 May 2024 05:38:24 +0000 Subject: [PATCH] Pass `Stack` ref to `Completer::fetch` (#12783) # Description Adds an additional `&Stack` parameter to `Completer::fetch` so that the completers don't have to store a `Stack` themselves. I also removed unnecessary `EngineState`s from the completers, since the same `EngineState` is available in the `working_set.permanent_state` also passed to `Completer::fetch`. --- crates/nu-cli/src/completions/base.rs | 7 +- .../src/completions/command_completions.rs | 20 +++--- crates/nu-cli/src/completions/completer.rs | 54 +++++---------- .../src/completions/custom_completions.rs | 15 ++-- .../src/completions/directory_completions.rs | 28 +++----- .../src/completions/dotnu_completions.rs | 69 ++++++++----------- .../src/completions/file_completions.rs | 28 +++----- .../src/completions/flag_completions.rs | 5 +- .../src/completions/variable_completions.rs | 35 ++++------ crates/nu-cli/src/repl.rs | 2 +- crates/nu-cli/tests/completions.rs | 59 ++++++++-------- crates/nu-lsp/src/lib.rs | 4 +- src/ide.rs | 3 +- 13 files changed, 146 insertions(+), 183 deletions(-) diff --git a/crates/nu-cli/src/completions/base.rs b/crates/nu-cli/src/completions/base.rs index c4290b8767..0debabe688 100644 --- a/crates/nu-cli/src/completions/base.rs +++ b/crates/nu-cli/src/completions/base.rs @@ -1,13 +1,18 @@ use crate::completions::{CompletionOptions, SortBy}; -use nu_protocol::{engine::StateWorkingSet, levenshtein_distance, Span}; +use nu_protocol::{ + engine::{Stack, StateWorkingSet}, + levenshtein_distance, Span, +}; use reedline::Suggestion; // Completer trait represents the three stages of the completion // fetch, filter and sort pub trait Completer { + #[allow(clippy::too_many_arguments)] fn fetch( &mut self, working_set: &StateWorkingSet, + stack: &Stack, prefix: Vec, span: Span, offset: usize, diff --git a/crates/nu-cli/src/completions/command_completions.rs b/crates/nu-cli/src/completions/command_completions.rs index 42094f9c97..2549854540 100644 --- a/crates/nu-cli/src/completions/command_completions.rs +++ b/crates/nu-cli/src/completions/command_completions.rs @@ -4,16 +4,14 @@ use crate::{ }; use nu_parser::FlatShape; use nu_protocol::{ - engine::{CachedFile, EngineState, StateWorkingSet}, + engine::{CachedFile, Stack, StateWorkingSet}, Span, }; use reedline::Suggestion; -use std::sync::Arc; use super::SemanticSuggestion; pub struct CommandCompletion { - engine_state: Arc, flattened: Vec<(Span, FlatShape)>, flat_shape: FlatShape, force_completion_after_space: bool, @@ -21,14 +19,11 @@ pub struct CommandCompletion { impl CommandCompletion { pub fn new( - engine_state: Arc, - _: &StateWorkingSet, flattened: Vec<(Span, FlatShape)>, flat_shape: FlatShape, force_completion_after_space: bool, ) -> Self { Self { - engine_state, flattened, flat_shape, force_completion_after_space, @@ -37,13 +32,14 @@ impl CommandCompletion { fn external_command_completion( &self, + working_set: &StateWorkingSet, prefix: &str, match_algorithm: MatchAlgorithm, ) -> Vec { let mut executables = vec![]; // os agnostic way to get the PATH env var - let paths = self.engine_state.get_path_env_var(); + let paths = working_set.permanent_state.get_path_env_var(); if let Some(paths) = paths { if let Ok(paths) = paths.as_list() { @@ -52,7 +48,10 @@ impl CommandCompletion { if let Ok(mut contents) = std::fs::read_dir(path.as_ref()) { while let Some(Ok(item)) = contents.next() { - if self.engine_state.config.max_external_completion_results + if working_set + .permanent_state + .config + .max_external_completion_results > executables.len() as i64 && !executables.contains( &item @@ -114,7 +113,7 @@ impl CommandCompletion { if find_externals { let results_external = self - .external_command_completion(&partial, match_algorithm) + .external_command_completion(working_set, &partial, match_algorithm) .into_iter() .map(move |x| SemanticSuggestion { suggestion: Suggestion { @@ -161,6 +160,7 @@ impl Completer for CommandCompletion { fn fetch( &mut self, working_set: &StateWorkingSet, + _stack: &Stack, _prefix: Vec, span: Span, offset: usize, @@ -266,6 +266,8 @@ pub fn is_passthrough_command(working_set_file_contents: &[CachedFile]) -> bool #[cfg(test)] mod command_completions_tests { use super::*; + use nu_protocol::engine::EngineState; + use std::sync::Arc; #[test] fn test_find_non_whitespace_index() { diff --git a/crates/nu-cli/src/completions/completer.rs b/crates/nu-cli/src/completions/completer.rs index 5837772d54..348111f009 100644 --- a/crates/nu-cli/src/completions/completer.rs +++ b/crates/nu-cli/src/completions/completer.rs @@ -22,10 +22,10 @@ pub struct NuCompleter { } impl NuCompleter { - pub fn new(engine_state: Arc, stack: Stack) -> Self { + pub fn new(engine_state: Arc, stack: Arc) -> Self { Self { engine_state, - stack: stack.reset_out_dest().capture(), + stack: Stack::with_parent(stack).reset_out_dest().capture(), } } @@ -52,8 +52,15 @@ impl NuCompleter { }; // Fetch - let mut suggestions = - completer.fetch(working_set, prefix.clone(), new_span, offset, pos, &options); + let mut suggestions = completer.fetch( + working_set, + &self.stack, + prefix.clone(), + new_span, + offset, + pos, + &options, + ); // Sort suggestions = completer.sort(suggestions, prefix); @@ -175,11 +182,8 @@ impl NuCompleter { // Variables completion if prefix.starts_with(b"$") || most_left_var.is_some() { - let mut completer = VariableCompletion::new( - self.engine_state.clone(), - self.stack.clone(), - most_left_var.unwrap_or((vec![], vec![])), - ); + let mut completer = + VariableCompletion::new(most_left_var.unwrap_or((vec![], vec![]))); return self.process_completion( &mut completer, @@ -224,8 +228,6 @@ impl NuCompleter { || (flat_idx == 0 && working_set.get_span_contents(new_span).is_empty()) { let mut completer = CommandCompletion::new( - self.engine_state.clone(), - &working_set, flattened.clone(), // flat_idx, FlatShape::String, @@ -253,10 +255,7 @@ impl NuCompleter { || prev_expr_str == b"overlay use" || prev_expr_str == b"source-env" { - let mut completer = DotNuCompletion::new( - self.engine_state.clone(), - self.stack.clone(), - ); + let mut completer = DotNuCompletion::new(); return self.process_completion( &mut completer, @@ -267,10 +266,7 @@ impl NuCompleter { pos, ); } else if prev_expr_str == b"ls" { - let mut completer = FileCompletion::new( - self.engine_state.clone(), - self.stack.clone(), - ); + let mut completer = FileCompletion::new(); return self.process_completion( &mut completer, @@ -288,7 +284,6 @@ impl NuCompleter { match &flat.1 { FlatShape::Custom(decl_id) => { let mut completer = CustomCompletion::new( - self.engine_state.clone(), self.stack.clone(), *decl_id, initial_line, @@ -304,10 +299,7 @@ impl NuCompleter { ); } FlatShape::Directory => { - let mut completer = DirectoryCompletion::new( - self.engine_state.clone(), - self.stack.clone(), - ); + let mut completer = DirectoryCompletion::new(); return self.process_completion( &mut completer, @@ -319,10 +311,7 @@ impl NuCompleter { ); } FlatShape::Filepath | FlatShape::GlobPattern => { - let mut completer = FileCompletion::new( - self.engine_state.clone(), - self.stack.clone(), - ); + let mut completer = FileCompletion::new(); return self.process_completion( &mut completer, @@ -335,8 +324,6 @@ impl NuCompleter { } flat_shape => { let mut completer = CommandCompletion::new( - self.engine_state.clone(), - &working_set, flattened.clone(), // flat_idx, flat_shape.clone(), @@ -369,10 +356,7 @@ impl NuCompleter { } // Check for file completion - let mut completer = FileCompletion::new( - self.engine_state.clone(), - self.stack.clone(), - ); + let mut completer = FileCompletion::new(); out = self.process_completion( &mut completer, &working_set, @@ -557,7 +541,7 @@ mod completer_tests { result.err().unwrap() ); - let mut completer = NuCompleter::new(engine_state.into(), Stack::new()); + let mut completer = NuCompleter::new(engine_state.into(), Arc::new(Stack::new())); let dataset = [ ("sudo", false, "", Vec::new()), ("sudo l", true, "l", vec!["ls", "let", "lines", "loop"]), diff --git a/crates/nu-cli/src/completions/custom_completions.rs b/crates/nu-cli/src/completions/custom_completions.rs index 12a7762e94..d2ccd5191d 100644 --- a/crates/nu-cli/src/completions/custom_completions.rs +++ b/crates/nu-cli/src/completions/custom_completions.rs @@ -6,14 +6,13 @@ use nu_engine::eval_call; use nu_protocol::{ ast::{Argument, Call, Expr, Expression}, debugger::WithoutDebug, - engine::{EngineState, Stack, StateWorkingSet}, + engine::{Stack, StateWorkingSet}, PipelineData, Span, Type, Value, }; use nu_utils::IgnoreCaseExt; -use std::{collections::HashMap, sync::Arc}; +use std::collections::HashMap; pub struct CustomCompletion { - engine_state: Arc, stack: Stack, decl_id: usize, line: String, @@ -21,10 +20,9 @@ pub struct CustomCompletion { } impl CustomCompletion { - pub fn new(engine_state: Arc, stack: Stack, decl_id: usize, line: String) -> Self { + pub fn new(stack: Stack, decl_id: usize, line: String) -> Self { Self { - engine_state, - stack: stack.reset_out_dest().capture(), + stack, decl_id, line, sort_by: SortBy::None, @@ -35,7 +33,8 @@ impl CustomCompletion { impl Completer for CustomCompletion { fn fetch( &mut self, - _: &StateWorkingSet, + working_set: &StateWorkingSet, + _stack: &Stack, prefix: Vec, span: Span, offset: usize, @@ -47,7 +46,7 @@ impl Completer for CustomCompletion { // Call custom declaration let result = eval_call::( - &self.engine_state, + working_set.permanent_state, &mut self.stack, &Call { decl_id: self.decl_id, diff --git a/crates/nu-cli/src/completions/directory_completions.rs b/crates/nu-cli/src/completions/directory_completions.rs index e8d463c19f..024322f997 100644 --- a/crates/nu-cli/src/completions/directory_completions.rs +++ b/crates/nu-cli/src/completions/directory_completions.rs @@ -8,25 +8,16 @@ use nu_protocol::{ levenshtein_distance, Span, }; use reedline::Suggestion; -use std::{ - path::{Path, MAIN_SEPARATOR as SEP}, - sync::Arc, -}; +use std::path::{Path, MAIN_SEPARATOR as SEP}; use super::SemanticSuggestion; -#[derive(Clone)] -pub struct DirectoryCompletion { - engine_state: Arc, - stack: Stack, -} +#[derive(Clone, Default)] +pub struct DirectoryCompletion {} impl DirectoryCompletion { - pub fn new(engine_state: Arc, stack: Stack) -> Self { - Self { - engine_state, - stack, - } + pub fn new() -> Self { + Self::default() } } @@ -34,10 +25,11 @@ impl Completer for DirectoryCompletion { fn fetch( &mut self, working_set: &StateWorkingSet, + stack: &Stack, prefix: Vec, span: Span, offset: usize, - _: usize, + _pos: usize, options: &CompletionOptions, ) -> Vec { let AdjustView { prefix, span, .. } = adjust_if_intermediate(&prefix, working_set, span); @@ -47,10 +39,10 @@ impl Completer for DirectoryCompletion { let output: Vec<_> = directory_completion( span, &prefix, - &self.engine_state.current_work_dir(), + &working_set.permanent_state.current_work_dir(), options, - self.engine_state.as_ref(), - &self.stack, + working_set.permanent_state, + stack, ) .into_iter() .map(move |x| SemanticSuggestion { diff --git a/crates/nu-cli/src/completions/dotnu_completions.rs b/crates/nu-cli/src/completions/dotnu_completions.rs index 8927738491..c939578b41 100644 --- a/crates/nu-cli/src/completions/dotnu_completions.rs +++ b/crates/nu-cli/src/completions/dotnu_completions.rs @@ -1,39 +1,31 @@ use crate::completions::{file_path_completion, Completer, CompletionOptions, SortBy}; use nu_protocol::{ - engine::{EngineState, Stack, StateWorkingSet}, + engine::{Stack, StateWorkingSet}, Span, }; use reedline::Suggestion; -use std::{ - path::{is_separator, Path, MAIN_SEPARATOR as SEP, MAIN_SEPARATOR_STR}, - sync::Arc, -}; +use std::path::{is_separator, Path, MAIN_SEPARATOR as SEP, MAIN_SEPARATOR_STR}; use super::SemanticSuggestion; -#[derive(Clone)] -pub struct DotNuCompletion { - engine_state: Arc, - stack: Stack, -} +#[derive(Clone, Default)] +pub struct DotNuCompletion {} impl DotNuCompletion { - pub fn new(engine_state: Arc, stack: Stack) -> Self { - Self { - engine_state, - stack, - } + pub fn new() -> Self { + Self::default() } } impl Completer for DotNuCompletion { fn fetch( &mut self, - _: &StateWorkingSet, + working_set: &StateWorkingSet, + stack: &Stack, prefix: Vec, span: Span, offset: usize, - _: usize, + _pos: usize, options: &CompletionOptions, ) -> Vec { let prefix_str = String::from_utf8_lossy(&prefix).replace('`', ""); @@ -49,26 +41,25 @@ impl Completer for DotNuCompletion { let mut is_current_folder = false; // Fetch the lib dirs - let lib_dirs: Vec = - if let Some(lib_dirs) = self.engine_state.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 = 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") }) - .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() + } else { + vec![] + }; // Check if the base_dir is a folder // rsplit_once removes the separator @@ -85,7 +76,7 @@ impl Completer for DotNuCompletion { } else { // Fetch the current folder #[allow(deprecated)] - let current_folder = self.engine_state.current_work_dir(); + let current_folder = working_set.permanent_state.current_work_dir(); is_current_folder = true; // Add the current folder and the lib dirs into the @@ -104,8 +95,8 @@ impl Completer for DotNuCompletion { &partial, &search_dir, options, - self.engine_state.as_ref(), - &self.stack, + working_set.permanent_state, + stack, ); completions .into_iter() diff --git a/crates/nu-cli/src/completions/file_completions.rs b/crates/nu-cli/src/completions/file_completions.rs index 1a99c995db..f6205f6792 100644 --- a/crates/nu-cli/src/completions/file_completions.rs +++ b/crates/nu-cli/src/completions/file_completions.rs @@ -9,25 +9,16 @@ use nu_protocol::{ }; use nu_utils::IgnoreCaseExt; use reedline::Suggestion; -use std::{ - path::{Path, MAIN_SEPARATOR as SEP}, - sync::Arc, -}; +use std::path::{Path, MAIN_SEPARATOR as SEP}; use super::SemanticSuggestion; -#[derive(Clone)] -pub struct FileCompletion { - engine_state: Arc, - stack: Stack, -} +#[derive(Clone, Default)] +pub struct FileCompletion {} impl FileCompletion { - pub fn new(engine_state: Arc, stack: Stack) -> Self { - Self { - engine_state, - stack, - } + pub fn new() -> Self { + Self::default() } } @@ -35,10 +26,11 @@ impl Completer for FileCompletion { fn fetch( &mut self, working_set: &StateWorkingSet, + stack: &Stack, prefix: Vec, span: Span, offset: usize, - _: usize, + _pos: usize, options: &CompletionOptions, ) -> Vec { let AdjustView { @@ -52,10 +44,10 @@ impl Completer for FileCompletion { readjusted, span, &prefix, - &self.engine_state.current_work_dir(), + &working_set.permanent_state.current_work_dir(), options, - self.engine_state.as_ref(), - &self.stack, + working_set.permanent_state, + stack, ) .into_iter() .map(move |x| SemanticSuggestion { diff --git a/crates/nu-cli/src/completions/flag_completions.rs b/crates/nu-cli/src/completions/flag_completions.rs index 07cd89dc0a..b0dcc0963b 100644 --- a/crates/nu-cli/src/completions/flag_completions.rs +++ b/crates/nu-cli/src/completions/flag_completions.rs @@ -1,7 +1,7 @@ use crate::completions::{Completer, CompletionOptions}; use nu_protocol::{ ast::{Expr, Expression}, - engine::StateWorkingSet, + engine::{Stack, StateWorkingSet}, Span, }; use reedline::Suggestion; @@ -23,10 +23,11 @@ impl Completer for FlagCompletion { fn fetch( &mut self, working_set: &StateWorkingSet, + _stack: &Stack, prefix: Vec, span: Span, offset: usize, - _: usize, + _pos: usize, options: &CompletionOptions, ) -> Vec { // Check if it's a flag diff --git a/crates/nu-cli/src/completions/variable_completions.rs b/crates/nu-cli/src/completions/variable_completions.rs index b869e9f972..0572fe93c1 100644 --- a/crates/nu-cli/src/completions/variable_completions.rs +++ b/crates/nu-cli/src/completions/variable_completions.rs @@ -3,30 +3,20 @@ use crate::completions::{ }; use nu_engine::{column::get_columns, eval_variable}; use nu_protocol::{ - engine::{EngineState, Stack, StateWorkingSet}, + engine::{Stack, StateWorkingSet}, Span, Value, }; use reedline::Suggestion; -use std::{str, sync::Arc}; +use std::str; #[derive(Clone)] pub struct VariableCompletion { - engine_state: Arc, // TODO: Is engine state necessary? It's already a part of working set in fetch() - stack: Stack, var_context: (Vec, Vec>), // tuple with $var and the sublevels (.b.c.d) } impl VariableCompletion { - pub fn new( - engine_state: Arc, - stack: Stack, - var_context: (Vec, Vec>), - ) -> Self { - Self { - engine_state, - stack, - var_context, - } + pub fn new(var_context: (Vec, Vec>)) -> Self { + Self { var_context } } } @@ -34,10 +24,11 @@ impl Completer for VariableCompletion { fn fetch( &mut self, working_set: &StateWorkingSet, + stack: &Stack, prefix: Vec, span: Span, offset: usize, - _: usize, + _pos: usize, options: &CompletionOptions, ) -> Vec { let mut output = vec![]; @@ -54,7 +45,7 @@ impl Completer for VariableCompletion { if !var_str.is_empty() { // Completion for $env. if var_str == "$env" { - let env_vars = self.stack.get_env_vars(&self.engine_state); + let env_vars = stack.get_env_vars(working_set.permanent_state); // Return nested values if sublevels_count > 0 { @@ -110,8 +101,8 @@ impl Completer for VariableCompletion { if var_str == "$nu" { // Eval nu var if let Ok(nuval) = eval_variable( - &self.engine_state, - &self.stack, + working_set.permanent_state, + stack, nu_protocol::NU_VARIABLE_ID, nu_protocol::Span::new(current_span.start, current_span.end), ) { @@ -133,7 +124,7 @@ impl Completer for VariableCompletion { // Completion other variable types if let Some(var_id) = var_id { // Extract the variable value from the stack - let var = self.stack.get_var(var_id, Span::new(span.start, span.end)); + let var = stack.get_var(var_id, Span::new(span.start, span.end)); // If the value exists and it's of type Record if let Ok(value) = var { @@ -207,7 +198,11 @@ impl Completer for VariableCompletion { // Permanent state vars // for scope in &self.engine_state.scope { - for overlay_frame in self.engine_state.active_overlays(&removed_overlays).rev() { + for overlay_frame in working_set + .permanent_state + .active_overlays(&removed_overlays) + .rev() + { for v in &overlay_frame.vars { if options.match_algorithm.matches_u8_insensitive( options.case_sensitive, diff --git a/crates/nu-cli/src/repl.rs b/crates/nu-cli/src/repl.rs index 338d924a69..02609924a1 100644 --- a/crates/nu-cli/src/repl.rs +++ b/crates/nu-cli/src/repl.rs @@ -389,7 +389,7 @@ fn loop_iteration(ctx: LoopContext) -> (bool, Stack, Reedline) { .with_completer(Box::new(NuCompleter::new( engine_reference.clone(), // STACK-REFERENCE 2 - Stack::with_parent(stack_arc.clone()), + stack_arc.clone(), ))) .with_quick_completions(config.quick_completions) .with_partial_completions(config.partial_completions) diff --git a/crates/nu-cli/tests/completions.rs b/crates/nu-cli/tests/completions.rs index a22d770010..cb883b67db 100644 --- a/crates/nu-cli/tests/completions.rs +++ b/crates/nu-cli/tests/completions.rs @@ -6,7 +6,10 @@ use nu_parser::parse; use nu_protocol::{debugger::WithoutDebug, engine::StateWorkingSet, PipelineData}; use reedline::{Completer, Suggestion}; use rstest::{fixture, rstest}; -use std::path::{PathBuf, MAIN_SEPARATOR}; +use std::{ + path::{PathBuf, MAIN_SEPARATOR}, + sync::Arc, +}; use support::{ completions_helpers::{new_partial_engine, new_quote_engine}, file, folder, match_suggestions, new_engine, @@ -22,7 +25,7 @@ fn completer() -> NuCompleter { assert!(support::merge_input(record.as_bytes(), &mut engine, &mut stack, dir).is_ok()); // Instantiate a new completer - NuCompleter::new(std::sync::Arc::new(engine), stack) + NuCompleter::new(Arc::new(engine), Arc::new(stack)) } #[fixture] @@ -36,7 +39,7 @@ fn completer_strings() -> NuCompleter { assert!(support::merge_input(record.as_bytes(), &mut engine, &mut stack, dir).is_ok()); // Instantiate a new completer - NuCompleter::new(std::sync::Arc::new(engine), stack) + NuCompleter::new(Arc::new(engine), Arc::new(stack)) } #[fixture] @@ -56,7 +59,7 @@ fn extern_completer() -> NuCompleter { assert!(support::merge_input(record.as_bytes(), &mut engine, &mut stack, dir).is_ok()); // Instantiate a new completer - NuCompleter::new(std::sync::Arc::new(engine), stack) + NuCompleter::new(Arc::new(engine), Arc::new(stack)) } #[fixture] @@ -79,14 +82,14 @@ fn custom_completer() -> NuCompleter { assert!(support::merge_input(record.as_bytes(), &mut engine, &mut stack, dir).is_ok()); // Instantiate a new completer - NuCompleter::new(std::sync::Arc::new(engine), stack) + NuCompleter::new(Arc::new(engine), Arc::new(stack)) } #[test] fn variables_dollar_sign_with_varialblecompletion() { let (_, _, engine, stack) = new_engine(); - let mut completer = NuCompleter::new(std::sync::Arc::new(engine), stack); + let mut completer = NuCompleter::new(Arc::new(engine), Arc::new(stack)); let target_dir = "$ "; let suggestions = completer.complete(target_dir, target_dir.len()); @@ -138,7 +141,7 @@ fn dotnu_completions() { let (_, _, engine, stack) = new_engine(); // Instantiate a new completer - let mut completer = NuCompleter::new(std::sync::Arc::new(engine), stack); + let mut completer = NuCompleter::new(Arc::new(engine), Arc::new(stack)); // Test source completion let completion_str = "source-env ".to_string(); @@ -217,7 +220,7 @@ fn file_completions() { let (dir, dir_str, engine, stack) = new_engine(); // Instantiate a new completer - let mut completer = NuCompleter::new(std::sync::Arc::new(engine), stack); + let mut completer = NuCompleter::new(Arc::new(engine), Arc::new(stack)); // Test completions for the current folder let target_dir = format!("cp {dir_str}{MAIN_SEPARATOR}"); @@ -265,7 +268,7 @@ fn partial_completions() { let (dir, _, engine, stack) = new_partial_engine(); // Instantiate a new completer - let mut completer = NuCompleter::new(std::sync::Arc::new(engine), stack); + let mut completer = NuCompleter::new(Arc::new(engine), Arc::new(stack)); // Test completions for a folder's name let target_dir = format!("cd {}", file(dir.join("pa"))); @@ -363,7 +366,7 @@ fn partial_completions() { fn command_ls_with_filecompletion() { let (_, _, engine, stack) = new_engine(); - let mut completer = NuCompleter::new(std::sync::Arc::new(engine), stack); + let mut completer = NuCompleter::new(Arc::new(engine), Arc::new(stack)); let target_dir = "ls "; let suggestions = completer.complete(target_dir, target_dir.len()); @@ -397,7 +400,7 @@ fn command_ls_with_filecompletion() { fn command_open_with_filecompletion() { let (_, _, engine, stack) = new_engine(); - let mut completer = NuCompleter::new(std::sync::Arc::new(engine), stack); + let mut completer = NuCompleter::new(Arc::new(engine), Arc::new(stack)); let target_dir = "open "; let suggestions = completer.complete(target_dir, target_dir.len()); @@ -432,7 +435,7 @@ fn command_open_with_filecompletion() { fn command_rm_with_globcompletion() { let (_, _, engine, stack) = new_engine(); - let mut completer = NuCompleter::new(std::sync::Arc::new(engine), stack); + let mut completer = NuCompleter::new(Arc::new(engine), Arc::new(stack)); let target_dir = "rm "; let suggestions = completer.complete(target_dir, target_dir.len()); @@ -467,7 +470,7 @@ fn command_rm_with_globcompletion() { fn command_cp_with_globcompletion() { let (_, _, engine, stack) = new_engine(); - let mut completer = NuCompleter::new(std::sync::Arc::new(engine), stack); + let mut completer = NuCompleter::new(Arc::new(engine), Arc::new(stack)); let target_dir = "cp "; let suggestions = completer.complete(target_dir, target_dir.len()); @@ -502,7 +505,7 @@ fn command_cp_with_globcompletion() { fn command_save_with_filecompletion() { let (_, _, engine, stack) = new_engine(); - let mut completer = NuCompleter::new(std::sync::Arc::new(engine), stack); + let mut completer = NuCompleter::new(Arc::new(engine), Arc::new(stack)); let target_dir = "save "; let suggestions = completer.complete(target_dir, target_dir.len()); @@ -537,7 +540,7 @@ fn command_save_with_filecompletion() { fn command_touch_with_filecompletion() { let (_, _, engine, stack) = new_engine(); - let mut completer = NuCompleter::new(std::sync::Arc::new(engine), stack); + let mut completer = NuCompleter::new(Arc::new(engine), Arc::new(stack)); let target_dir = "touch "; let suggestions = completer.complete(target_dir, target_dir.len()); @@ -572,7 +575,7 @@ fn command_touch_with_filecompletion() { fn command_watch_with_filecompletion() { let (_, _, engine, stack) = new_engine(); - let mut completer = NuCompleter::new(std::sync::Arc::new(engine), stack); + let mut completer = NuCompleter::new(Arc::new(engine), Arc::new(stack)); let target_dir = "watch "; let suggestions = completer.complete(target_dir, target_dir.len()); @@ -607,7 +610,7 @@ fn command_watch_with_filecompletion() { fn file_completion_quoted() { let (_, _, engine, stack) = new_quote_engine(); - let mut completer = NuCompleter::new(std::sync::Arc::new(engine), stack); + let mut completer = NuCompleter::new(Arc::new(engine), Arc::new(stack)); let target_dir = "open "; let suggestions = completer.complete(target_dir, target_dir.len()); @@ -645,7 +648,7 @@ fn flag_completions() { let (_, _, engine, stack) = new_engine(); // Instantiate a new completer - let mut completer = NuCompleter::new(std::sync::Arc::new(engine), stack); + let mut completer = NuCompleter::new(Arc::new(engine), Arc::new(stack)); // Test completions for the 'ls' flags let suggestions = completer.complete("ls -", 4); @@ -680,7 +683,7 @@ fn folder_with_directorycompletions() { let (dir, dir_str, engine, stack) = new_engine(); // Instantiate a new completer - let mut completer = NuCompleter::new(std::sync::Arc::new(engine), stack); + let mut completer = NuCompleter::new(Arc::new(engine), Arc::new(stack)); // Test completions for the current folder let target_dir = format!("cd {dir_str}{MAIN_SEPARATOR}"); @@ -709,7 +712,7 @@ fn variables_completions() { assert!(support::merge_input(record.as_bytes(), &mut engine, &mut stack, dir).is_ok()); // Instantiate a new completer - let mut completer = NuCompleter::new(std::sync::Arc::new(engine), stack); + let mut completer = NuCompleter::new(Arc::new(engine), Arc::new(stack)); // Test completions for $nu let suggestions = completer.complete("$nu.", 4); @@ -815,7 +818,7 @@ fn alias_of_command_and_flags() { let alias = r#"alias ll = ls -l"#; assert!(support::merge_input(alias.as_bytes(), &mut engine, &mut stack, dir).is_ok()); - let mut completer = NuCompleter::new(std::sync::Arc::new(engine), stack); + let mut completer = NuCompleter::new(Arc::new(engine), Arc::new(stack)); let suggestions = completer.complete("ll t", 4); #[cfg(windows)] @@ -834,7 +837,7 @@ fn alias_of_basic_command() { let alias = r#"alias ll = ls "#; assert!(support::merge_input(alias.as_bytes(), &mut engine, &mut stack, dir).is_ok()); - let mut completer = NuCompleter::new(std::sync::Arc::new(engine), stack); + let mut completer = NuCompleter::new(Arc::new(engine), Arc::new(stack)); let suggestions = completer.complete("ll t", 4); #[cfg(windows)] @@ -856,7 +859,7 @@ fn alias_of_another_alias() { let alias = r#"alias lf = ll -f"#; assert!(support::merge_input(alias.as_bytes(), &mut engine, &mut stack, dir).is_ok()); - let mut completer = NuCompleter::new(std::sync::Arc::new(engine), stack); + let mut completer = NuCompleter::new(Arc::new(engine), Arc::new(stack)); let suggestions = completer.complete("lf t", 4); #[cfg(windows)] @@ -890,7 +893,7 @@ fn run_external_completion(completer: &str, input: &str) -> Vec { assert!(engine_state.merge_env(&mut stack, &dir).is_ok()); // Instantiate a new completer - let mut completer = NuCompleter::new(std::sync::Arc::new(engine_state), stack); + let mut completer = NuCompleter::new(Arc::new(engine_state), Arc::new(stack)); completer.complete(input, input.len()) } @@ -899,7 +902,7 @@ fn run_external_completion(completer: &str, input: &str) -> Vec { fn unknown_command_completion() { let (_, _, engine, stack) = new_engine(); - let mut completer = NuCompleter::new(std::sync::Arc::new(engine), stack); + let mut completer = NuCompleter::new(Arc::new(engine), Arc::new(stack)); let target_dir = "thiscommanddoesnotexist "; let suggestions = completer.complete(target_dir, target_dir.len()); @@ -962,7 +965,7 @@ fn flagcompletion_triggers_after_cursor_piped(mut completer: NuCompleter) { fn filecompletions_triggers_after_cursor() { let (_, _, engine, stack) = new_engine(); - let mut completer = NuCompleter::new(std::sync::Arc::new(engine), stack); + let mut completer = NuCompleter::new(Arc::new(engine), Arc::new(stack)); let suggestions = completer.complete("cp test_c", 3); @@ -1071,7 +1074,7 @@ fn alias_offset_bug_7648() { let alias = r#"alias ea = ^$env.EDITOR /tmp/test.s"#; assert!(support::merge_input(alias.as_bytes(), &mut engine, &mut stack, dir).is_ok()); - let mut completer = NuCompleter::new(std::sync::Arc::new(engine), stack); + let mut completer = NuCompleter::new(Arc::new(engine), Arc::new(stack)); // Issue #7648 // Nushell crashes when an alias name is shorter than the alias command @@ -1090,7 +1093,7 @@ fn alias_offset_bug_7754() { let alias = r#"alias ll = ls -l"#; assert!(support::merge_input(alias.as_bytes(), &mut engine, &mut stack, dir).is_ok()); - let mut completer = NuCompleter::new(std::sync::Arc::new(engine), stack); + let mut completer = NuCompleter::new(Arc::new(engine), Arc::new(stack)); // Issue #7754 // Nushell crashes when an alias name is shorter than the alias command diff --git a/crates/nu-lsp/src/lib.rs b/crates/nu-lsp/src/lib.rs index 939bb0e4e0..47535d9bd4 100644 --- a/crates/nu-lsp/src/lib.rs +++ b/crates/nu-lsp/src/lib.rs @@ -552,8 +552,8 @@ impl LanguageServer { ¶ms.text_document_position.text_document.uri, )?; - let stack = Stack::new(); - let mut completer = NuCompleter::new(Arc::new(engine_state.clone()), stack); + let mut completer = + NuCompleter::new(Arc::new(engine_state.clone()), Arc::new(Stack::new())); let location = Self::lsp_position_to_location(¶ms.text_document_position.position, rope_of_file); diff --git a/src/ide.rs b/src/ide.rs index 2b39dda946..73419ed857 100644 --- a/src/ide.rs +++ b/src/ide.rs @@ -606,8 +606,7 @@ pub fn hover(engine_state: &mut EngineState, file_path: &str, location: &Value) } pub fn complete(engine_reference: Arc, file_path: &str, location: &Value) { - let stack = Stack::new(); - let mut completer = NuCompleter::new(engine_reference, stack); + let mut completer = NuCompleter::new(engine_reference, Arc::new(Stack::new())); let file = std::fs::read(file_path) .into_diagnostic()