22
33use std:: fmt;
44
5- use hir:: { Documentation , Mutability } ;
6- use syntax:: TextRange ;
5+ use assists:: utils:: { insert_use, mod_path_to_ast, ImportScope , MergeBehaviour } ;
6+ use hir:: { Documentation , ModPath , Mutability } ;
7+ use syntax:: { algo, TextRange } ;
78use text_edit:: TextEdit ;
89
910use crate :: config:: SnippetCap ;
@@ -200,25 +201,7 @@ impl CompletionItem {
200201 trigger_call_info : None ,
201202 score : None ,
202203 ref_match : None ,
203- }
204- }
205-
206- pub ( crate ) fn into_builder ( self ) -> Builder {
207- Builder {
208- source_range : self . source_range ,
209- completion_kind : self . completion_kind ,
210- label : self . label ,
211- insert_text : None ,
212- insert_text_format : self . insert_text_format ,
213- detail : self . detail ,
214- documentation : self . documentation ,
215- lookup : self . lookup ,
216- kind : self . kind ,
217- text_edit : Some ( self . text_edit ) ,
218- deprecated : Some ( self . deprecated ) ,
219- trigger_call_info : Some ( self . trigger_call_info ) ,
220- score : self . score ,
221- ref_match : self . ref_match ,
204+ import_data : None ,
222205 }
223206 }
224207
@@ -278,6 +261,7 @@ impl CompletionItem {
278261pub ( crate ) struct Builder {
279262 source_range : TextRange ,
280263 completion_kind : CompletionKind ,
264+ import_data : Option < ( ModPath , ImportScope , Option < MergeBehaviour > ) > ,
281265 label : String ,
282266 insert_text : Option < String > ,
283267 insert_text_format : InsertTextFormat ,
@@ -294,23 +278,50 @@ pub(crate) struct Builder {
294278
295279impl Builder {
296280 pub ( crate ) fn build ( self ) -> CompletionItem {
297- let label = self . label ;
298- let text_edit = match self . text_edit {
281+ let mut label = self . label ;
282+ let mut lookup = self . lookup ;
283+ let mut insert_text = self . insert_text ;
284+ let mut text_edits = TextEdit :: builder ( ) ;
285+
286+ if let Some ( ( import_path, import_scope, merge_behaviour) ) = self . import_data {
287+ let import = mod_path_to_ast ( & import_path) ;
288+ let mut import_path_without_last_segment = import_path;
289+ let _ = import_path_without_last_segment. segments . pop ( ) ;
290+
291+ if !import_path_without_last_segment. segments . is_empty ( ) {
292+ if lookup. is_none ( ) {
293+ lookup = Some ( label. clone ( ) ) ;
294+ }
295+ if insert_text. is_none ( ) {
296+ insert_text = Some ( label. clone ( ) ) ;
297+ }
298+ label = format ! ( "{}::{}" , import_path_without_last_segment, label) ;
299+ }
300+
301+ let rewriter = insert_use ( & import_scope, import, merge_behaviour) ;
302+ if let Some ( old_ast) = rewriter. rewrite_root ( ) {
303+ algo:: diff ( & old_ast, & rewriter. rewrite ( & old_ast) ) . into_text_edit ( & mut text_edits) ;
304+ }
305+ }
306+
307+ let original_edit = match self . text_edit {
299308 Some ( it) => it,
300- None => TextEdit :: replace (
301- self . source_range ,
302- self . insert_text . unwrap_or_else ( || label. clone ( ) ) ,
303- ) ,
309+ None => {
310+ TextEdit :: replace ( self . source_range , insert_text. unwrap_or_else ( || label. clone ( ) ) )
311+ }
304312 } ;
305313
314+ let mut resulting_edit = text_edits. finish ( ) ;
315+ resulting_edit. union ( original_edit) . expect ( "Failed to unite text edits" ) ;
316+
306317 CompletionItem {
307318 source_range : self . source_range ,
308319 label,
309320 insert_text_format : self . insert_text_format ,
310- text_edit,
321+ text_edit : resulting_edit ,
311322 detail : self . detail ,
312323 documentation : self . documentation ,
313- lookup : self . lookup ,
324+ lookup,
314325 kind : self . kind ,
315326 completion_kind : self . completion_kind ,
316327 deprecated : self . deprecated . unwrap_or ( false ) ,
@@ -379,6 +390,13 @@ impl Builder {
379390 self . trigger_call_info = Some ( true ) ;
380391 self
381392 }
393+ pub ( crate ) fn import_data (
394+ mut self ,
395+ import_data : Option < ( ModPath , ImportScope , Option < MergeBehaviour > ) > ,
396+ ) -> Builder {
397+ self . import_data = import_data;
398+ self
399+ }
382400 pub ( crate ) fn set_ref_match (
383401 mut self ,
384402 ref_match : Option < ( Mutability , CompletionScore ) > ,
0 commit comments