From 0ebbc8f71c5c28bbed376bd6ac931468172cbc1c Mon Sep 17 00:00:00 2001 From: Yash Thakur <45539777+ysthakur@users.noreply.github.com> Date: Thu, 11 Jan 2024 12:58:14 -0500 Subject: [PATCH] Make only_buffer_difference: true work (#11488) --- Cargo.lock | 2 +- crates/nu-cli/src/completions/completer.rs | 44 +++++++++++++-------- crates/nu-cli/src/menus/description_menu.rs | 20 ++++++---- crates/nu-lsp/src/lib.rs | 2 +- src/ide.rs | 5 ++- 5 files changed, 46 insertions(+), 27 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0d2438fcde..5d638667b0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4375,7 +4375,7 @@ dependencies = [ [[package]] name = "reedline" version = "0.28.0" -source = "git+https://github.com/nushell/reedline.git?branch=main#3e2c0fef3b0bf6bff2ab8c8853a4f0bb8c1d53f1" +source = "git+https://github.com/nushell/reedline.git?branch=main#0c5f9817465df3c80e062dd1b5b05bdd91924b83" dependencies = [ "chrono", "crossterm", diff --git a/crates/nu-cli/src/completions/completer.rs b/crates/nu-cli/src/completions/completer.rs index febd1046db..fc4a861f5f 100644 --- a/crates/nu-cli/src/completions/completer.rs +++ b/crates/nu-cli/src/completions/completer.rs @@ -110,10 +110,16 @@ impl NuCompleter { fn completion_helper(&mut self, line: &str, pos: usize) -> Vec { let mut working_set = StateWorkingSet::new(&self.engine_state); let offset = working_set.next_span_start(); + // TODO: Callers should be trimming the line themselves + let line = if line.len() > pos { &line[..pos] } else { line }; + // Adjust offset so that the spans of the suggestions will start at the right + // place even with `only_buffer_difference: true` + let fake_offset = offset + line.len() - pos; + let pos = offset + line.len(); let initial_line = line.to_string(); let mut line = line.to_string(); - line.insert(pos, 'a'); - let pos = offset + pos; + line.push('a'); + let config = self.engine_state.get_config(); let output = parse(&mut working_set, Some("completer"), line.as_bytes(), false); @@ -186,7 +192,7 @@ impl NuCompleter { &working_set, prefix, new_span, - offset, + fake_offset, pos, ); } @@ -200,7 +206,7 @@ impl NuCompleter { &working_set, prefix.clone(), new_span, - offset, + fake_offset, pos, ); @@ -211,9 +217,12 @@ impl NuCompleter { // We got no results for internal completion // now we can check if external completer is set and use it if let Some(block_id) = config.external_completer { - if let Some(external_result) = self - .external_completion(block_id, &spans, offset, new_span) - { + if let Some(external_result) = self.external_completion( + block_id, + &spans, + fake_offset, + new_span, + ) { return external_result; } } @@ -237,7 +246,7 @@ impl NuCompleter { &working_set, prefix, new_span, - offset, + fake_offset, pos, ); } @@ -262,7 +271,7 @@ impl NuCompleter { &working_set, prefix, new_span, - offset, + fake_offset, pos, ); } else if prev_expr_str == b"ls" { @@ -274,7 +283,7 @@ impl NuCompleter { &working_set, prefix, new_span, - offset, + fake_offset, pos, ); } @@ -296,7 +305,7 @@ impl NuCompleter { &working_set, prefix, new_span, - offset, + fake_offset, pos, ); } @@ -309,7 +318,7 @@ impl NuCompleter { &working_set, prefix, new_span, - offset, + fake_offset, pos, ); } @@ -322,7 +331,7 @@ impl NuCompleter { &working_set, prefix, new_span, - offset, + fake_offset, pos, ); } @@ -341,7 +350,7 @@ impl NuCompleter { &working_set, prefix.clone(), new_span, - offset, + fake_offset, pos, ); @@ -352,7 +361,10 @@ impl NuCompleter { // Try to complete using an external completer (if set) if let Some(block_id) = config.external_completer { if let Some(external_result) = self.external_completion( - block_id, &spans, offset, new_span, + block_id, + &spans, + fake_offset, + new_span, ) { return external_result; } @@ -366,7 +378,7 @@ impl NuCompleter { &working_set, prefix, new_span, - offset, + fake_offset, pos, ); diff --git a/crates/nu-cli/src/menus/description_menu.rs b/crates/nu-cli/src/menus/description_menu.rs index 26db0afb7e..11d7c76068 100644 --- a/crates/nu-cli/src/menus/description_menu.rs +++ b/crates/nu-cli/src/menus/description_menu.rs @@ -482,22 +482,26 @@ impl Menu for DescriptionMenu { /// Updates menu values fn update_values(&mut self, editor: &mut Editor, completer: &mut dyn Completer) { - if self.only_buffer_difference { + self.values = if self.only_buffer_difference { if let Some(old_string) = &self.input { let (start, input) = string_difference(editor.get_buffer(), old_string); if !input.is_empty() { - self.reset_position(); - self.values = completer.complete(input, start); + completer.complete(input, start + input.len()) + } else { + completer.complete("", editor.line_buffer().insertion_point()) } + } else { + completer.complete("", editor.line_buffer().insertion_point()) } } else { let trimmed_buffer = editor.get_buffer().replace('\n', " "); - self.values = completer.complete( - trimmed_buffer.as_str(), + completer.complete( + &trimmed_buffer.as_str()[..editor.line_buffer().insertion_point()], editor.line_buffer().insertion_point(), - ); - self.reset_position(); - } + ) + }; + + self.reset_position(); } /// The working details for the menu changes based on the size of the lines diff --git a/crates/nu-lsp/src/lib.rs b/crates/nu-lsp/src/lib.rs index 288549d34c..51a60a7e4a 100644 --- a/crates/nu-lsp/src/lib.rs +++ b/crates/nu-lsp/src/lib.rs @@ -550,7 +550,7 @@ impl LanguageServer { let location = Self::lsp_position_to_location(¶ms.text_document_position.position, rope_of_file); - let results = completer.complete(&rope_of_file.to_string(), location); + let results = completer.complete(&rope_of_file.to_string()[..location], location); if results.is_empty() { None } else { diff --git a/src/ide.rs b/src/ide.rs index 07d57d8ab9..f59011d477 100644 --- a/src/ide.rs +++ b/src/ide.rs @@ -607,7 +607,10 @@ pub fn complete(engine_reference: Arc, file_path: &str, location: & }); if let Ok(location) = location.as_i64() { - let results = completer.complete(&String::from_utf8_lossy(&file), location as usize); + let results = completer.complete( + &String::from_utf8_lossy(&file)[..location as usize], + location as usize, + ); print!("{{\"completions\": ["); let mut first = true; for result in results {