Skip to content

Commit e946481

Browse files
Analyze completion site re: trailing parens (#680)
* Analyze completion site re: trailing parens * Start dismantling measures that just aided development * More parallel with the other branch * Get inspired by the less nested approach in PR #369 * Must have been leftover from an experiment * Add tests * Be consistent * Try to get a bit more info on the Windows test failure * Flatten this out too * Not my problem to solve: Revert "Try to get a bit more info on the Windows test failure" This reverts commit dea921d. This is unrelated to this PR and is being tracked in #678. * Remove rest of temporary logging * Extract out `node_find_containing_call()` * Rework on top of `parameter_hints()` idea * Add `ParameterHints` enum And fix a bug with imports environment functions not respecting `parameter_hints` * Move tests to `parameter_hints.rs` It seems obvious to me that we are testing a feature that "officially" lives here now * Tweak examples probed in tests * Add comment * Use original name of function --------- Co-authored-by: Davis Vaughan <[email protected]>
1 parent c4d95eb commit e946481

File tree

13 files changed

+455
-69
lines changed

13 files changed

+455
-69
lines changed

.vscode/launch.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@
1414
},
1515
"windows": {
1616
"program": "ark.exe"
17-
}
17+
},
18+
"sourceLanguages": ["rust"]
1819
},
1920
{
2021
"type": "lldb",

crates/ark/src/lsp/completions.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
//
77

88
mod completion_item;
9+
mod parameter_hints;
910
mod provide;
1011
mod resolve;
1112
mod sources;

crates/ark/src/lsp/completions/completion_item.rs

Lines changed: 65 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ use tower_lsp::lsp_types::Range;
4040
use tower_lsp::lsp_types::TextEdit;
4141
use tree_sitter::Node;
4242

43+
use crate::lsp::completions::parameter_hints::ParameterHints;
4344
use crate::lsp::completions::types::CompletionData;
4445
use crate::lsp::completions::types::PromiseStrategy;
4546
use crate::lsp::document_context::DocumentContext;
@@ -169,6 +170,7 @@ pub(super) unsafe fn completion_item_from_package(
169170
pub(super) fn completion_item_from_function(
170171
name: &str,
171172
package: Option<&str>,
173+
parameter_hints: ParameterHints,
172174
) -> Result<CompletionItem> {
173175
let label = format!("{}", name);
174176
let mut item = completion_item(label, CompletionData::Function {
@@ -182,17 +184,23 @@ pub(super) fn completion_item_from_function(
182184
item.label_details = Some(label_details);
183185

184186
let insert_text = sym_quote_invalid(name);
185-
item.insert_text_format = Some(InsertTextFormat::SNIPPET);
186-
item.insert_text = Some(format!("{insert_text}($0)"));
187187

188-
// provide parameter completions after completing function
189-
item.command = Some(Command {
190-
title: "Trigger Parameter Hints".to_string(),
191-
command: "editor.action.triggerParameterHints".to_string(),
192-
..Default::default()
193-
});
188+
if parameter_hints.is_enabled() {
189+
item.insert_text_format = Some(InsertTextFormat::SNIPPET);
190+
item.insert_text = Some(format!("{insert_text}($0)"));
194191

195-
return Ok(item);
192+
// provide parameter completions after completing function
193+
item.command = Some(Command {
194+
title: "Trigger Parameter Hints".to_string(),
195+
command: "editor.action.triggerParameterHints".to_string(),
196+
..Default::default()
197+
});
198+
} else {
199+
item.insert_text_format = Some(InsertTextFormat::PLAIN_TEXT);
200+
item.insert_text = Some(insert_text);
201+
}
202+
203+
Ok(item)
196204
}
197205

198206
fn item_details(package: Option<&str>) -> CompletionItemLabelDetails {
@@ -245,9 +253,17 @@ pub(super) unsafe fn completion_item_from_object(
245253
envir: SEXP,
246254
package: Option<&str>,
247255
promise_strategy: PromiseStrategy,
256+
parameter_hints: ParameterHints,
248257
) -> Result<CompletionItem> {
249258
if r_typeof(object) == PROMSXP {
250-
return completion_item_from_promise(name, object, envir, package, promise_strategy);
259+
return completion_item_from_promise(
260+
name,
261+
object,
262+
envir,
263+
package,
264+
promise_strategy,
265+
parameter_hints,
266+
);
251267
}
252268

253269
// TODO: For some functions (e.g. S4 generics?) the help file might be
@@ -256,7 +272,7 @@ pub(super) unsafe fn completion_item_from_object(
256272
// In other words, when creating a completion item for these functions,
257273
// we should also figure out where we can receive the help from.
258274
if Rf_isFunction(object) != 0 {
259-
return completion_item_from_function(name, package);
275+
return completion_item_from_function(name, package, parameter_hints);
260276
}
261277

262278
let mut item = completion_item(name, CompletionData::Object {
@@ -287,12 +303,20 @@ pub(super) unsafe fn completion_item_from_promise(
287303
envir: SEXP,
288304
package: Option<&str>,
289305
promise_strategy: PromiseStrategy,
306+
parameter_hints: ParameterHints,
290307
) -> Result<CompletionItem> {
291308
if r_promise_is_forced(object) {
292309
// Promise has already been evaluated before.
293310
// Generate completion item from underlying value.
294311
let object = PRVALUE(object);
295-
return completion_item_from_object(name, object, envir, package, promise_strategy);
312+
return completion_item_from_object(
313+
name,
314+
object,
315+
envir,
316+
package,
317+
promise_strategy,
318+
parameter_hints,
319+
);
296320
}
297321

298322
if promise_strategy == PromiseStrategy::Force && r_promise_is_lazy_load_binding(object) {
@@ -302,7 +326,14 @@ pub(super) unsafe fn completion_item_from_promise(
302326
// important for functions, where we also set a `CompletionItem::command()`
303327
// to display function signature help after the completion.
304328
let object = r_promise_force_with_rollback(object)?;
305-
return completion_item_from_object(name, object.sexp, envir, package, promise_strategy);
329+
return completion_item_from_object(
330+
name,
331+
object.sexp,
332+
envir,
333+
package,
334+
promise_strategy,
335+
parameter_hints,
336+
);
306337
}
307338

308339
// Otherwise we never want to force promises, so we return a fairly
@@ -342,19 +373,28 @@ pub(super) unsafe fn completion_item_from_namespace(
342373
name: &str,
343374
namespace: SEXP,
344375
package: &str,
376+
parameter_hints: ParameterHints,
345377
) -> Result<CompletionItem> {
346378
// First, look in the namespace itself.
347-
if let Some(item) =
348-
completion_item_from_symbol(name, namespace, Some(package), PromiseStrategy::Force)
349-
{
379+
if let Some(item) = completion_item_from_symbol(
380+
name,
381+
namespace,
382+
Some(package),
383+
PromiseStrategy::Force,
384+
parameter_hints,
385+
) {
350386
return item;
351387
}
352388

353389
// Otherwise, try the imports environment.
354390
let imports = ENCLOS(namespace);
355-
if let Some(item) =
356-
completion_item_from_symbol(name, imports, Some(package), PromiseStrategy::Force)
357-
{
391+
if let Some(item) = completion_item_from_symbol(
392+
name,
393+
imports,
394+
Some(package),
395+
PromiseStrategy::Force,
396+
parameter_hints,
397+
) {
358398
return item;
359399
}
360400

@@ -376,7 +416,10 @@ pub(super) unsafe fn completion_item_from_lazydata(
376416
// long time to load.
377417
let promise_strategy = PromiseStrategy::Simple;
378418

379-
match completion_item_from_symbol(name, env, Some(package), promise_strategy) {
419+
// Lazydata objects are never functions, so this doesn't really matter
420+
let parameter_hints = ParameterHints::Enabled;
421+
422+
match completion_item_from_symbol(name, env, Some(package), promise_strategy, parameter_hints) {
380423
Some(item) => item,
381424
None => {
382425
// Should be impossible, but we'll be extra safe
@@ -390,6 +433,7 @@ pub(super) unsafe fn completion_item_from_symbol(
390433
envir: SEXP,
391434
package: Option<&str>,
392435
promise_strategy: PromiseStrategy,
436+
parameter_hints: ParameterHints,
393437
) -> Option<Result<CompletionItem>> {
394438
let symbol = r_symbol!(name);
395439

@@ -422,6 +466,7 @@ pub(super) unsafe fn completion_item_from_symbol(
422466
envir,
423467
package,
424468
promise_strategy,
469+
parameter_hints,
425470
))
426471
}
427472

0 commit comments

Comments
 (0)