aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/ra_ide/src/completion/completion_item.rs15
-rw-r--r--crates/ra_ide/src/completion/presentation.rs22
-rw-r--r--crates/ra_ide_db/src/feature_flags.rs2
-rw-r--r--crates/rust-analyzer/src/conv.rs39
-rw-r--r--crates/rust-analyzer/src/main_loop/handlers.rs8
5 files changed, 65 insertions, 21 deletions
diff --git a/crates/ra_ide/src/completion/completion_item.rs b/crates/ra_ide/src/completion/completion_item.rs
index 61867c0ff..19bbb2517 100644
--- a/crates/ra_ide/src/completion/completion_item.rs
+++ b/crates/ra_ide/src/completion/completion_item.rs
@@ -47,6 +47,10 @@ pub struct CompletionItem {
47 47
48 /// Whether this item is marked as deprecated 48 /// Whether this item is marked as deprecated
49 deprecated: bool, 49 deprecated: bool,
50
51 /// If completing a function call, ask the editor to show parameter popup
52 /// after completion.
53 trigger_call_info: bool,
50} 54}
51 55
52// We use custom debug for CompletionItem to make `insta`'s diffs more readable. 56// We use custom debug for CompletionItem to make `insta`'s diffs more readable.
@@ -139,6 +143,7 @@ impl CompletionItem {
139 kind: None, 143 kind: None,
140 text_edit: None, 144 text_edit: None,
141 deprecated: None, 145 deprecated: None,
146 trigger_call_info: None,
142 } 147 }
143 } 148 }
144 /// What user sees in pop-up in the UI. 149 /// What user sees in pop-up in the UI.
@@ -177,6 +182,10 @@ impl CompletionItem {
177 pub fn deprecated(&self) -> bool { 182 pub fn deprecated(&self) -> bool {
178 self.deprecated 183 self.deprecated
179 } 184 }
185
186 pub fn trigger_call_info(&self) -> bool {
187 self.trigger_call_info
188 }
180} 189}
181 190
182/// A helper to make `CompletionItem`s. 191/// A helper to make `CompletionItem`s.
@@ -193,6 +202,7 @@ pub(crate) struct Builder {
193 kind: Option<CompletionItemKind>, 202 kind: Option<CompletionItemKind>,
194 text_edit: Option<TextEdit>, 203 text_edit: Option<TextEdit>,
195 deprecated: Option<bool>, 204 deprecated: Option<bool>,
205 trigger_call_info: Option<bool>,
196} 206}
197 207
198impl Builder { 208impl Builder {
@@ -221,6 +231,7 @@ impl Builder {
221 kind: self.kind, 231 kind: self.kind,
222 completion_kind: self.completion_kind, 232 completion_kind: self.completion_kind,
223 deprecated: self.deprecated.unwrap_or(false), 233 deprecated: self.deprecated.unwrap_or(false),
234 trigger_call_info: self.trigger_call_info.unwrap_or(false),
224 } 235 }
225 } 236 }
226 pub(crate) fn lookup_by(mut self, lookup: impl Into<String>) -> Builder { 237 pub(crate) fn lookup_by(mut self, lookup: impl Into<String>) -> Builder {
@@ -271,6 +282,10 @@ impl Builder {
271 self.deprecated = Some(deprecated); 282 self.deprecated = Some(deprecated);
272 self 283 self
273 } 284 }
285 pub(crate) fn trigger_call_info(mut self) -> Builder {
286 self.trigger_call_info = Some(true);
287 self
288 }
274} 289}
275 290
276impl<'a> Into<CompletionItem> for Builder { 291impl<'a> Into<CompletionItem> for Builder {
diff --git a/crates/ra_ide/src/completion/presentation.rs b/crates/ra_ide/src/completion/presentation.rs
index dac232a85..aada4d025 100644
--- a/crates/ra_ide/src/completion/presentation.rs
+++ b/crates/ra_ide/src/completion/presentation.rs
@@ -103,7 +103,7 @@ impl Completions {
103 } 103 }
104 }; 104 };
105 105
106 // If not an import, add parenthesis automatically. 106 // Add `<>` for generic types
107 if ctx.is_path_type 107 if ctx.is_path_type
108 && !ctx.has_type_args 108 && !ctx.has_type_args
109 && ctx.db.feature_flags.get("completion.insertion.add-call-parenthesis") 109 && ctx.db.feature_flags.get("completion.insertion.add-call-parenthesis")
@@ -211,7 +211,7 @@ impl Completions {
211 .set_deprecated(is_deprecated(func, ctx.db)) 211 .set_deprecated(is_deprecated(func, ctx.db))
212 .detail(function_signature.to_string()); 212 .detail(function_signature.to_string());
213 213
214 // Add `<>` for generic types 214 // If not an import, add parenthesis automatically.
215 if ctx.use_item_syntax.is_none() 215 if ctx.use_item_syntax.is_none()
216 && !ctx.is_call 216 && !ctx.is_call
217 && ctx.db.feature_flags.get("completion.insertion.add-call-parenthesis") 217 && ctx.db.feature_flags.get("completion.insertion.add-call-parenthesis")
@@ -221,16 +221,26 @@ impl Completions {
221 let (snippet, label) = if params.is_empty() || has_self_param && params.len() == 1 { 221 let (snippet, label) = if params.is_empty() || has_self_param && params.len() == 1 {
222 (format!("{}()$0", name), format!("{}()", name)) 222 (format!("{}()$0", name), format!("{}()", name))
223 } else { 223 } else {
224 let to_skip = if has_self_param { 1 } else { 0 }; 224 builder = builder.trigger_call_info();
225 let function_params_snippet = 225 let snippet = if ctx
226 join( 226 .db
227 .feature_flags
228 .get("completion.insertion.add-argument-snippets")
229 {
230 let to_skip = if has_self_param { 1 } else { 0 };
231 let function_params_snippet = join(
227 function_signature.parameter_names.iter().skip(to_skip).enumerate().map( 232 function_signature.parameter_names.iter().skip(to_skip).enumerate().map(
228 |(index, param_name)| format!("${{{}:{}}}", index + 1, param_name), 233 |(index, param_name)| format!("${{{}:{}}}", index + 1, param_name),
229 ), 234 ),
230 ) 235 )
231 .separator(", ") 236 .separator(", ")
232 .to_string(); 237 .to_string();
233 (format!("{}({})$0", name, function_params_snippet), format!("{}(…)", name)) 238 format!("{}({})$0", name, function_params_snippet)
239 } else {
240 format!("{}($0)", name)
241 };
242
243 (snippet, format!("{}(…)", name))
234 }; 244 };
235 builder = builder.lookup_by(name).label(label).insert_snippet(snippet); 245 builder = builder.lookup_by(name).label(label).insert_snippet(snippet);
236 } 246 }
diff --git a/crates/ra_ide_db/src/feature_flags.rs b/crates/ra_ide_db/src/feature_flags.rs
index 76655f572..968415072 100644
--- a/crates/ra_ide_db/src/feature_flags.rs
+++ b/crates/ra_ide_db/src/feature_flags.rs
@@ -54,7 +54,9 @@ impl Default for FeatureFlags {
54 FeatureFlags::new(&[ 54 FeatureFlags::new(&[
55 ("lsp.diagnostics", true), 55 ("lsp.diagnostics", true),
56 ("completion.insertion.add-call-parenthesis", true), 56 ("completion.insertion.add-call-parenthesis", true),
57 ("completion.insertion.add-argument-snippets", true),
57 ("completion.enable-postfix", true), 58 ("completion.enable-postfix", true),
59 ("call-info.full", true),
58 ("notifications.workspace-loaded", true), 60 ("notifications.workspace-loaded", true),
59 ("notifications.cargo-toml-not-found", true), 61 ("notifications.cargo-toml-not-found", true),
60 ]) 62 ])
diff --git a/crates/rust-analyzer/src/conv.rs b/crates/rust-analyzer/src/conv.rs
index eeeb33e8f..a2d68c344 100644
--- a/crates/rust-analyzer/src/conv.rs
+++ b/crates/rust-analyzer/src/conv.rs
@@ -3,10 +3,10 @@
3 3
4use lsp_types::{ 4use lsp_types::{
5 self, CreateFile, DiagnosticSeverity, DocumentChangeOperation, DocumentChanges, Documentation, 5 self, CreateFile, DiagnosticSeverity, DocumentChangeOperation, DocumentChanges, Documentation,
6 Location, LocationLink, MarkupContent, MarkupKind, Position, Range, RenameFile, ResourceOp, 6 Location, LocationLink, MarkupContent, MarkupKind, ParameterInformation, ParameterLabel,
7 SemanticTokenModifier, SemanticTokenType, SymbolKind, TextDocumentEdit, TextDocumentIdentifier, 7 Position, Range, RenameFile, ResourceOp, SemanticTokenModifier, SemanticTokenType,
8 TextDocumentItem, TextDocumentPositionParams, Url, VersionedTextDocumentIdentifier, 8 SignatureInformation, SymbolKind, TextDocumentEdit, TextDocumentIdentifier, TextDocumentItem,
9 WorkspaceEdit, 9 TextDocumentPositionParams, Url, VersionedTextDocumentIdentifier, WorkspaceEdit,
10}; 10};
11use ra_ide::{ 11use ra_ide::{
12 translate_offset_with_edit, CompletionItem, CompletionItemKind, FileId, FilePosition, 12 translate_offset_with_edit, CompletionItem, CompletionItemKind, FileId, FilePosition,
@@ -150,6 +150,16 @@ impl ConvWith<(&LineIndex, LineEndings)> for CompletionItem {
150 additional_text_edits: Some(additional_text_edits), 150 additional_text_edits: Some(additional_text_edits),
151 documentation: self.documentation().map(|it| it.conv()), 151 documentation: self.documentation().map(|it| it.conv()),
152 deprecated: Some(self.deprecated()), 152 deprecated: Some(self.deprecated()),
153 command: if self.trigger_call_info() {
154 let cmd = lsp_types::Command {
155 title: "triggerParameterHints".into(),
156 command: "editor.action.triggerParameterHints".into(),
157 arguments: None,
158 };
159 Some(cmd)
160 } else {
161 None
162 },
153 ..Default::default() 163 ..Default::default()
154 }; 164 };
155 165
@@ -210,17 +220,20 @@ impl Conv for ra_ide::Documentation {
210 } 220 }
211} 221}
212 222
213impl Conv for ra_ide::FunctionSignature { 223impl ConvWith<bool> for ra_ide::FunctionSignature {
214 type Output = lsp_types::SignatureInformation; 224 type Output = lsp_types::SignatureInformation;
215 fn conv(self) -> Self::Output { 225 fn conv_with(self, concise: bool) -> Self::Output {
216 use lsp_types::{ParameterInformation, ParameterLabel, SignatureInformation}; 226 let (label, documentation, params) = if concise {
217 227 let mut params = self.parameters;
218 let label = self.to_string(); 228 if self.has_self_param {
219 229 params.remove(0);
220 let documentation = self.doc.map(|it| it.conv()); 230 }
231 (params.join(", "), None, params)
232 } else {
233 (self.to_string(), self.doc.map(|it| it.conv()), self.parameters)
234 };
221 235
222 let parameters: Vec<ParameterInformation> = self 236 let parameters: Vec<ParameterInformation> = params
223 .parameters
224 .into_iter() 237 .into_iter()
225 .map(|param| ParameterInformation { 238 .map(|param| ParameterInformation {
226 label: ParameterLabel::Simple(param), 239 label: ParameterLabel::Simple(param),
diff --git a/crates/rust-analyzer/src/main_loop/handlers.rs b/crates/rust-analyzer/src/main_loop/handlers.rs
index b5db1fd38..b498c90c9 100644
--- a/crates/rust-analyzer/src/main_loop/handlers.rs
+++ b/crates/rust-analyzer/src/main_loop/handlers.rs
@@ -459,8 +459,12 @@ pub fn handle_signature_help(
459 let _p = profile("handle_signature_help"); 459 let _p = profile("handle_signature_help");
460 let position = params.try_conv_with(&world)?; 460 let position = params.try_conv_with(&world)?;
461 if let Some(call_info) = world.analysis().call_info(position)? { 461 if let Some(call_info) = world.analysis().call_info(position)? {
462 let active_parameter = call_info.active_parameter.map(|it| it as i64); 462 let concise = !world.analysis().feature_flags().get("call-info.full");
463 let sig_info = call_info.signature.conv(); 463 let mut active_parameter = call_info.active_parameter.map(|it| it as i64);
464 if concise && call_info.signature.has_self_param {
465 active_parameter = active_parameter.map(|it| it.saturating_sub(1));
466 }
467 let sig_info = call_info.signature.conv_with(concise);
464 468
465 Ok(Some(req::SignatureHelp { 469 Ok(Some(req::SignatureHelp {
466 signatures: vec![sig_info], 470 signatures: vec![sig_info],