refactor(completion, lsp): include decl_id in suggetion_kind for later usage

This commit is contained in:
blindfs 2025-04-10 08:48:52 +08:00
parent 173162df2e
commit 1d40bf2f59
7 changed files with 27 additions and 27 deletions

View File

@ -27,7 +27,7 @@ impl Completer for AttributeCompletion {
let attr_commands = let attr_commands =
working_set.find_commands_by_predicate(|s| s.starts_with(b"attr "), true); working_set.find_commands_by_predicate(|s| s.starts_with(b"attr "), true);
for (name, desc, ty) in attr_commands { for (decl_id, name, desc, ty) in attr_commands {
let name = name.strip_prefix(b"attr ").unwrap_or(&name); let name = name.strip_prefix(b"attr ").unwrap_or(&name);
matcher.add_semantic_suggestion(SemanticSuggestion { matcher.add_semantic_suggestion(SemanticSuggestion {
suggestion: Suggestion { suggestion: Suggestion {
@ -41,7 +41,7 @@ impl Completer for AttributeCompletion {
}, },
append_whitespace: false, append_whitespace: false,
}, },
kind: Some(SuggestionKind::Command(ty)), kind: Some(SuggestionKind::Command(ty, Some(decl_id))),
}); });
} }
@ -78,7 +78,7 @@ impl Completer for AttributableCompletion {
}, },
append_whitespace: false, append_whitespace: false,
}, },
kind: Some(SuggestionKind::Command(cmd.command_type())), kind: Some(SuggestionKind::Command(cmd.command_type(), None)),
}); });
} }

View File

@ -1,7 +1,7 @@
use crate::completions::CompletionOptions; use crate::completions::CompletionOptions;
use nu_protocol::{ use nu_protocol::{
engine::{Stack, StateWorkingSet}, engine::{Stack, StateWorkingSet},
Span, DeclId, Span,
}; };
use reedline::Suggestion; use reedline::Suggestion;
@ -28,7 +28,7 @@ pub struct SemanticSuggestion {
// TODO: think about name: maybe suggestion context? // TODO: think about name: maybe suggestion context?
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]
pub enum SuggestionKind { pub enum SuggestionKind {
Command(nu_protocol::engine::CommandType), Command(nu_protocol::engine::CommandType, Option<DeclId>),
Value(nu_protocol::Type), Value(nu_protocol::Type),
CellPath, CellPath,
Directory, Directory,

View File

@ -75,7 +75,10 @@ impl CommandCompletion {
append_whitespace: true, append_whitespace: true,
..Default::default() ..Default::default()
}, },
kind: Some(SuggestionKind::Command(CommandType::External)), kind: Some(SuggestionKind::Command(
CommandType::External,
None,
)),
}, },
); );
} }
@ -112,7 +115,7 @@ impl Completer for CommandCompletion {
}, },
true, true,
); );
for (name, description, typ) in filtered_commands { for (decl_id, name, description, typ) in filtered_commands {
let name = String::from_utf8_lossy(&name); let name = String::from_utf8_lossy(&name);
internal_suggs.insert( internal_suggs.insert(
name.to_string(), name.to_string(),
@ -124,7 +127,7 @@ impl Completer for CommandCompletion {
append_whitespace: true, append_whitespace: true,
..Suggestion::default() ..Suggestion::default()
}, },
kind: Some(SuggestionKind::Command(typ)), kind: Some(SuggestionKind::Command(typ, Some(decl_id))),
}, },
); );
} }

View File

@ -69,7 +69,7 @@ impl Completer for ExportableCompletion<'_> {
wrapped_name(name), wrapped_name(name),
Some(cmd.description().to_string()), Some(cmd.description().to_string()),
None, None,
SuggestionKind::Command(cmd.command_type()), SuggestionKind::Command(cmd.command_type(), Some(*decl_id)),
); );
} }
} }

View File

