Unnamed repository; edit this file 'description' to name the repository.
-rw-r--r--crates/ide_completion/src/lib.rs58
1 files changed, 27 insertions, 31 deletions
diff --git a/crates/ide_completion/src/lib.rs b/crates/ide_completion/src/lib.rs
index bbfdadafc7..647bbc8af5 100644
--- a/crates/ide_completion/src/lib.rs
+++ b/crates/ide_completion/src/lib.rs
@@ -15,11 +15,13 @@ use completions::flyimport::position_for_import;
use ide_db::{
base_db::FilePosition,
helpers::{
- import_assets::{LocatedImport, NameToImport},
- insert_use::ImportScope,
+ import_assets::NameToImport,
+ insert_use::{self, ImportScope},
+ mod_path_to_ast,
},
items_locator, RootDatabase,
};
+use syntax::algo;
use text_edit::TextEdit;
use crate::{completions::Completions, context::CompletionContext, item::CompletionKind};
@@ -177,41 +179,35 @@ pub fn resolve_completion_edits(
position: FilePosition,
imports: impl IntoIterator<Item = (String, String)>,
) -> Option<Vec<TextEdit>> {
+ let _p = profile::span("resolve_completion_edits");
let ctx = CompletionContext::new(db, position, config)?;
let position_for_import = position_for_import(&ctx, None)?;
let scope = ImportScope::find_insert_use_container_with_macros(position_for_import, &ctx.sema)?;
let current_module = ctx.sema.scope(position_for_import).module()?;
let current_crate = current_module.krate();
+ let new_ast = scope.clone_for_update();
+ let mut import_insert = TextEdit::builder();
- Some(
- imports
- .into_iter()
- .filter_map(|(full_import_path, imported_name)| {
- let (import_path, item_to_import) = items_locator::items_with_name(
- &ctx.sema,
- current_crate,
- NameToImport::Exact(imported_name),
- items_locator::AssocItemSearch::Include,
- Some(items_locator::DEFAULT_QUERY_SEARCH_LIMIT.inner()),
- )
- .filter_map(|candidate| {
- current_module
- .find_use_path_prefixed(db, candidate, config.insert_use.prefix_kind)
- .zip(Some(candidate))
- })
- .find(|(mod_path, _)| mod_path.to_string() == full_import_path)?;
- let import = LocatedImport::new(
- import_path.clone(),
- item_to_import,
- item_to_import,
- Some(import_path),
- );
-
- ImportEdit { import, scope: scope.clone() }
- .to_text_edit(config.insert_use)
- .map(|edit| edit)
+ // FIXME: lift out and make some tests here, this is ImportEdit::to_text_edit but changed to work with multiple edits
+ imports.into_iter().for_each(|(full_import_path, imported_name)| {
+ let items_with_name = items_locator::items_with_name(
+ &ctx.sema,
+ current_crate,
+ NameToImport::Exact(imported_name),
+ items_locator::AssocItemSearch::Include,
+ Some(items_locator::DEFAULT_QUERY_SEARCH_LIMIT.inner()),
+ );
+ let import = items_with_name
+ .filter_map(|candidate| {
+ current_module.find_use_path_prefixed(db, candidate, config.insert_use.prefix_kind)
})
- .collect(),
- )
+ .find(|mod_path| mod_path.to_string() == full_import_path);
+ if let Some(import_path) = import {
+ insert_use::insert_use(&new_ast, mod_path_to_ast(&import_path), &config.insert_use);
+ }
+ });
+
+ algo::diff(scope.as_syntax_node(), new_ast.as_syntax_node()).into_text_edit(&mut import_insert);
+ Some(vec![import_insert.finish()])
}