diff --git a/crates/nu-cli/src/completions/completer.rs b/crates/nu-cli/src/completions/completer.rs index 40231dabf7a..d0e045e3c82 100644 --- a/crates/nu-cli/src/completions/completer.rs +++ b/crates/nu-cli/src/completions/completer.rs @@ -307,6 +307,7 @@ impl NuCompleter { let need_externals = !prefix_str.contains(' '); let need_internals = !prefix_str.starts_with('^'); let mut span = element_expression.span; + span.end = std::cmp::min(span.end, pos + 1); if !need_internals { span = Span::new(span.start + 1, span.end) }; diff --git a/crates/nu-lsp/src/completion.rs b/crates/nu-lsp/src/completion.rs index 91918ac5405..7312e90c7c2 100644 --- a/crates/nu-lsp/src/completion.rs +++ b/crates/nu-lsp/src/completion.rs @@ -7,7 +7,7 @@ use lsp_types::{ TextEdit, }; use nu_cli::{NuCompleter, SuggestionKind}; -use nu_protocol::engine::Stack; +use nu_protocol::engine::{CommandType, Stack}; impl LanguageServer { pub(crate) fn complete(&mut self, params: &CompletionParams) -> Option { @@ -49,7 +49,12 @@ impl LanguageServer { .into_iter() .map(|r| { let mut start = params.text_document_position.position; - start.character -= (r.suggestion.span.end - r.suggestion.span.start) as u32; + start.character = start.character.saturating_sub( + r.suggestion + .span + .end + .saturating_sub(r.suggestion.span.start) as u32, + ); let decl_id = r.kind.clone().and_then(|kind| { matches!(kind, SuggestionKind::Command(_)) .then_some(engine_state.find_decl(r.suggestion.value.as_bytes(), &[])?) @@ -112,10 +117,11 @@ impl LanguageServer { }, SuggestionKind::CellPath => Some(CompletionItemKind::PROPERTY), SuggestionKind::Command(c) => match c { - nu_protocol::engine::CommandType::Keyword => Some(CompletionItemKind::KEYWORD), - nu_protocol::engine::CommandType::Builtin => Some(CompletionItemKind::FUNCTION), - nu_protocol::engine::CommandType::External => Some(CompletionItemKind::INTERFACE), - _ => None, + CommandType::Keyword => Some(CompletionItemKind::KEYWORD), + CommandType::Builtin => Some(CompletionItemKind::FUNCTION), + CommandType::Custom => Some(CompletionItemKind::METHOD), + CommandType::Alias => Some(CompletionItemKind::REFERENCE), + CommandType::External | CommandType::Plugin => Some(CompletionItemKind::INTERFACE), }, SuggestionKind::Directory => Some(CompletionItemKind::FOLDER), SuggestionKind::File => Some(CompletionItemKind::FILE), @@ -210,7 +216,7 @@ mod tests { let script = path_to_uri(&script); open_unchecked(&client_connection, script.clone()); - let resp = send_complete_request(&client_connection, script.clone(), 0, 8); + let resp = send_complete_request(&client_connection, script.clone(), 0, 6); #[cfg(not(windows))] let detail_str = "detail"; @@ -221,20 +227,15 @@ mod tests { expected: serde_json::json!([ // defined after the cursor { - "label": "config n foo bar", - "detail": detail_str, - "textEdit": { "range": { "start": { "line": 0, "character": 0 }, "end": { "line": 0, "character": 8 }, }, - "newText": "config n foo bar" + "label": "config", + "detail": "Edit nushell configuration files.", + "textEdit": { "range": { "start": { "line": 0, "character": 0 }, "end": { "line": 0, "character": 6 }, }, + "newText": "config" }, }, - { - "label": "config nu", - "detail": "Edit nu configurations.", - "textEdit": { "range": { "start": { "line": 0, "character": 0 }, "end": { "line": 0, "character": 8 }, }, - "newText": "config nu" - }, - "kind": 3 - }, + { "label": "config env", "kind": 3 }, + { "label": "config flatten", "kind": 3 }, + { "label": "config n foo bar", "detail": detail_str, "kind": 2 }, ]) );