@ -62,17 +62,12 @@ impl LanguageServer {
suggestion: SemanticSuggestion, suggestion: SemanticSuggestion,
range: Range, range: Range,
) -> CompletionItem { ) -> CompletionItem {
let decl_id = suggestion.kind.as_ref().and_then(|kind| {
matches!(kind, SuggestionKind::Command(_))
.then_some(engine_state.find_decl(suggestion.suggestion.value.as_bytes(), &[])?)
});
let mut snippet_text = suggestion.suggestion.value.clone(); let mut snippet_text = suggestion.suggestion.value.clone();
let mut doc_string = suggestion.suggestion.extra.map(|ex| ex.join("\n")); let mut doc_string = suggestion.suggestion.extra.map(|ex| ex.join("\n"));
let mut insert_text_format = None; let mut insert_text_format = None;
let mut idx = 0; let mut idx = 0;
// use snippet as `insert_text_format` for command argument completion // use snippet as `insert_text_format` for command argument completion
if let Some(decl_id) = decl_id { if let Some(SuggestionKind::Command(_, Some(decl_id))) = suggestion.kind {
let cmd = engine_state.get_decl(decl_id); let cmd = engine_state.get_decl(decl_id);
doc_string = Some(Self::get_decl_description(cmd, true)); doc_string = Some(Self::get_decl_description(cmd, true));
insert_text_format = Some(InsertTextFormat::SNIPPET); insert_text_format = Some(InsertTextFormat::SNIPPET);
@ -138,7 +133,7 @@ impl LanguageServer {
.as_ref() .as_ref()
.map(|kind| match kind { .map(|kind| match kind {
SuggestionKind::Value(t) => t.to_string(), SuggestionKind::Value(t) => t.to_string(),
SuggestionKind::Command(cmd) => cmd.to_string(), SuggestionKind::Command(cmd, _) => cmd.to_string(),
SuggestionKind::Module => "module".to_string(), SuggestionKind::Module => "module".to_string(),
SuggestionKind::Operator => "operator".to_string(), SuggestionKind::Operator => "operator".to_string(),
SuggestionKind::Variable => "variable".to_string(), SuggestionKind::Variable => "variable".to_string(),
@ -172,7 +167,7 @@ impl LanguageServer {
_ => None, _ => None,
}, },
SuggestionKind::CellPath => Some(CompletionItemKind::PROPERTY), SuggestionKind::CellPath => Some(CompletionItemKind::PROPERTY),
SuggestionKind::Command(c) => match c { SuggestionKind::Command(c, _) => match c {
CommandType::Keyword => Some(CompletionItemKind::KEYWORD), CommandType::Keyword => Some(CompletionItemKind::KEYWORD),
CommandType::Builtin => Some(CompletionItemKind::FUNCTION), CommandType::Builtin => Some(CompletionItemKind::FUNCTION),
CommandType::Alias => Some(CompletionItemKind::REFERENCE), CommandType::Alias => Some(CompletionItemKind::REFERENCE),

View File

@ -731,18 +731,19 @@ impl EngineState {
&self, &self,
mut predicate: impl FnMut(&[u8]) -> bool, mut predicate: impl FnMut(&[u8]) -> bool,
ignore_deprecated: bool, ignore_deprecated: bool,
) -> Vec<(Vec<u8>, Option<String>, CommandType)> { ) -> Vec<(DeclId, Vec<u8>, Option<String>, CommandType)> {
let mut output = vec![]; let mut output = vec![];
for overlay_frame in self.active_overlays(&[]).rev() { for overlay_frame in self.active_overlays(&[]).rev() {
for decl in &overlay_frame.decls { for (name, decl_id) in &overlay_frame.decls {
if overlay_frame.visibility.is_decl_id_visible(decl.1) && predicate(decl.0) { if overlay_frame.visibility.is_decl_id_visible(decl_id) && predicate(name) {
let command = self.get_decl(*decl.1); let command = self.get_decl(*decl_id);
if ignore_deprecated && command.signature().category == Category::Removed { if ignore_deprecated && command.signature().category == Category::Removed {
continue; continue;
} }
output.push(( output.push((
decl.0.clone(), *decl_id,
name.clone(),
Some(command.description().to_string()), Some(command.description().to_string()),
command.command_type(), command.command_type(),
)); ));

View File

@ -780,21 +780,22 @@ impl<'a> StateWorkingSet<'a> {
&self, &self,
mut predicate: impl FnMut(&[u8]) -> bool, mut predicate: impl FnMut(&[u8]) -> bool,
ignore_deprecated: bool, ignore_deprecated: bool,
) -> Vec<(Vec<u8>, Option<String>, CommandType)> { ) -> Vec<(DeclId, Vec<u8>, Option<String>, CommandType)> {
let mut output = vec![]; let mut output = vec![];
for scope_frame in self.delta.scope.iter().rev() { for scope_frame in self.delta.scope.iter().rev() {
for overlay_id in scope_frame.active_overlays.iter().rev() { for overlay_id in scope_frame.active_overlays.iter().rev() {
let overlay_frame = scope_frame.get_overlay(*overlay_id); let overlay_frame = scope_frame.get_overlay(*overlay_id);
for decl in &overlay_frame.decls { for (name, decl_id) in &overlay_frame.decls {
if overlay_frame.visibility.is_decl_id_visible(decl.1) && predicate(decl.0) { if overlay_frame.visibility.is_decl_id_visible(decl_id) && predicate(name) {
let command = self.get_decl(*decl.1); let command = self.get_decl(*decl_id);
if ignore_deprecated && command.signature().category == Category::Removed { if ignore_deprecated && command.signature().category == Category::Removed {
continue; continue;
} }
output.push(( output.push((
decl.0.clone(), *decl_id,
name.clone(),
Some(command.description().to_string()), Some(command.description().to_string()),
command.command_type(), command.command_type(),
)); ));