diff options
-rw-r--r-- | crates/ra_ide/src/completion/completion_item.rs | 15 | ||||
-rw-r--r-- | crates/ra_ide/src/completion/presentation.rs | 22 | ||||
-rw-r--r-- | crates/ra_ide_db/src/feature_flags.rs | 2 | ||||
-rw-r--r-- | crates/rust-analyzer/src/conv.rs | 39 | ||||
-rw-r--r-- | crates/rust-analyzer/src/main_loop/handlers.rs | 8 | ||||
-rw-r--r-- | editors/code/package.json | 8 |
6 files changed, 73 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 | ||
198 | impl Builder { | 208 | impl 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 | ||
276 | impl<'a> Into<CompletionItem> for Builder { | 291 | impl<'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 | ||
4 | use lsp_types::{ | 4 | use 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 | }; |
11 | use ra_ide::{ | 11 | use 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 | ||
213 | impl Conv for ra_ide::FunctionSignature { | 223 | impl 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], |
diff --git a/editors/code/package.json b/editors/code/package.json index 830358605..3a1e6cf23 100644 --- a/editors/code/package.json +++ b/editors/code/package.json | |||
@@ -197,10 +197,18 @@ | |||
197 | "type": "boolean", | 197 | "type": "boolean", |
198 | "description": "Whether to add parenthesis when completing functions" | 198 | "description": "Whether to add parenthesis when completing functions" |
199 | }, | 199 | }, |
200 | "completion.insertion.add-argument-snippets": { | ||
201 | "type": "boolean", | ||
202 | "description": "Whether to add argument snippets when completing functions" | ||
203 | }, | ||
200 | "completion.enable-postfix": { | 204 | "completion.enable-postfix": { |
201 | "type": "boolean", | 205 | "type": "boolean", |
202 | "description": "Whether to show postfix snippets like `dbg`, `if`, `not`, etc." | 206 | "description": "Whether to show postfix snippets like `dbg`, `if`, `not`, etc." |
203 | }, | 207 | }, |
208 | "call-info.full": { | ||
209 | "type": "boolean", | ||
210 | "description": "Show function name and docs in parameter hints" | ||
211 | }, | ||
204 | "notifications.workspace-loaded": { | 212 | "notifications.workspace-loaded": { |
205 | "type": "boolean", | 213 | "type": "boolean", |
206 | "description": "Whether to show `workspace loaded` message" | 214 | "description": "Whether to show `workspace loaded` message" |