Refactor the code
This commit is contained in:
parent
d9bd1f171d
commit
50e06ee95a
@ -15,9 +15,15 @@ pub struct CompletionConfig {
|
||||
pub add_call_argument_snippets: bool,
|
||||
pub snippet_cap: Option<SnippetCap>,
|
||||
pub merge: Option<MergeBehaviour>,
|
||||
/// A set of capabilities, enabled on the cliend and supported on the server.
|
||||
pub resolve_capabilities: FxHashSet<CompletionResolveCapability>,
|
||||
}
|
||||
|
||||
/// A resolve capability, supported on a server.
|
||||
/// If the client registers any of those in its completion resolve capabilities,
|
||||
/// the server is able to render completion items' corresponding fields later,
|
||||
/// not during an initial completion item request.
|
||||
/// See https://github.com/rust-analyzer/rust-analyzer/issues/6366 for more details.
|
||||
#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq)]
|
||||
pub enum CompletionResolveCapability {
|
||||
Documentation,
|
||||
@ -30,7 +36,8 @@ impl CompletionConfig {
|
||||
self.snippet_cap = if yes { Some(SnippetCap { _private: () }) } else { None }
|
||||
}
|
||||
|
||||
pub fn should_resolve_immediately(&self) -> bool {
|
||||
/// Whether the completions' additional edits are calculated later, during a resolve request or not.
|
||||
pub fn should_resolve_additional_edits_immediately(&self) -> bool {
|
||||
!self.resolve_capabilities.contains(&CompletionResolveCapability::AdditionalTextEdits)
|
||||
}
|
||||
}
|
||||
|
@ -67,8 +67,7 @@ pub struct CompletionItem {
|
||||
/// possible match.
|
||||
ref_match: Option<(Mutability, CompletionScore)>,
|
||||
|
||||
/// The data later to be used in the `completionItem/resolve` response
|
||||
/// to add the insert import edit.
|
||||
/// The import data to add to completion's edits.
|
||||
import_to_add: Option<ImportToAdd>,
|
||||
}
|
||||
|
||||
|
@ -194,7 +194,10 @@ impl<'a> Render<'a> {
|
||||
local_name,
|
||||
)
|
||||
.kind(CompletionItemKind::UnresolvedReference)
|
||||
.add_import(import_to_add, self.ctx.completion.config.should_resolve_immediately())
|
||||
.add_import(
|
||||
import_to_add,
|
||||
self.ctx.completion.config.should_resolve_additional_edits_immediately(),
|
||||
)
|
||||
.build();
|
||||
return Some(item);
|
||||
}
|
||||
@ -249,7 +252,10 @@ impl<'a> Render<'a> {
|
||||
|
||||
let item = item
|
||||
.kind(kind)
|
||||
.add_import(import_to_add, self.ctx.completion.config.should_resolve_immediately())
|
||||
.add_import(
|
||||
import_to_add,
|
||||
self.ctx.completion.config.should_resolve_additional_edits_immediately(),
|
||||
)
|
||||
.set_documentation(docs)
|
||||
.set_ref_match(ref_match)
|
||||
.build();
|
||||
|
@ -71,7 +71,10 @@ impl<'a> EnumVariantRender<'a> {
|
||||
.kind(CompletionItemKind::EnumVariant)
|
||||
.set_documentation(self.variant.docs(self.ctx.db()))
|
||||
.set_deprecated(self.ctx.is_deprecated(self.variant))
|
||||
.add_import(import_to_add, self.ctx.completion.config.should_resolve_immediately())
|
||||
.add_import(
|
||||
import_to_add,
|
||||
self.ctx.completion.config.should_resolve_additional_edits_immediately(),
|
||||
)
|
||||
.detail(self.detail());
|
||||
|
||||
if self.variant_kind == StructKind::Tuple {
|
||||
|
@ -47,7 +47,10 @@ impl<'a> FunctionRender<'a> {
|
||||
.set_deprecated(self.ctx.is_deprecated(self.func))
|
||||
.detail(self.detail())
|
||||
.add_call_parens(self.ctx.completion, self.name, params)
|
||||
.add_import(import_to_add, self.ctx.completion.config.should_resolve_immediately())
|
||||
.add_import(
|
||||
import_to_add,
|
||||
self.ctx.completion.config.should_resolve_additional_edits_immediately(),
|
||||
)
|
||||
.build()
|
||||
}
|
||||
|
||||
|
@ -50,7 +50,10 @@ impl<'a> MacroRender<'a> {
|
||||
.kind(CompletionItemKind::Macro)
|
||||
.set_documentation(self.docs.clone())
|
||||
.set_deprecated(self.ctx.is_deprecated(self.macro_))
|
||||
.add_import(import_to_add, self.ctx.completion.config.should_resolve_immediately())
|
||||
.add_import(
|
||||
import_to_add,
|
||||
self.ctx.completion.config.should_resolve_additional_edits_immediately(),
|
||||
)
|
||||
.detail(self.detail());
|
||||
|
||||
let needs_bang = self.needs_bang();
|
||||
|
@ -97,7 +97,6 @@ pub(crate) fn check_edit_with_config(
|
||||
.unwrap_or_else(|| panic!("can't find {:?} completion in {:#?}", what, completions));
|
||||
let mut actual = db.file_text(position.file_id).to_string();
|
||||
completion.text_edit().apply(&mut actual);
|
||||
// git how to apply imports now?
|
||||
assert_eq_text!(&ra_fixture_after, &actual)
|
||||
}
|
||||
|
||||
|
@ -32,7 +32,7 @@ pub fn server_capabilities(client_caps: &ClientCapabilities) -> ServerCapabiliti
|
||||
})),
|
||||
hover_provider: Some(HoverProviderCapability::Simple(true)),
|
||||
completion_provider: Some(CompletionOptions {
|
||||
resolve_provider: Some(true),
|
||||
resolve_provider: completions_resolve_provider(client_caps),
|
||||
trigger_characters: Some(vec![":".to_string(), ".".to_string()]),
|
||||
work_done_progress_options: WorkDoneProgressOptions { work_done_progress: None },
|
||||
}),
|
||||
@ -50,9 +50,7 @@ pub fn server_capabilities(client_caps: &ClientCapabilities) -> ServerCapabiliti
|
||||
document_symbol_provider: Some(OneOf::Left(true)),
|
||||
workspace_symbol_provider: Some(OneOf::Left(true)),
|
||||
code_action_provider: Some(code_action_capabilities(client_caps)),
|
||||
code_lens_provider: Some(CodeLensOptions {
|
||||
resolve_provider: resolve_provider(client_caps),
|
||||
}),
|
||||
code_lens_provider: Some(CodeLensOptions { resolve_provider: Some(true) }),
|
||||
document_formatting_provider: Some(OneOf::Left(true)),
|
||||
document_range_formatting_provider: None,
|
||||
document_on_type_formatting_provider: Some(DocumentOnTypeFormattingOptions {
|
||||
@ -97,16 +95,16 @@ pub fn server_capabilities(client_caps: &ClientCapabilities) -> ServerCapabiliti
|
||||
}
|
||||
}
|
||||
|
||||
fn resolve_provider(client_caps: &ClientCapabilities) -> Option<bool> {
|
||||
if enabled_resolve_capabilities(client_caps)?.is_empty() {
|
||||
fn completions_resolve_provider(client_caps: &ClientCapabilities) -> Option<bool> {
|
||||
if enabled_completions_resolve_capabilities(client_caps)?.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(true)
|
||||
}
|
||||
}
|
||||
|
||||
/// Parses client capabilities and returns all that rust-analyzer supports.
|
||||
pub fn enabled_resolve_capabilities(
|
||||
/// Parses client capabilities and returns all completion resolve capabilities rust-analyzer supports.
|
||||
pub fn enabled_completions_resolve_capabilities(
|
||||
caps: &ClientCapabilities,
|
||||
) -> Option<FxHashSet<CompletionResolveCapability>> {
|
||||
Some(
|
||||
|
@ -19,7 +19,7 @@ use rustc_hash::FxHashSet;
|
||||
use serde::Deserialize;
|
||||
use vfs::AbsPathBuf;
|
||||
|
||||
use crate::{caps::enabled_resolve_capabilities, diagnostics::DiagnosticsMapConfig};
|
||||
use crate::{caps::enabled_completions_resolve_capabilities, diagnostics::DiagnosticsMapConfig};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Config {
|
||||
@ -389,7 +389,7 @@ impl Config {
|
||||
|
||||
self.completion.allow_snippets(false);
|
||||
self.completion.resolve_capabilities =
|
||||
enabled_resolve_capabilities(caps).unwrap_or_default();
|
||||
enabled_completions_resolve_capabilities(caps).unwrap_or_default();
|
||||
if let Some(completion) = &doc_caps.completion {
|
||||
if let Some(completion_item) = &completion.completion_item {
|
||||
if let Some(value) = completion_item.snippet_support {
|
||||
|
@ -581,7 +581,7 @@ pub(crate) fn handle_completion(
|
||||
&line_index,
|
||||
line_endings,
|
||||
item.clone(),
|
||||
&snap.config.completion.resolve_capabilities,
|
||||
snap.config.completion.should_resolve_additional_edits_immediately(),
|
||||
);
|
||||
|
||||
let item_id = serde_json::to_value(&item_index)
|
||||
|
@ -5,10 +5,10 @@ use std::{
|
||||
};
|
||||
|
||||
use ide::{
|
||||
Assist, AssistKind, CallInfo, CompletionItem, CompletionItemKind, CompletionResolveCapability,
|
||||
Documentation, FileSystemEdit, Fold, FoldKind, Highlight, HighlightModifier, HighlightTag,
|
||||
HighlightedRange, ImportToAdd, Indel, InlayHint, InlayKind, InsertTextFormat, LineIndex,
|
||||
Markup, NavigationTarget, ReferenceAccess, ResolvedAssist, Runnable, Severity, SourceChange,
|
||||
Assist, AssistKind, CallInfo, CompletionItem, CompletionItemKind, Documentation,
|
||||
FileSystemEdit, Fold, FoldKind, Highlight, HighlightModifier, HighlightTag, HighlightedRange,
|
||||
ImportToAdd, Indel, InlayHint, InlayKind, InsertTextFormat, LineIndex, Markup,
|
||||
NavigationTarget, ReferenceAccess, ResolvedAssist, Runnable, Severity, SourceChange,
|
||||
SourceFileEdit, TextEdit,
|
||||
};
|
||||
use ide_db::{
|
||||
@ -16,7 +16,6 @@ use ide_db::{
|
||||
helpers::{insert_use, mod_path_to_ast},
|
||||
};
|
||||
use itertools::Itertools;
|
||||
use rustc_hash::FxHashSet;
|
||||
use syntax::{algo, SyntaxKind, TextRange, TextSize};
|
||||
|
||||
use crate::{
|
||||
@ -163,7 +162,7 @@ pub(crate) fn completion_item(
|
||||
line_index: &LineIndex,
|
||||
line_endings: LineEndings,
|
||||
completion_item: CompletionItem,
|
||||
resolve_capabilities: &FxHashSet<CompletionResolveCapability>,
|
||||
should_resolve_additional_edits_immediately: bool,
|
||||
) -> Vec<lsp_types::CompletionItem> {
|
||||
fn set_score(res: &mut lsp_types::CompletionItem, label: &str) {
|
||||
res.preselect = Some(true);
|
||||
@ -237,14 +236,12 @@ pub(crate) fn completion_item(
|
||||
None => vec![res],
|
||||
};
|
||||
|
||||
let unapplied_import_data = completion_item.import_to_add().filter(|_| {
|
||||
!resolve_capabilities.contains(&CompletionResolveCapability::AdditionalTextEdits)
|
||||
});
|
||||
|
||||
for mut r in all_results.iter_mut() {
|
||||
r.insert_text_format = Some(insert_text_format(completion_item.insert_text_format()));
|
||||
if let Some(unapplied_import_data) = unapplied_import_data {
|
||||
append_import_edits(r, unapplied_import_data, line_index, line_endings);
|
||||
if !should_resolve_additional_edits_immediately {
|
||||
if let Some(unapplied_import_data) = completion_item.import_to_add() {
|
||||
append_import_edits(r, unapplied_import_data, line_index, line_endings);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -891,7 +888,6 @@ mod tests {
|
||||
let (offset, text) = test_utils::extract_offset(fixture);
|
||||
let line_index = LineIndex::new(&text);
|
||||
let (analysis, file_id) = Analysis::from_single_file(text);
|
||||
let resolve_caps = FxHashSet::default();
|
||||
let completions: Vec<(String, Option<String>)> = analysis
|
||||
.completions(
|
||||
&ide::CompletionConfig::default(),
|
||||
@ -901,7 +897,7 @@ mod tests {
|
||||
.unwrap()
|
||||
.into_iter()
|
||||
.filter(|c| c.label().ends_with("arg"))
|
||||
.map(|c| completion_item(&line_index, LineEndings::Unix, c, &resolve_caps))
|
||||
.map(|c| completion_item(&line_index, LineEndings::Unix, c, true))
|
||||
.flat_map(|comps| comps.into_iter().map(|c| (c.label, c.sort_text)))
|
||||
.collect();
|
||||
expect_test::expect![[r#"
|
||||
|
Loading…
x
Reference in New Issue
Block a user