mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-29 21:35:20 +00:00
Add eager resolve capability
This commit is contained in:
parent
2a7be4afb0
commit
d9bd1f171d
8 changed files with 43 additions and 13 deletions
|
@ -29,6 +29,10 @@ impl CompletionConfig {
|
||||||
pub fn allow_snippets(&mut self, yes: bool) {
|
pub fn allow_snippets(&mut self, yes: bool) {
|
||||||
self.snippet_cap = if yes { Some(SnippetCap { _private: () }) } else { None }
|
self.snippet_cap = if yes { Some(SnippetCap { _private: () }) } else { None }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn should_resolve_immediately(&self) -> bool {
|
||||||
|
!self.resolve_capabilities.contains(&CompletionResolveCapability::AdditionalTextEdits)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||||
|
|
|
@ -3,8 +3,11 @@
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
use hir::{Documentation, ModPath, Mutability};
|
use hir::{Documentation, ModPath, Mutability};
|
||||||
use ide_db::helpers::insert_use::{ImportScope, MergeBehaviour};
|
use ide_db::helpers::{
|
||||||
use syntax::TextRange;
|
insert_use::{self, ImportScope, MergeBehaviour},
|
||||||
|
mod_path_to_ast,
|
||||||
|
};
|
||||||
|
use syntax::{algo, TextRange};
|
||||||
use text_edit::TextEdit;
|
use text_edit::TextEdit;
|
||||||
|
|
||||||
use crate::config::SnippetCap;
|
use crate::config::SnippetCap;
|
||||||
|
@ -207,6 +210,7 @@ impl CompletionItem {
|
||||||
score: None,
|
score: None,
|
||||||
ref_match: None,
|
ref_match: None,
|
||||||
import_to_add: None,
|
import_to_add: None,
|
||||||
|
resolve_import_immediately: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -279,6 +283,7 @@ pub(crate) struct Builder {
|
||||||
source_range: TextRange,
|
source_range: TextRange,
|
||||||
completion_kind: CompletionKind,
|
completion_kind: CompletionKind,
|
||||||
import_to_add: Option<ImportToAdd>,
|
import_to_add: Option<ImportToAdd>,
|
||||||
|
resolve_import_immediately: bool,
|
||||||
label: String,
|
label: String,
|
||||||
insert_text: Option<String>,
|
insert_text: Option<String>,
|
||||||
insert_text_format: InsertTextFormat,
|
insert_text_format: InsertTextFormat,
|
||||||
|
@ -300,6 +305,7 @@ impl Builder {
|
||||||
let mut label = self.label;
|
let mut label = self.label;
|
||||||
let mut lookup = self.lookup;
|
let mut lookup = self.lookup;
|
||||||
let mut insert_text = self.insert_text;
|
let mut insert_text = self.insert_text;
|
||||||
|
let mut text_edits = TextEdit::builder();
|
||||||
|
|
||||||
if let Some(import_to_add) = self.import_to_add.as_ref() {
|
if let Some(import_to_add) = self.import_to_add.as_ref() {
|
||||||
let mut import_path_without_last_segment = import_to_add.import_path.to_owned();
|
let mut import_path_without_last_segment = import_to_add.import_path.to_owned();
|
||||||
|
@ -314,20 +320,35 @@ impl Builder {
|
||||||
}
|
}
|
||||||
label = format!("{}::{}", import_path_without_last_segment, label);
|
label = format!("{}::{}", import_path_without_last_segment, label);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if self.resolve_import_immediately {
|
||||||
|
let rewriter = insert_use::insert_use(
|
||||||
|
&import_to_add.import_scope,
|
||||||
|
mod_path_to_ast(&import_to_add.import_path),
|
||||||
|
import_to_add.merge_behaviour,
|
||||||
|
);
|
||||||
|
if let Some(old_ast) = rewriter.rewrite_root() {
|
||||||
|
algo::diff(&old_ast, &rewriter.rewrite(&old_ast))
|
||||||
|
.into_text_edit(&mut text_edits);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let text_edit = match self.text_edit {
|
let original_edit = match self.text_edit {
|
||||||
Some(it) => it,
|
Some(it) => it,
|
||||||
None => {
|
None => {
|
||||||
TextEdit::replace(self.source_range, insert_text.unwrap_or_else(|| label.clone()))
|
TextEdit::replace(self.source_range, insert_text.unwrap_or_else(|| label.clone()))
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let mut resulting_edit = text_edits.finish();
|
||||||
|
resulting_edit.union(original_edit).expect("Failed to unite text edits");
|
||||||
|
|
||||||
CompletionItem {
|
CompletionItem {
|
||||||
source_range: self.source_range,
|
source_range: self.source_range,
|
||||||
label,
|
label,
|
||||||
insert_text_format: self.insert_text_format,
|
insert_text_format: self.insert_text_format,
|
||||||
text_edit,
|
text_edit: resulting_edit,
|
||||||
detail: self.detail,
|
detail: self.detail,
|
||||||
documentation: self.documentation,
|
documentation: self.documentation,
|
||||||
lookup,
|
lookup,
|
||||||
|
@ -400,8 +421,13 @@ impl Builder {
|
||||||
self.trigger_call_info = Some(true);
|
self.trigger_call_info = Some(true);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
pub(crate) fn add_import(mut self, import_to_add: Option<ImportToAdd>) -> Builder {
|
pub(crate) fn add_import(
|
||||||
|
mut self,
|
||||||
|
import_to_add: Option<ImportToAdd>,
|
||||||
|
resolve_import_immediately: bool,
|
||||||
|
) -> Builder {
|
||||||
self.import_to_add = import_to_add;
|
self.import_to_add = import_to_add;
|
||||||
|
self.resolve_import_immediately = resolve_import_immediately;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
pub(crate) fn set_ref_match(
|
pub(crate) fn set_ref_match(
|
||||||
|
|
|
@ -194,7 +194,7 @@ impl<'a> Render<'a> {
|
||||||
local_name,
|
local_name,
|
||||||
)
|
)
|
||||||
.kind(CompletionItemKind::UnresolvedReference)
|
.kind(CompletionItemKind::UnresolvedReference)
|
||||||
.add_import(import_to_add)
|
.add_import(import_to_add, self.ctx.completion.config.should_resolve_immediately())
|
||||||
.build();
|
.build();
|
||||||
return Some(item);
|
return Some(item);
|
||||||
}
|
}
|
||||||
|
@ -249,7 +249,7 @@ impl<'a> Render<'a> {
|
||||||
|
|
||||||
let item = item
|
let item = item
|
||||||
.kind(kind)
|
.kind(kind)
|
||||||
.add_import(import_to_add)
|
.add_import(import_to_add, self.ctx.completion.config.should_resolve_immediately())
|
||||||
.set_documentation(docs)
|
.set_documentation(docs)
|
||||||
.set_ref_match(ref_match)
|
.set_ref_match(ref_match)
|
||||||
.build();
|
.build();
|
||||||
|
|
|
@ -71,7 +71,7 @@ impl<'a> EnumVariantRender<'a> {
|
||||||
.kind(CompletionItemKind::EnumVariant)
|
.kind(CompletionItemKind::EnumVariant)
|
||||||
.set_documentation(self.variant.docs(self.ctx.db()))
|
.set_documentation(self.variant.docs(self.ctx.db()))
|
||||||
.set_deprecated(self.ctx.is_deprecated(self.variant))
|
.set_deprecated(self.ctx.is_deprecated(self.variant))
|
||||||
.add_import(import_to_add)
|
.add_import(import_to_add, self.ctx.completion.config.should_resolve_immediately())
|
||||||
.detail(self.detail());
|
.detail(self.detail());
|
||||||
|
|
||||||
if self.variant_kind == StructKind::Tuple {
|
if self.variant_kind == StructKind::Tuple {
|
||||||
|
|
|
@ -47,7 +47,7 @@ impl<'a> FunctionRender<'a> {
|
||||||
.set_deprecated(self.ctx.is_deprecated(self.func))
|
.set_deprecated(self.ctx.is_deprecated(self.func))
|
||||||
.detail(self.detail())
|
.detail(self.detail())
|
||||||
.add_call_parens(self.ctx.completion, self.name, params)
|
.add_call_parens(self.ctx.completion, self.name, params)
|
||||||
.add_import(import_to_add)
|
.add_import(import_to_add, self.ctx.completion.config.should_resolve_immediately())
|
||||||
.build()
|
.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,7 @@ impl<'a> MacroRender<'a> {
|
||||||
.kind(CompletionItemKind::Macro)
|
.kind(CompletionItemKind::Macro)
|
||||||
.set_documentation(self.docs.clone())
|
.set_documentation(self.docs.clone())
|
||||||
.set_deprecated(self.ctx.is_deprecated(self.macro_))
|
.set_deprecated(self.ctx.is_deprecated(self.macro_))
|
||||||
.add_import(import_to_add)
|
.add_import(import_to_add, self.ctx.completion.config.should_resolve_immediately())
|
||||||
.detail(self.detail());
|
.detail(self.detail());
|
||||||
|
|
||||||
let needs_bang = self.needs_bang();
|
let needs_bang = self.needs_bang();
|
||||||
|
|
|
@ -97,7 +97,7 @@ pub(crate) fn check_edit_with_config(
|
||||||
.unwrap_or_else(|| panic!("can't find {:?} completion in {:#?}", what, completions));
|
.unwrap_or_else(|| panic!("can't find {:?} completion in {:#?}", what, completions));
|
||||||
let mut actual = db.file_text(position.file_id).to_string();
|
let mut actual = db.file_text(position.file_id).to_string();
|
||||||
completion.text_edit().apply(&mut actual);
|
completion.text_edit().apply(&mut actual);
|
||||||
// TODO kb how to apply imports now?
|
// git how to apply imports now?
|
||||||
assert_eq_text!(&ra_fixture_after, &actual)
|
assert_eq_text!(&ra_fixture_after, &actual)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -623,7 +623,7 @@ pub(crate) fn handle_resolve_completion(
|
||||||
for supported_completion_resolve_cap in &snap.config.completion.resolve_capabilities {
|
for supported_completion_resolve_cap in &snap.config.completion.resolve_capabilities {
|
||||||
match supported_completion_resolve_cap {
|
match supported_completion_resolve_cap {
|
||||||
ide::CompletionResolveCapability::AdditionalTextEdits => {
|
ide::CompletionResolveCapability::AdditionalTextEdits => {
|
||||||
// TODO kb actually add all additional edits here?
|
// FIXME actually add all additional edits here?
|
||||||
if let Some(import_to_add) = server_completion_data.item.import_to_add() {
|
if let Some(import_to_add) = server_completion_data.item.import_to_add() {
|
||||||
append_import_edits(
|
append_import_edits(
|
||||||
&mut original_completion,
|
&mut original_completion,
|
||||||
|
@ -633,7 +633,7 @@ pub(crate) fn handle_resolve_completion(
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// TODO kb calculate the rest also?
|
// FIXME resolve the other capabilities also?
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue