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

add support for LSP workspace/executeCommand message for initial use with Scala Metals #3300

Open
StephenWithPH opened this issue Aug 20, 2020 · 4 comments

Comments

@StephenWithPH
Copy link
Contributor

I'm using Metals via https://github.com/dense-analysis/ale/blob/master/ale_linters/scala/metals.vim (thanks, @zoonfafer!)

Metals needs users to import the build upon first use within a workspace (i.e., a Scala project). Once you do that, the Metals server exposes all the goodies necessary for a rich user experience.

To tell the Metals server to import the build, you POST to its /execute-command endpoint with command=build-import:

curl -XPOST http://localhost:5031/execute-command?command=build-import

The first time one does this in a project, it takes a while. Subsequent invocations take much less time.

Is there some standard pattern for this sort of thing in ALE's plugin ecosystem?

@zoonfafer
Copy link
Contributor

Would like to know about it also.

As a starting point, I would imagine the following might be relevant?

  • https://github.com/dense-analysis/ale/blob/master/autoload/ale/lsp/message.vim
    Perhaps a new function ale#lsp#message#ExecuteCommand(buffer, command) could be implemented here.
  • ale#lsp#Send(conn_id, message) -

    ale/autoload/ale/lsp.vim

    Lines 542 to 560 in 2b78568

    " Returns -1 when a message is sent, but no response is expected
    " 0 when the message is not sent and
    " >= 1 with the message ID when a response is expected.
    function! ale#lsp#Send(conn_id, message) abort
    let l:conn = get(s:connections, a:conn_id, {})
    if empty(l:conn)
    return 0
    endif
    if !l:conn.initialized
    throw 'LSP server not initialized yet!'
    endif
    let [l:id, l:data] = ale#lsp#CreateMessageData(a:message)
    call s:SendMessageData(l:conn, l:data)
    return l:id == 0 ? -1 : l:id
    endfunction

@StephenWithPH
Copy link
Contributor Author

StephenWithPH commented Aug 21, 2020

Having done more research, Metals' http approach is there only as a fallback for users when their LSP client doesn't support workspace/executeCommand (or other LSP methods):

The most popular LSP clients in editors like Vim currently have
limited support so that endpoints like window/showMessageRequest are ignored,
with no workaround for users to interact with the Metals language server.
This http client allows users in those editors to trigger server commands
and respond to UI dialogues through their browser instead.

(https://github.com/scalameta/metals/blob/a75b5f61577d2270ed435d956627ab5a7b996482/metals/src/main/scala/scala/meta/internal/metals/MetalsHttpClient.scala#L39-L43)


Perhaps a new function ale#lsp#message#ExecuteCommand(buffer, command) could be implemented here.

@zoonfafer ... I agree that adding standard LSP client support for workspace/executeCommand (relevant LSP spec) is the proper approach. This is far better than any http workaround.

We would also need to update the capabilities here:

ale/autoload/ale/lsp.vim

Lines 361 to 371 in 2b78568

\ 'workspace': {
\ 'applyEdit': v:false,
\ 'didChangeConfiguration': {
\ 'dynamicRegistration': v:false,
\ },
\ 'symbol': {
\ 'dynamicRegistration': v:false,
\ },
\ 'workspaceFolders': v:false,
\ 'configuration': v:false,
\ },

Given this change would add capabilities relevant for any LSP server that ALE can handle, I think it's reasonable to ask for @w0rp 's thoughts...

@w0rp : does the above approach seem reasonable?

@StephenWithPH StephenWithPH changed the title tell (via http post) Scala Metals to import the current project add support for LSP workspace/executeCommand message for initial use with Scala Metals Aug 21, 2020
@w0rp
Copy link
Member

w0rp commented Aug 29, 2020

Sending the workspace/executeCommand messages via a command in ALE is fine to do, as long as the code is simple enough. This may be related to "Code Actions" in some way. There's an issue for "Code Actions" here: #1466

@dassio
Copy link

dassio commented Sep 8, 2020

this is will also be really helpful for starting the eclipselsp DAP, right now vimspector are using YCM to do this one, but this could be made possible by ALE:

Ultimately, the way the debug server is started is:
something, somewhere starts up a jdt.ls instance with the debug adapter "bundle" passed as an additional initialisation option, and connects to it. In my case, this is my fork of ycmd.
something provides the capability send a Language Server Protocol 'executeCommand' message to that jdt.ls instance (In my case, this is :YcmCompleter ExectuteCommand )
you execute the LSP command java.execute.workspaceCommand with arguments [ 'vscode.java.startDebugSession' ] (In my case, this is :YcmCompleter ExectuteCommand vscode.java.startDebugSession, as in the above demo)

puremourning/vimspector#3 (comment)

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

4 participants