aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbors[bot] <bors[bot]@users.noreply.github.com>2018-12-21 23:28:47 +0000
committerbors[bot] <bors[bot]@users.noreply.github.com>2018-12-21 23:28:47 +0000
commit4e4ca27eabac6a9c97dc07baf9a067efdfc63384 (patch)
tree83c75bdefa688a220054bf671ffe1692887d6dd4
parente4d0930d9c6478f7aa069401fb7e28ab7c80fd14 (diff)
parentea763c73b8d89edbf716805c62cf31b00e2e1a4f (diff)
Merge #319
319: Completion icons r=matklad a=matklad Co-authored-by: Aleksey Kladov <[email protected]>
-rw-r--r--crates/gen_lsp_server/Cargo.toml2
-rw-r--r--crates/gen_lsp_server/src/msg.rs2
-rw-r--r--crates/ra_analysis/src/completion.rs2
-rw-r--r--crates/ra_analysis/src/completion/complete_fn_param.rs3
-rw-r--r--crates/ra_analysis/src/completion/complete_keyword.rs16
-rw-r--r--crates/ra_analysis/src/completion/complete_path.rs8
-rw-r--r--crates/ra_analysis/src/completion/complete_scope.rs14
-rw-r--r--crates/ra_analysis/src/completion/complete_snippet.rs37
-rw-r--r--crates/ra_analysis/src/completion/completion_item.rs54
-rw-r--r--crates/ra_analysis/src/lib.rs2
-rw-r--r--crates/ra_hir/src/function/scope.rs3
-rw-r--r--crates/ra_hir/src/lib.rs2
-rw-r--r--crates/ra_hir/src/module.rs2
-rw-r--r--crates/ra_hir/src/module/nameres.rs2
-rw-r--r--crates/ra_lsp_server/src/conv.rs44
-rw-r--r--crates/ra_lsp_server/src/main_loop/handlers.rs29
16 files changed, 136 insertions, 86 deletions
diff --git a/crates/gen_lsp_server/Cargo.toml b/crates/gen_lsp_server/Cargo.toml
index 5f90d39d6..9776a82e3 100644
--- a/crates/gen_lsp_server/Cargo.toml
+++ b/crates/gen_lsp_server/Cargo.toml
@@ -12,5 +12,5 @@ languageserver-types = "0.53.0"
12log = "0.4.3" 12log = "0.4.3"
13failure = "0.1.2" 13failure = "0.1.2"
14serde_json = "1.0.24" 14serde_json = "1.0.24"
15serde = "1.0.71" 15serde = { version = "1.0.71", features = ["derive"] }
16crossbeam-channel = "0.2.4" 16crossbeam-channel = "0.2.4"
diff --git a/crates/gen_lsp_server/src/msg.rs b/crates/gen_lsp_server/src/msg.rs
index ef6358cb1..af901d0d2 100644
--- a/crates/gen_lsp_server/src/msg.rs
+++ b/crates/gen_lsp_server/src/msg.rs
@@ -7,7 +7,7 @@ use failure::{bail, format_err};
7 7
8use crate::Result; 8use crate::Result;
9 9
10#[derive(Debug, Serialize, Deserialize, Clone)] 10#[derive(Serialize, Deserialize, Debug, Clone)]
11#[serde(untagged)] 11#[serde(untagged)]
12pub enum RawMessage { 12pub enum RawMessage {
13 Request(RawRequest), 13 Request(RawRequest),
diff --git a/crates/ra_analysis/src/completion.rs b/crates/ra_analysis/src/completion.rs
index 2d61a3aef..d742d6295 100644
--- a/crates/ra_analysis/src/completion.rs
+++ b/crates/ra_analysis/src/completion.rs
@@ -18,7 +18,7 @@ use crate::{
18 }, 18 },
19}; 19};
20 20
21pub use crate::completion::completion_item::{CompletionItem, InsertText}; 21pub use crate::completion::completion_item::{CompletionItem, InsertText, CompletionItemKind};
22 22
23/// Main entry point for copmletion. We run comletion as a two-phase process. 23/// Main entry point for copmletion. We run comletion as a two-phase process.
24/// 24///
diff --git a/crates/ra_analysis/src/completion/complete_fn_param.rs b/crates/ra_analysis/src/completion/complete_fn_param.rs
index 6a6213e67..bb5fdfda0 100644
--- a/crates/ra_analysis/src/completion/complete_fn_param.rs
+++ b/crates/ra_analysis/src/completion/complete_fn_param.rs
@@ -34,9 +34,8 @@ pub(super) fn complete_fn_param(acc: &mut Completions, ctx: &CompletionContext)
34 } 34 }
35 }) 35 })
36 .for_each(|(label, lookup)| { 36 .for_each(|(label, lookup)| {
37 CompletionItem::new(label) 37 CompletionItem::new(CompletionKind::Magic, label)
38 .lookup_by(lookup) 38 .lookup_by(lookup)
39 .kind(CompletionKind::Magic)
40 .add_to(acc) 39 .add_to(acc)
41 }); 40 });
42 41
diff --git a/crates/ra_analysis/src/completion/complete_keyword.rs b/crates/ra_analysis/src/completion/complete_keyword.rs
index dead15bb6..5427fcb11 100644
--- a/crates/ra_analysis/src/completion/complete_keyword.rs
+++ b/crates/ra_analysis/src/completion/complete_keyword.rs
@@ -5,7 +5,14 @@ use ra_syntax::{
5 SyntaxKind::*, SyntaxNodeRef, 5 SyntaxKind::*, SyntaxNodeRef,
6}; 6};
7 7
8use crate::completion::{CompletionContext, CompletionItem, Completions, CompletionKind::*}; 8use crate::completion::{CompletionContext, CompletionItem, Completions, CompletionKind, CompletionItemKind};
9
10fn keyword(kw: &str, snippet: &str) -> CompletionItem {
11 CompletionItem::new(CompletionKind::Keyword, kw)
12 .kind(CompletionItemKind::Keyword)
13 .snippet(snippet)
14 .build()
15}
9 16
10pub(super) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionContext) { 17pub(super) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionContext) {
11 if !ctx.is_trivial_path { 18 if !ctx.is_trivial_path {
@@ -60,13 +67,6 @@ fn complete_return(fn_def: ast::FnDef, is_stmt: bool) -> Option<CompletionItem>
60 Some(keyword("return", snip)) 67 Some(keyword("return", snip))
61} 68}
62 69
63fn keyword(kw: &str, snippet: &str) -> CompletionItem {
64 CompletionItem::new(kw)
65 .kind(Keyword)
66 .snippet(snippet)
67 .build()
68}
69
70#[cfg(test)] 70#[cfg(test)]
71mod tests { 71mod tests {
72 use crate::completion::{CompletionKind, check_completion}; 72 use crate::completion::{CompletionKind, check_completion};
diff --git a/crates/ra_analysis/src/completion/complete_path.rs b/crates/ra_analysis/src/completion/complete_path.rs
index 5fc24af72..ad4d68a33 100644
--- a/crates/ra_analysis/src/completion/complete_path.rs
+++ b/crates/ra_analysis/src/completion/complete_path.rs
@@ -1,6 +1,6 @@
1use crate::{ 1use crate::{
2 Cancelable, 2 Cancelable,
3 completion::{CompletionItem, Completions, CompletionKind::*, CompletionContext}, 3 completion::{CompletionItem, Completions, CompletionKind, CompletionContext},
4}; 4};
5 5
6pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) -> Cancelable<()> { 6pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) -> Cancelable<()> {
@@ -17,9 +17,9 @@ pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) -> C
17 _ => return Ok(()), 17 _ => return Ok(()),
18 }; 18 };
19 let module_scope = target_module.scope(ctx.db)?; 19 let module_scope = target_module.scope(ctx.db)?;
20 module_scope.entries().for_each(|(name, _res)| { 20 module_scope.entries().for_each(|(name, res)| {
21 CompletionItem::new(name.to_string()) 21 CompletionItem::new(CompletionKind::Reference, name.to_string())
22 .kind(Reference) 22 .from_resolution(ctx.db, res)
23 .add_to(acc) 23 .add_to(acc)
24 }); 24 });
25 Ok(()) 25 Ok(())
diff --git a/crates/ra_analysis/src/completion/complete_scope.rs b/crates/ra_analysis/src/completion/complete_scope.rs
index d07c0e46d..82610d63f 100644
--- a/crates/ra_analysis/src/completion/complete_scope.rs
+++ b/crates/ra_analysis/src/completion/complete_scope.rs
@@ -3,7 +3,7 @@ use ra_syntax::TextUnit;
3 3
4use crate::{ 4use crate::{
5 Cancelable, 5 Cancelable,
6 completion::{CompletionItem, Completions, CompletionKind::*, CompletionContext}, 6 completion::{CompletionItem, CompletionItemKind, Completions, CompletionKind, CompletionContext},
7}; 7};
8 8
9pub(super) fn complete_scope(acc: &mut Completions, ctx: &CompletionContext) -> Cancelable<()> { 9pub(super) fn complete_scope(acc: &mut Completions, ctx: &CompletionContext) -> Cancelable<()> {
@@ -29,9 +29,9 @@ pub(super) fn complete_scope(acc: &mut Completions, ctx: &CompletionContext) ->
29 } 29 }
30 } 30 }
31 }) 31 })
32 .for_each(|(name, _res)| { 32 .for_each(|(name, res)| {
33 CompletionItem::new(name.to_string()) 33 CompletionItem::new(CompletionKind::Reference, name.to_string())
34 .kind(Reference) 34 .from_resolution(ctx.db, res)
35 .add_to(acc) 35 .add_to(acc)
36 }); 36 });
37 } 37 }
@@ -46,12 +46,12 @@ fn complete_fn(acc: &mut Completions, scopes: &hir::FnScopes, offset: TextUnit)
46 .flat_map(|scope| scopes.entries(scope).iter()) 46 .flat_map(|scope| scopes.entries(scope).iter())
47 .filter(|entry| shadowed.insert(entry.name())) 47 .filter(|entry| shadowed.insert(entry.name()))
48 .for_each(|entry| { 48 .for_each(|entry| {
49 CompletionItem::new(entry.name().to_string()) 49 CompletionItem::new(CompletionKind::Reference, entry.name().to_string())
50 .kind(Reference) 50 .kind(CompletionItemKind::Binding)
51 .add_to(acc) 51 .add_to(acc)
52 }); 52 });
53 if scopes.self_param.is_some() { 53 if scopes.self_param.is_some() {
54 CompletionItem::new("self").kind(Reference).add_to(acc); 54 CompletionItem::new(CompletionKind::Reference, "self").add_to(acc);
55 } 55 }
56} 56}
57 57
diff --git a/crates/ra_analysis/src/completion/complete_snippet.rs b/crates/ra_analysis/src/completion/complete_snippet.rs
index ccd68832b..fb9da0a4f 100644
--- a/crates/ra_analysis/src/completion/complete_snippet.rs
+++ b/crates/ra_analysis/src/completion/complete_snippet.rs
@@ -1,38 +1,35 @@
1use crate::completion::{CompletionItem, Completions, CompletionKind::*, CompletionContext}; 1use crate::completion::{CompletionItem, Completions, CompletionKind, CompletionItemKind, CompletionContext, completion_item::Builder};
2
3fn snippet(label: &str, snippet: &str) -> Builder {
4 CompletionItem::new(CompletionKind::Snippet, label)
5 .snippet(snippet)
6 .kind(CompletionItemKind::Snippet)
7}
2 8
3pub(super) fn complete_expr_snippet(acc: &mut Completions, ctx: &CompletionContext) { 9pub(super) fn complete_expr_snippet(acc: &mut Completions, ctx: &CompletionContext) {
4 if !(ctx.is_trivial_path && ctx.enclosing_fn.is_some()) { 10 if !(ctx.is_trivial_path && ctx.enclosing_fn.is_some()) {
5 return; 11 return;
6 } 12 }
7 CompletionItem::new("pd") 13 snippet("pd", "eprintln!(\"$0 = {:?}\", $0);").add_to(acc);
8 .snippet("eprintln!(\"$0 = {:?}\", $0);") 14 snippet("ppd", "eprintln!(\"$0 = {:#?}\", $0);").add_to(acc);
9 .kind(Snippet)
10 .add_to(acc);
11 CompletionItem::new("ppd")
12 .snippet("eprintln!(\"$0 = {:#?}\", $0);")
13 .kind(Snippet)
14 .add_to(acc);
15} 15}
16 16
17pub(super) fn complete_item_snippet(acc: &mut Completions, ctx: &CompletionContext) { 17pub(super) fn complete_item_snippet(acc: &mut Completions, ctx: &CompletionContext) {
18 if !ctx.is_new_item { 18 if !ctx.is_new_item {
19 return; 19 return;
20 } 20 }
21 CompletionItem::new("Test function") 21 snippet(
22 .lookup_by("tfn") 22 "Test function",
23 .snippet( 23 "\
24 "\
25#[test] 24#[test]
26fn ${1:feature}() { 25fn ${1:feature}() {
27 $0 26 $0
28}", 27}",
29 ) 28 )
30 .kind(Snippet) 29 .lookup_by("tfn")
31 .add_to(acc); 30 .add_to(acc);
32 CompletionItem::new("pub(crate)") 31
33 .snippet("pub(crate) $0") 32 snippet("pub(crate)", "pub(crate) $0").add_to(acc);
34 .kind(Snippet)
35 .add_to(acc);
36} 33}
37 34
38#[cfg(test)] 35#[cfg(test)]
diff --git a/crates/ra_analysis/src/completion/completion_item.rs b/crates/ra_analysis/src/completion/completion_item.rs
index d5d751759..911f08468 100644
--- a/crates/ra_analysis/src/completion/completion_item.rs
+++ b/crates/ra_analysis/src/completion/completion_item.rs
@@ -1,13 +1,17 @@
1use crate::db;
2
1/// `CompletionItem` describes a single completion variant in the editor pop-up. 3/// `CompletionItem` describes a single completion variant in the editor pop-up.
2/// It is basically a POD with various properties. To construct a 4/// It is basically a POD with various properties. To construct a
3/// `CompletionItem`, use `new` method and the `Builder` struct. 5/// `CompletionItem`, use `new` method and the `Builder` struct.
4#[derive(Debug)] 6#[derive(Debug)]
5pub struct CompletionItem { 7pub struct CompletionItem {
8 /// Used only internally in tests, to check only specific kind of
9 /// completion.
10 completion_kind: CompletionKind,
6 label: String, 11 label: String,
7 lookup: Option<String>, 12 lookup: Option<String>,
8 snippet: Option<String>, 13 snippet: Option<String>,
9 /// Used only internally in test, to check only specific kind of completion. 14 kind: Option<CompletionItemKind>,
10 kind: CompletionKind,
11} 15}
12 16
13pub enum InsertText { 17pub enum InsertText {
@@ -15,6 +19,15 @@ pub enum InsertText {
15 Snippet { text: String }, 19 Snippet { text: String },
16} 20}
17 21
22#[derive(Debug, Clone, Copy, PartialEq, Eq)]
23pub enum CompletionItemKind {
24 Snippet,
25 Keyword,
26 Module,
27 Function,
28 Binding,
29}
30
18#[derive(Debug, PartialEq, Eq)] 31#[derive(Debug, PartialEq, Eq)]
19pub(crate) enum CompletionKind { 32pub(crate) enum CompletionKind {
20 /// Parser-based keyword completion. 33 /// Parser-based keyword completion.
@@ -24,17 +37,17 @@ pub(crate) enum CompletionKind {
24 /// "Secret sauce" completions. 37 /// "Secret sauce" completions.
25 Magic, 38 Magic,
26 Snippet, 39 Snippet,
27 Unspecified,
28} 40}
29 41
30impl CompletionItem { 42impl CompletionItem {
31 pub(crate) fn new(label: impl Into<String>) -> Builder { 43 pub(crate) fn new(completion_kind: CompletionKind, label: impl Into<String>) -> Builder {
32 let label = label.into(); 44 let label = label.into();
33 Builder { 45 Builder {
46 completion_kind,
34 label, 47 label,
35 lookup: None, 48 lookup: None,
36 snippet: None, 49 snippet: None,
37 kind: CompletionKind::Unspecified, 50 kind: None,
38 } 51 }
39 } 52 }
40 /// What user sees in pop-up in the UI. 53 /// What user sees in pop-up in the UI.
@@ -57,15 +70,20 @@ impl CompletionItem {
57 Some(it) => InsertText::Snippet { text: it.clone() }, 70 Some(it) => InsertText::Snippet { text: it.clone() },
58 } 71 }
59 } 72 }
73
74 pub fn kind(&self) -> Option<CompletionItemKind> {
75 self.kind
76 }
60} 77}
61 78
62/// A helper to make `CompletionItem`s. 79/// A helper to make `CompletionItem`s.
63#[must_use] 80#[must_use]
64pub(crate) struct Builder { 81pub(crate) struct Builder {
82 completion_kind: CompletionKind,
65 label: String, 83 label: String,
66 lookup: Option<String>, 84 lookup: Option<String>,
67 snippet: Option<String>, 85 snippet: Option<String>,
68 kind: CompletionKind, 86 kind: Option<CompletionItemKind>,
69} 87}
70 88
71impl Builder { 89impl Builder {
@@ -79,6 +97,7 @@ impl Builder {
79 lookup: self.lookup, 97 lookup: self.lookup,
80 snippet: self.snippet, 98 snippet: self.snippet,
81 kind: self.kind, 99 kind: self.kind,
100 completion_kind: self.completion_kind,
82 } 101 }
83 } 102 }
84 pub(crate) fn lookup_by(mut self, lookup: impl Into<String>) -> Builder { 103 pub(crate) fn lookup_by(mut self, lookup: impl Into<String>) -> Builder {
@@ -89,8 +108,25 @@ impl Builder {
89 self.snippet = Some(snippet.into()); 108 self.snippet = Some(snippet.into());
90 self 109 self
91 } 110 }
92 pub(crate) fn kind(mut self, kind: CompletionKind) -> Builder { 111 pub(crate) fn kind(mut self, kind: CompletionItemKind) -> Builder {
93 self.kind = kind; 112 self.kind = Some(kind);
113 self
114 }
115 pub(crate) fn from_resolution(
116 mut self,
117 db: &db::RootDatabase,
118 resolution: &hir::Resolution,
119 ) -> Builder {
120 if let Some(def_id) = resolution.def_id {
121 if let Ok(def) = def_id.resolve(db) {
122 let kind = match def {
123 hir::Def::Module(..) => CompletionItemKind::Module,
124 hir::Def::Function(..) => CompletionItemKind::Function,
125 _ => return self,
126 };
127 self.kind = Some(kind);
128 }
129 }
94 self 130 self
95 } 131 }
96} 132}
@@ -154,7 +190,7 @@ impl Completions {
154 fn debug_render(&self, kind: CompletionKind) -> String { 190 fn debug_render(&self, kind: CompletionKind) -> String {
155 let mut res = String::new(); 191 let mut res = String::new();
156 for c in self.buf.iter() { 192 for c in self.buf.iter() {
157 if c.kind == kind { 193 if c.completion_kind == kind {
158 if let Some(lookup) = &c.lookup { 194 if let Some(lookup) = &c.lookup {
159 res.push_str(lookup); 195 res.push_str(lookup);
160 res.push_str(&format!(" {:?}", c.label)); 196 res.push_str(&format!(" {:?}", c.label));
diff --git a/crates/ra_analysis/src/lib.rs b/crates/ra_analysis/src/lib.rs
index b2f4cd228..6fd157880 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, InsertText}, 33 completion::{CompletionItem, CompletionItemKind, 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_hir/src/function/scope.rs b/crates/ra_hir/src/function/scope.rs
index 9f1aa1ef2..77be25f1a 100644
--- a/crates/ra_hir/src/function/scope.rs
+++ b/crates/ra_hir/src/function/scope.rs
@@ -95,7 +95,7 @@ impl FnScopes {
95 r1.start().cmp(&r2.start()) 95 r1.start().cmp(&r2.start())
96 } 96 }
97 }) 97 })
98 .map(|(ptr, scope)| *scope) 98 .map(|(_ptr, scope)| *scope)
99 .unwrap_or(original_scope) 99 .unwrap_or(original_scope)
100 } 100 }
101 101
@@ -209,7 +209,6 @@ fn compute_block_scopes(block: ast::Block, scopes: &mut FnScopes, mut scope: Sco
209 } 209 }
210 } 210 }
211 if let Some(expr) = block.expr() { 211 if let Some(expr) = block.expr() {
212 eprintln!("{:?}", expr);
213 scopes.set_scope(expr.syntax(), scope); 212 scopes.set_scope(expr.syntax(), scope);
214 compute_expr_scopes(expr, scopes, scope); 213 compute_expr_scopes(expr, scopes, scope);
215 } 214 }
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs
index 5941a9ea3..f56214b47 100644
--- a/crates/ra_hir/src/lib.rs
+++ b/crates/ra_hir/src/lib.rs
@@ -39,7 +39,7 @@ use crate::{
39pub use self::{ 39pub use self::{
40 path::{Path, PathKind}, 40 path::{Path, PathKind},
41 krate::Crate, 41 krate::Crate,
42 module::{Module, ModuleId, Problem, nameres::ItemMap}, 42 module::{Module, ModuleId, Problem, nameres::ItemMap, ModuleScope, Resolution},
43 function::{Function, FnScopes}, 43 function::{Function, FnScopes},
44}; 44};
45 45
diff --git a/crates/ra_hir/src/module.rs b/crates/ra_hir/src/module.rs
index d5866f6ef..cd31e8cfe 100644
--- a/crates/ra_hir/src/module.rs
+++ b/crates/ra_hir/src/module.rs
@@ -16,7 +16,7 @@ use crate::{
16 arena::{Arena, Id}, 16 arena::{Arena, Id},
17}; 17};
18 18
19pub use self::nameres::ModuleScope; 19pub use self::nameres::{ModuleScope, Resolution};
20 20
21/// `Module` is API entry point to get all the information 21/// `Module` is API entry point to get all the information
22/// about a particular module. 22/// about a particular module.
diff --git a/crates/ra_hir/src/module/nameres.rs b/crates/ra_hir/src/module/nameres.rs
index f44abc730..39e891cda 100644
--- a/crates/ra_hir/src/module/nameres.rs
+++ b/crates/ra_hir/src/module/nameres.rs
@@ -49,7 +49,7 @@ pub struct ModuleScope {
49} 49}
50 50
51impl ModuleScope { 51impl ModuleScope {
52 pub fn entries<'a>(&'a self) -> impl Iterator<Item = (&'a SmolStr, &Resolution)> + 'a { 52 pub fn entries<'a>(&'a self) -> impl Iterator<Item = (&'a SmolStr, &'a Resolution)> + 'a {
53 self.items.iter() 53 self.items.iter()
54 } 54 }
55 pub fn get(&self, name: &SmolStr) -> Option<&Resolution> { 55 pub fn get(&self, name: &SmolStr) -> Option<&Resolution> {
diff --git a/crates/ra_lsp_server/src/conv.rs b/crates/ra_lsp_server/src/conv.rs
index 218ded4ee..051f1f995 100644
--- a/crates/ra_lsp_server/src/conv.rs
+++ b/crates/ra_lsp_server/src/conv.rs
@@ -1,8 +1,8 @@
1use languageserver_types::{ 1use languageserver_types::{
2 self, Location, Position, Range, SymbolKind, TextDocumentEdit, TextDocumentIdentifier, 2 self, Location, Position, Range, SymbolKind, TextDocumentEdit, TextDocumentIdentifier,
3 TextDocumentItem, TextDocumentPositionParams, Url, VersionedTextDocumentIdentifier, 3 TextDocumentItem, TextDocumentPositionParams, Url, VersionedTextDocumentIdentifier, InsertTextFormat,
4}; 4};
5use ra_analysis::{FileId, FileSystemEdit, SourceChange, SourceFileEdit, FilePosition}; 5use ra_analysis::{FileId, FileSystemEdit, SourceChange, SourceFileEdit, FilePosition, CompletionItem, CompletionItemKind, InsertText};
6use ra_editor::{LineCol, LineIndex}; 6use ra_editor::{LineCol, LineIndex};
7use ra_text_edit::{AtomTextEdit, TextEdit}; 7use ra_text_edit::{AtomTextEdit, TextEdit};
8use ra_syntax::{SyntaxKind, TextRange, TextUnit}; 8use ra_syntax::{SyntaxKind, TextRange, TextUnit};
@@ -45,6 +45,46 @@ impl Conv for SyntaxKind {
45 } 45 }
46} 46}
47 47
48impl Conv for CompletionItemKind {
49 type Output = ::languageserver_types::CompletionItemKind;
50
51 fn conv(self) -> <Self as Conv>::Output {
52 use ::languageserver_types::CompletionItemKind::*;
53 match self {
54 CompletionItemKind::Keyword => Keyword,
55 CompletionItemKind::Snippet => Snippet,
56 CompletionItemKind::Module => Module,
57 CompletionItemKind::Function => Function,
58 CompletionItemKind::Binding => Variable,
59 }
60 }
61}
62
63impl Conv for CompletionItem {
64 type Output = ::languageserver_types::CompletionItem;
65
66 fn conv(self) -> <Self as Conv>::Output {
67 let mut res = ::languageserver_types::CompletionItem {
68 label: self.label().to_string(),
69 filter_text: Some(self.lookup().to_string()),
70 kind: self.kind().map(|it| it.conv()),
71 ..Default::default()
72 };
73 match self.insert_text() {
74 InsertText::PlainText { text } => {
75 res.insert_text = Some(text);
76 res.insert_text_format = Some(InsertTextFormat::PlainText);
77 }
78 InsertText::Snippet { text } => {
79 res.insert_text = Some(text);
80 res.insert_text_format = Some(InsertTextFormat::Snippet);
81 res.kind = Some(languageserver_types::CompletionItemKind::Keyword);
82 }
83 }
84 res
85 }
86}
87
48impl ConvWith for Position { 88impl ConvWith for Position {
49 type Ctx = LineIndex; 89 type Ctx = LineIndex;
50 type Output = TextUnit; 90 type Output = TextUnit;
diff --git a/crates/ra_lsp_server/src/main_loop/handlers.rs b/crates/ra_lsp_server/src/main_loop/handlers.rs
index 2dfeb061a..252d1ba3e 100644
--- a/crates/ra_lsp_server/src/main_loop/handlers.rs
+++ b/crates/ra_lsp_server/src/main_loop/handlers.rs
@@ -2,13 +2,13 @@ use std::collections::HashMap;
2 2
3use gen_lsp_server::ErrorCode; 3use gen_lsp_server::ErrorCode;
4use languageserver_types::{ 4use languageserver_types::{
5 CodeActionResponse, Command, CompletionItem, CompletionItemKind, Diagnostic, 5 CodeActionResponse, Command, Diagnostic,
6 DiagnosticSeverity, DocumentSymbol, Documentation, FoldingRange, FoldingRangeKind, 6 DiagnosticSeverity, DocumentSymbol, Documentation, FoldingRange, FoldingRangeKind,
7 FoldingRangeParams, InsertTextFormat, Location, MarkupContent, MarkupKind, MarkedString, Position, 7 FoldingRangeParams, Location, MarkupContent, MarkupKind, MarkedString, Position,
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, InsertText}; 11use ra_analysis::{FileId, FoldKind, Query, RunnableKind, FilePosition};
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;
@@ -419,28 +419,7 @@ pub fn handle_completion(
419 None => return Ok(None), 419 None => return Ok(None),
420 Some(items) => items, 420 Some(items) => items,
421 }; 421 };
422 let items = items 422 let items = items.into_iter().map(|item| item.conv()).collect();
423 .into_iter()
424 .map(|item| {
425 let mut res = CompletionItem {
426 label: item.label().to_string(),
427 filter_text: Some(item.lookup().to_string()),
428 ..Default::default()
429 };
430 match item.insert_text() {
431 InsertText::PlainText { text } => {
432 res.insert_text = Some(text);
433 res.insert_text_format = Some(InsertTextFormat::PlainText);
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 }
441 res
442 })
443 .collect();
444 423
445 Ok(Some(req::CompletionResponse::Array(items))) 424 Ok(Some(req::CompletionResponse::Array(items)))
446} 425}