Skip to content

In a scenario where ark should provide all completions, it provides none #770

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
jennybc opened this issue Apr 10, 2025 · 3 comments
Open

Comments

@jennybc
Copy link
Member

jennybc commented Apr 10, 2025

The most basic gesture to get completions in VS Code / Positron is Ctrl + Space. From the IntelliSense docs:

You can trigger IntelliSense in any editor window by typing ⌃Space or by typing a trigger character ...

(BTW this is invoking the command editor.action.triggerSuggest.)

Now, more often, you type a few characters and then you get completions.
Either automatically after 3 characters or because you request with tab or because you trigger with a character, like $ or @.

But what if you want to trigger completions before you've typed anything? You can use
Ctrl + Space to do it.

This should reveal "all completions", for some definition of "all".
But currently ark returns ZERO completions in this scenario.
This causes VS Code / Positron to fall back to this weird language agnostic word based completion list (quote is from Intellisense docs):

VS Code supports word-based completions for any programming language but can also be configured to have richer IntelliSense by installing a language extension.

Empirically, this list seems to consist of tokens parsed out of ?all the files you have open in the current window?. Something like that.

Ways to experience this:

  1. Ctrl + Space at the R prompt in the Console

    Image
  2. Ctrl + Space in an empty R file (looks same as above)

  3. Ctrl + Space on an empty line of a non-empty R file

    Image

Why does this happen?
Because the nominal completion node when the user hasn't typed anything yet does not meet our criteria for providing completions.
Mostly because our logic doesn't account for the possibility that there really is no completion node and, instead, always latches on to something "nearby", in find_closest_node_to_point():

let Some(node) = ast.root_node().find_closest_node_to_point(point) else {

We then fail to pass the is_identifier_like() test when getting composite completions, which means we never consult keywords, snippets, the search path, the current document, or the current workspace.

// For the rest of the general completions, we require an identifier to
// begin showing anything.
if is_identifier_like(completion_context.document_context.node) {

And thus ark returns zero completions and the fallback list kicks in.
In the log, you can see the completion search just ends abruptly.

[R]   2025-04-10T15:47:27.133734Z  INFO  Getting completions from composite sources
[R]   2025-04-10T15:47:27.133751Z  INFO  Trying completions from source: call
[R]   2025-04-10T15:47:27.133796Z  INFO  Trying completions from source: pipe
[R]   2025-04-10T15:47:27.133816Z  INFO  Trying completions from source: subset

This happens in two different ways:

  • The document really is empty, so the node type is 'Program' and the node text is the empty string. Cases 1 and 2 in the list above. How it looks in the log:

    [R]   2025-04-10T15:45:52.401668Z  INFO  provide_completions() - Completion node text: '', Node type: 'Program'
    
  • The document is not empty, so ast.root_node().find_closest_node_to_point(point) latches on to a bit of code elsewhere in the document. The node text varies, of course, but generally it fails the is_identifier_like() test. Case 3 in the list above. Examples of how this looks in the log:

    [R]   2025-04-10T15:47:27.133082Z  INFO  provide_completions() - Completion node text: '10', Node type: 'Float'
    
    [R]   2025-04-10T16:40:39.468395Z  INFO  provide_completions() - Completion node text: ')', Node type: 'Anonymous(")")'
    
    [R]   2025-04-10T17:19:24.813969Z  INFO  provide_completions() - Completion node text: '
    [R]
    [R] toupper(month.abb)
    [R] ', Node type: 'Program'
    

Thoughts about how to solve this:

  • Add the empty string or the 'Program' node as a special case that satisfies is_identifier_like(). See PR Be willing to complete in the face of emptiness #772 for this. This feels like a bandaid. But it is a really good bandaid that fixes one route into this problem.
  • Recognize it's possible that the completion node is actually undefined and account for this when constructing and processing a DocumentContext. This is a bigger undertaking.

I need to discuss with others before moving forward.

This analysis has brought up some other ideas:

  • Store the the completion node's kind and text in the CompletionContext, alongside features like parameters hints and pipe root. You end up wanting to know these facts in various places downstream, for logging and branching, and it's a bit of a PITA to inline that repeatedly.
  • Maybe we really should make "is identifier like" into another feature that we store in the completion context and can branch on. For example, I think we can probably skip all unique sources if that is false. Then, for composite sources, we could push that check down into the implementation of each composite source. We've discussed this before and already thought this might be a good idea.
@jennybc
Copy link
Member Author

jennybc commented Apr 10, 2025

Summary motivated by pre-discussion in Slack:

The command editor.action.triggerSuggest should not lead to weird word-based completions, ever, in the R console or an R file.

Open question whether we want "all completions" or nothing. But either is preferable to weird stuff.

@jennybc
Copy link
Member Author

jennybc commented Apr 10, 2025

For comparison with Python, the LSP provides real completions in all of these scenarios:

  • at the console prompt
  • in an empty Python file
  • on an empty line in a non-empty Python file

They all look like this:

Image

@jennybc
Copy link
Member Author

jennybc commented Apr 16, 2025

Anecdotally, when asking for completions in one of these valid-but-empty contexts, different folks are getting different results at different times. I don't have complete clarity on this, but approximately:

  • "No suggestions" is seen in release builds of Positron (?)
Image
  • The word-based completions are seen in dev builds of Positron (?), as shown in plenty of screenshots above

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant