One feature that I love when I write code is the completion apply which opens a second completion popup which suggests the values that you can insert after completion apply.
Here a Java demo which defines 2 int variables (i and j). When substring method completion is applied, it suggest completion popup for the substring parameters which are int.

There are other usecases like HTML/XML (when completion for attribute is applied, it suggest values for attribute values, etc).
It should be cool if LSP could specify a new protocol to manage that (by extending completionItem/resolve?)
I think this can be covered by using placeholder and choices which are already specified for completion.
But these placeholders don't get rich information like what completion gives. So there is indeed room for improvements.
Maybe the Completion response could add a new type of placeholders that could be "completablePlaceholders" with one default value for insertion, tab stops and so on, and just giving the hint that on edition of this placeholder, a new completion request should be sent?
Actually, as I'm thinking about it, I don't think we need the protocol to state something about it: if there is a placeholder, it's most likely that user will probably want to edit it, and if user wants to edit it, why wouldn't the client ask for another completion?
FWIW, automatically asking for completion on placeholders would be a welcome addition to LSP4E for instance.
There is a command on CompletionItem which we use in the (not currently LSP) Dart plugin to do just this:
However, it's not clear how this could work with LSP since that command is VS Code-specific. I guess if you're implementing both the LSP server and the plugin the wraps it for an editor, you could send a custom command and then map it on to the appropriate thing for each editor, but it's messy.
@tsmaeder told me that it exists a specification for snippet choice https://github.com/Microsoft/language-server-protocol/blob/master/snippetSyntax.md#choice
@mickaelistria I'm not sure that LSP4e implement that ?
I think it's a good idea for values which not require complex computing. For other case like Java completion apply, I think it should be better to call a command. We could have a syntax snippet like this:
${1(myCompletionCommand)}
I think it should be better to call a command. We could have a syntax snippet like this:
There's already a command property on CompletionItem (see my previous comment above) - isn't this the same as what you're requesting?
Eclipse LSP4E implements snippet choice IIRC. But anyway, I still stand with my former command https://github.com/Microsoft/language-server-protocol/issues/565#issuecomment-419412040 : there is nothing preventing the client from invoking content assist at the location of placeholders and I don't think we need addition in LSP spec to do that.
Eclipse LSP4E implements snippet choice IIRC.
That's strange, I have tested with lsp4xml, but it doesn't work? Where is the supposed code which manages the open of the second completion popup with choice values?
I have tested with lsp4xml, but it doesn't work?
Sorry you're right. Eclipse LSP4E has support for linked regions but not yet for snippet proposals. Feel free to open a new bug to LSP4E for that (and even for re-triggering completion when on another region and no snippet proposal is found); but still I don't think the spec needs anything more.
Looks like this doesn't need any addition in the spec. Any objection to close the issue?
@dbaeumer Actually, I think my comment above may be incorrect. Thinking again, it's not clear whether the command on a completionItem is a command that the LSP client sends back to the server (via executeCommand) or a command for the client to execute (eg. like calling editor.action.triggerSuggest).
I assumed you could put editor.action.triggerSuggest in it (since that's what I do in the equiv field in the VS Code API), however now I'm thinking this is unlikely, since an LSP server probably shouldn't be relying on internal command identifiers that may of may not be available on the client.
Can you clarify which it is - is CompletionItem.command the ID of a command the LSP server handles (via executeCommand) - in which case I think this requres is not currently possible - or executed by the client (in which case, should LSP define well-known commands that the server can call on the client)?
Actually, the spec does say this!
The protocol currently doesn鈥檛 specify a set of well-known commands. So executing a command requires some tool extension code
And the thing that decides which commands should be sent to the server versus executing in the client plugin is ExecuteCommandOptions.
TL;DR - putting editor.action.triggerSuggest in the command on a CompletionItem probably works, but since it might not be consistent across editors, may be better as a custom command.
The server in some respect relies on capabilities on the client side. These are commands which are not handled by the server itself and settings (getConfiguration call send from the server to the client). The current advice is that a server specs these and that the client plugin needs to do these transformations (for example map the settings to their settings store).
I am not a big fan of starting to spec editor commands since this can be very specific to a tool / UI.
Yeah, I think what is there is fine now I understand it better.
That said, I think there's still something ambiguous. The description of ExecuteCommandOptions sounds like any commands that are listed in there will be sent to the server (via workspace/executeCommand) and anything not listed in it will be handled locally (eg. the client expects the local extension can handle it).
However, for CodeAction the text says:
When the command is selected the server should be contacted again (via the
workspace/executeCommand) request to execute the command
It's not clear whether the client should send the command from the CodeAction to the server always, or whether it should handle it locally if it's not listed in ExecuteCommandOptions. I think the latter would be better (because if desired, it allows the code action commands to be run through a local handler), however I suspect based on the text that it currently always goes to the server in VS Code?
@DanTup actually no. The idea of this sentence was to avoid to execute local editor commands. I will clarify this.
@dbaeumer I'm not sure I follow - does this mean it's not allowed to execute local commands in code fixes? (If not, that somewhat throws a spanner in the works for the discussion on the "ask for user input" issue 馃槙)
@DanTup if you expect the server to run in different clients then executing the command will very likely fails unless we standardize commands which I am actually not a fan of. Or do I misunderstand something?
@dbaeumer No, that's right - but the spec already explicitly mentions this:
Command
Represents a reference to a command. Provides a title which will be used to represent a command in the UI. Commands are identified by a string identifier. The protocol currently doesn鈥檛 specify a set of well-known commands. So executing a command requires some tool extension code.
This is what #642 is about (ignoring the misleading title) - I think the client capabilities should include the command IDs the client extension supports, so the server can act appropriately. There's no need for LSP to standardise them, they should be documented by as LSP server as extra functionality that can be provided if the client provides the required local functionality.
As commented on the other item this sentence was added when a server had no way to handle commands. I will change this to indicate that the best way is to execute a command on the server.
I think I somewhat derailed this thread. I don't think the original request is resolved anymore, since the server shouldn't rely on being able to using editor.action.triggerSuggest as a command.
I want to use something like this to implement "multi-stage autocompletion", for example:

To record this gif I used the hack @DanTup suggested. It'd be nice to have a client-agnostic solution for this.
To revive the discussion, I propose we add a new LSP snippet variable COMPLETE that instructs the client to trigger a completion and insert the result. Since it is a variable that can be repeated inside the snippet, completion can be triggered at each tab stop, or a subset of tab stops.
For example, say you have
function foo(int a, string b) {}
Completing to foo could yield either of the following:
foo(${1:$COMPLETE}, ${2:$COMPLETE}) which would automatically trigger completion for the first argument, then after the user presses TAB it would trigger completion at the second argument.foo(${1:$COMPLETE}) which similarly triggers completion. However, the inner completion could return another snippet: best_int, ${1:$COMPLETE}, allowing you to complete each argument one at a time. I believe it would also allow for the "multi-stage autocomplete" @vrama628 is talking about.A problem arises if the user needs multiple completions to fill in a single argument. For example, they want to enter user.age() for a. If they press TAB after completing user, it will take them to the next parameter instead of letting them continue user. In this case the user could use a different trigger character such as . to select user and avoid TABbing to the next tab stop.
To be backwards compatible with clients that don't support COMPLETE, you can pass the existing placeholder value as the default value for the $COMPLETE variable. For example: foo(${1:${COMPLETE:a}}) would show "a" as the placeholder if the client doesn't support $COMPLETE.
Interesting idea. The only problem I see is that this makes the snippets deviate from TextMate snippets which we tried to avoid so far.
I would suggest that we open a separate issue for the snippet idea since I see this independent from this request. I don't want to ask users to generate snippets if they want to trigger a second code completion call after inserting a completion item.
I don't want to ask users to generate snippets if they want to trigger a second code completion call after inserting a completion item.
When would the user need to generate a snippet? In my proposal the LSP server generates the snippets with $COMPLETE, not the user.
I would suggest that we open a separate issue for the snippet idea since I see this independent from this request.
I was trying to propose a concrete way to implement the desired behavior. It seems natural to use snippets since otherwise it would be very clunky for a single completion item to control multiple completion triggers.
When would the user need to generate a snippet?
I meant users of the library.
Most helpful comment
There is a
commandonCompletionItemwhich we use in the (not currently LSP) Dart plugin to do just this:https://github.com/Dart-Code/Dart-Code/blob/7df6509870d51cc99a90cf220715f4f97c681bbf/src/providers/dart_completion_item_provider.ts#L197-202
However, it's not clear how this could work with LSP since that command is VS Code-specific. I guess if you're implementing both the LSP server and the plugin the wraps it for an editor, you could send a custom command and then map it on to the appropriate thing for each editor, but it's messy.