aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_analysis/src/completion.rs13
-rw-r--r--crates/ra_analysis/src/completion/completion_item.rs34
-rw-r--r--crates/ra_analysis/src/completion/reference_completion.rs30
-rw-r--r--crates/ra_analysis/src/lib.rs2
-rw-r--r--crates/ra_lsp_server/src/main_loop/handlers.rs22
5 files changed, 65 insertions, 36 deletions
diff --git a/crates/ra_analysis/src/completion.rs b/crates/ra_analysis/src/completion.rs
index fd7b78c2a..222b6854c 100644
--- a/crates/ra_analysis/src/completion.rs
+++ b/crates/ra_analysis/src/completion.rs
@@ -18,7 +18,7 @@ use crate::{
18 Cancelable, FilePosition 18 Cancelable, FilePosition
19}; 19};
20 20
21pub use crate::completion::completion_item::CompletionItem; 21pub use crate::completion::completion_item::{CompletionItem, InsertText};
22 22
23pub(crate) fn completions( 23pub(crate) fn completions(
24 db: &db::RootDatabase, 24 db: &db::RootDatabase,
@@ -109,13 +109,20 @@ mod tests {
109 109
110 use super::*; 110 use super::*;
111 111
112 fn is_snippet(completion_item: &CompletionItem) -> bool {
113 match completion_item.insert_text() {
114 InsertText::Snippet { .. } => true,
115 _ => false,
116 }
117 }
118
112 fn check_scope_completion(code: &str, expected_completions: &str) { 119 fn check_scope_completion(code: &str, expected_completions: &str) {
113 let (analysis, position) = single_file_with_position(code); 120 let (analysis, position) = single_file_with_position(code);
114 let completions = completions(&analysis.imp.db, position) 121 let completions = completions(&analysis.imp.db, position)
115 .unwrap() 122 .unwrap()
116 .unwrap() 123 .unwrap()
117 .into_iter() 124 .into_iter()
118 .filter(|c| c.snippet.is_none()) 125 .filter(|c| !is_snippet(c))
119 .collect::<Vec<_>>(); 126 .collect::<Vec<_>>();
120 assert_eq_dbg(expected_completions, &completions); 127 assert_eq_dbg(expected_completions, &completions);
121 } 128 }
@@ -126,7 +133,7 @@ mod tests {
126 .unwrap() 133 .unwrap()
127 .unwrap() 134 .unwrap()
128 .into_iter() 135 .into_iter()
129 .filter(|c| c.snippet.is_some()) 136 .filter(is_snippet)
130 .collect::<Vec<_>>(); 137 .collect::<Vec<_>>();
131 assert_eq_dbg(expected_completions, &completions); 138 assert_eq_dbg(expected_completions, &completions);
132 } 139 }
diff --git a/crates/ra_analysis/src/completion/completion_item.rs b/crates/ra_analysis/src/completion/completion_item.rs
index 7edb86436..4280976e7 100644
--- a/crates/ra_analysis/src/completion/completion_item.rs
+++ b/crates/ra_analysis/src/completion/completion_item.rs
@@ -1,11 +1,13 @@
1#[derive(Debug)] 1#[derive(Debug)]
2pub struct CompletionItem { 2pub struct CompletionItem {
3 /// What user sees in pop-up in the UI. 3 label: String,
4 pub label: String, 4 lookup: Option<String>,
5 /// What string is used for filtering, defaults to label. 5 snippet: Option<String>,
6 pub lookup: Option<String>, 6}
7 /// What is inserted, defaults to label. 7
8 pub snippet: Option<String>, 8pub enum InsertText {
9 PlainText { text: String },
10 Snippet { text: String },
9} 11}
10 12
11impl CompletionItem { 13impl CompletionItem {
@@ -17,6 +19,26 @@ impl CompletionItem {
17 snippet: None, 19 snippet: None,
18 } 20 }
19 } 21 }
22 /// What user sees in pop-up in the UI.
23 pub fn label(&self) -> &str {
24 &self.label
25 }
26 /// What string is used for filtering.
27 pub fn lookup(&self) -> &str {
28 self.lookup
29 .as_ref()
30 .map(|it| it.as_str())
31 .unwrap_or(self.label())
32 }
33 /// What is inserted.
34 pub fn insert_text(&self) -> InsertText {
35 match &self.snippet {
36 None => InsertText::PlainText {
37 text: self.label.clone(),
38 },
39 Some(it) => InsertText::Snippet { text: it.clone() },
40 }
41 }
20} 42}
21 43
22#[must_use] 44#[must_use]
diff --git a/crates/ra_analysis/src/completion/reference_completion.rs b/crates/ra_analysis/src/completion/reference_completion.rs
index 23052295c..f9f01a642 100644
--- a/crates/ra_analysis/src/completion/reference_completion.rs
+++ b/crates/ra_analysis/src/completion/reference_completion.rs
@@ -39,25 +39,19 @@ pub(super) fn completions(
39 } 39 }
40 40
41 let module_scope = module.scope(db)?; 41 let module_scope = module.scope(db)?;
42 acc.extend( 42 module_scope
43 module_scope 43 .entries()
44 .entries() 44 .filter(|(_name, res)| {
45 .filter(|(_name, res)| { 45 // Don't expose this item
46 // Don't expose this item 46 match res.import {
47 match res.import { 47 None => true,
48 None => true, 48 Some(import) => {
49 Some(import) => { 49 let range = import.range(db, module.source().file_id());
50 let range = import.range(db, module.source().file_id()); 50 !range.is_subrange(&name_ref.syntax().range())
51 !range.is_subrange(&name_ref.syntax().range())
52 }
53 } 51 }
54 }) 52 }
55 .map(|(name, _res)| CompletionItem { 53 })
56 label: name.to_string(), 54 .for_each(|(name, _res)| CompletionItem::new(name.to_string()).add_to(acc));
57 lookup: None,
58 snippet: None,
59 }),
60 );
61 } 55 }
62 NameRefKind::Path(path) => complete_path(acc, db, module, path)?, 56 NameRefKind::Path(path) => complete_path(acc, db, module, path)?,
63 NameRefKind::BareIdentInMod => { 57 NameRefKind::BareIdentInMod => {
diff --git a/crates/ra_analysis/src/lib.rs b/crates/ra_analysis/src/lib.rs
index c7e7dc1c0..1c8aa308b 100644
--- a/crates/ra_analysis/src/lib.rs
+++ b/crates/ra_analysis/src/lib.rs
@@ -30,7 +30,7 @@ use crate::{
30}; 30};
31 31
32pub use crate::{ 32pub use crate::{
33 completion::CompletionItem, 33 completion::{CompletionItem, InsertText},
34}; 34};
35pub use ra_editor::{ 35pub use ra_editor::{
36 FileSymbol, Fold, FoldKind, HighlightedRange, LineIndex, Runnable, RunnableKind, StructureNode, 36 FileSymbol, Fold, FoldKind, HighlightedRange, LineIndex, Runnable, RunnableKind, StructureNode,
diff --git a/crates/ra_lsp_server/src/main_loop/handlers.rs b/crates/ra_lsp_server/src/main_loop/handlers.rs
index 1751d7fa8..2dfeb061a 100644
--- a/crates/ra_lsp_server/src/main_loop/handlers.rs
+++ b/crates/ra_lsp_server/src/main_loop/handlers.rs
@@ -8,7 +8,7 @@ use languageserver_types::{
8 PrepareRenameResponse, RenameParams, SymbolInformation, TextDocumentIdentifier, TextEdit, 8 PrepareRenameResponse, RenameParams, SymbolInformation, TextDocumentIdentifier, TextEdit,
9 WorkspaceEdit, ParameterInformation, ParameterLabel, SignatureInformation, Hover, HoverContents, 9 WorkspaceEdit, ParameterInformation, ParameterLabel, SignatureInformation, Hover, HoverContents,
10}; 10};
11use ra_analysis::{FileId, FoldKind, Query, RunnableKind, FilePosition}; 11use ra_analysis::{FileId, FoldKind, Query, RunnableKind, FilePosition, InsertText};
12use ra_syntax::{TextUnit, text_utils::intersect}; 12use ra_syntax::{TextUnit, text_utils::intersect};
13use ra_text_edit::text_utils::contains_offset_nonstrict; 13use ra_text_edit::text_utils::contains_offset_nonstrict;
14use rustc_hash::FxHashMap; 14use rustc_hash::FxHashMap;
@@ -423,15 +423,21 @@ pub fn handle_completion(
423 .into_iter() 423 .into_iter()
424 .map(|item| { 424 .map(|item| {
425 let mut res = CompletionItem { 425 let mut res = CompletionItem {
426 label: item.label, 426 label: item.label().to_string(),
427 filter_text: item.lookup, 427 filter_text: Some(item.lookup().to_string()),
428 ..Default::default() 428 ..Default::default()
429 }; 429 };
430 if let Some(snip) = item.snippet { 430 match item.insert_text() {
431 res.insert_text = Some(snip); 431 InsertText::PlainText { text } => {
432 res.insert_text_format = Some(InsertTextFormat::Snippet); 432 res.insert_text = Some(text);
433 res.kind = Some(CompletionItemKind::Keyword); 433 res.insert_text_format = Some(InsertTextFormat::PlainText);
434 }; 434 }
435 InsertText::Snippet { text } => {
436 res.insert_text = Some(text);
437 res.insert_text_format = Some(InsertTextFormat::Snippet);
438 res.kind = Some(CompletionItemKind::Keyword);
439 }
440 }
435 res 441 res
436 }) 442 })
437 .collect(); 443 .collect();