Skip to content
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

Execute client side command #430

Open
henryju opened this issue Mar 21, 2018 · 5 comments
Open

Execute client side command #430

henryju opened this issue Mar 21, 2018 · 5 comments

Comments

@henryju
Copy link
Contributor

henryju commented Mar 21, 2018

We are providing some code actions, and some of them should be invoked on client side (like opening a new panel to display some guidelines about diagnostics).

The official workflow specified with protocol v3 is:

  • client invokes textDocument/codeAction
  • server returns an array of Command
  • user picks one command
  • client invokes workspace/executeCommand
    So we end up on LS side, with no way to invoke a command on client side.

VSCode has a specific behavior. If a returned Command matches a command declared on VSCode side, it will not call workspace/executeCommand but instead directly invoke the client side command.

I find this very convenient, but this is not what is defined in protocol V3, and consequently not portable (Atom doesn't work like this for example, see atom/atom-languageclient#183).

Proposals:

  • officially support this behavior, but this maybe a bit too "magic" (what if client doesn't have a concept of command? can the LS be sure the command exists on client side?)
  • add a new executeCommand operation, in the direction LS -> client, allowing a server to explicitly request a client to execute a command (with proper capability declaration, error handling, ...)
  • to avoid extra round trip, maybe add a flag on the Command returned by textDocument/codeAction to precise if this is a client side or a server side command
@kdvolder
Copy link

kdvolder commented Mar 21, 2018

We have another use case where executing client-side commands would fill a gap. What we need is this bit of @henryju 's proposal:

add a new executeCommand operation, in the direction LS -> client, allowing a server to explicitly request a client to execute a command (with proper capability declaration, error handling, ...)

See here for some details about our use case:

eclipse-jdtls/eclipse.jdt.ls#595

Summary: what we are really after is mechanism for one language server process (i.e. eclipse.jdt.ls) to send a 'message' to another language server (i.e. sts4 spring-boot language server).

If the jdt.ls could execute a command on the client-side, and the sts4 language server registers itself as a handler for this command, this makes that kind of server <-> server communication possible.

Some unrelated feedback on @henryju proposals.

to avoid extra round trip, maybe add a flag on the Command returned by textDocument/codeAction to precise if this is a client side or a server side command

I don't think this is necessary. In some sense all commands are 'client side' commands. But some client-side commands are implemented (on the client-side) by a handler that forwards them to a particular language server (because that server has registered itself as a handler for the command registerCapability). Therefore, I think the client knows exactly which commands exist (it contains the central command registry) and it also knows which commands it should handle locally itself and which it should forward to a particular server. So I think a flag to mark command as 'client-side' or 'server-side' explicitly is probably redundant.

@henryju
Copy link
Contributor Author

henryju commented Mar 22, 2018

I forgot the fact server was declaring commands he was able to handle, so indeed, no need for a special flag.

@kdvolder
Copy link

There actually seems to be some disagreement around what is the correct way to interpret the spec. So all my talk above about commands being entered into some kind of 'central command registry' on the client side... This is maybe just my interpretation. Just an FYI. After becoming aware of the confusion, I raised ticket to try and get some clarification around the intended mechanics here: #432

@dbaeumer
Copy link
Member

dbaeumer commented Apr 9, 2018

@henryju the commands returned from a code action or for example inside a code completion item must not necessarily be executed on the server. Only those commands are routed back to the server for which the server either return the id in the initialize response under executeCommandProvider or registered the command execution provider dynamically. All other commands can be handled on the client side. I am open to add a request from server -> client to trigger a command execution. Would be great to receive this as a PR following the guidelines here: https://github.com/Microsoft/language-server-protocol/blob/master/contributing.md

See also my comments in #432

@henryju
Copy link
Contributor Author

henryju commented Apr 9, 2018

The clarification on #432 (= it is possible to execute any command from a code action, not only the one from the same server) are enough to me.
We currently don't have the need to run a command at a different moment (like @kdvolder use case). So don't wait for me if you want to propose an addition to the protocol ;)

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

3 participants