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

Consider executeCommandProvider for multi server #45

Closed
mtsmfm opened this issue Jan 7, 2018 · 7 comments
Closed

Consider executeCommandProvider for multi server #45

mtsmfm opened this issue Jan 7, 2018 · 7 comments
Assignees
Labels
info-needed Issue requires more information from poster question

Comments

@mtsmfm
Copy link

mtsmfm commented Jan 7, 2018

Thank you for the giving awesome samples.

How can we implement multi server with executeCommandProvider?

I met command already exists error.

https://github.com/Microsoft/vscode/blob/8e0baeddeb7ba1b563233335bc28e37163669747/src/vs/workbench/api/node/extHostCommands.ts#L65

@jrieken jrieken added the info-needed Issue requires more information from poster label Jan 8, 2018
@jrieken
Copy link
Member

jrieken commented Jan 8, 2018

@mtsmfm Can you provide some more context please? Is executeCommandProvider the name of your command. The error you point to happens when registering the same command twice.

@mtsmfm
Copy link
Author

mtsmfm commented Jan 17, 2018

@jrieken Sorry for being late.

I created an example extension to describe this problem:

https://github.com/Microsoft/vscode-extension-samples/compare/master...mtsmfm:command-with-multi-server?expand=1

Please try this extension with https://github.com/mtsmfm/example-workspace

This extension just inserts workspace folder name as a code action.
So it should insert file:///path/to/example-workspace/foo for foo/foo.txt and file:///path/to/example-workspace/bar for bar/bar.txt.
But I got file:///path/to/example-workspace/foo for bar/bar.txt.

vscode

@mtsmfm
Copy link
Author

mtsmfm commented Jan 17, 2018

I met command already exists error.

Actually, we can't notice this error normally because it's suppressed in this line:

https://github.com/Microsoft/vscode-languageserver-node/blob/020764e3eacc76138ffbf63f09489adbfb9e1be8/client/src/client.ts#L2546

@mtsmfm
Copy link
Author

mtsmfm commented Feb 26, 2018

@jrieken Isn't this explanation enough?

@mtsmfm
Copy link
Author

mtsmfm commented Mar 11, 2018

@jrieken I guess you're busy though, could you have a look at this?
I think this is a critical problem to provide commands/actions from multi-server.

@nwolverson
Copy link

I just ran into this, been using a multi-server LSP setup following the example here without realising the major limitation that it won't even initialize if it contains an executeCommandProvider. If it can't be resolved it could at least be listed as a limitation.

(My plan is to avoid executeCommandProvider and manually register/proxy commands to the appropriate LS server)

@Tehnix
Copy link

Tehnix commented Apr 1, 2018

I think this should be related to this one.

What I've ended up doing is using a global clients: Map<string, LanguageClient> (as showed in the multi-server lsp example) and then I locate the correct client for when I have to launch commands. Something like,

async function registerHiePointCommand(name: string,
                                       command: string,
                                       context: ExtensionContext) {
  const editorCmd = commands.registerTextEditorCommand(name, (editor, edit) => {
    const cmd = {
      command,
      arguments: [
        {
          file: editor.document.uri.toString(),
          pos: editor.selections[0].active,
        },
      ],
    };
    // Get the current file and workspace folder.
    const uri = editor.document.uri;
    const folder = workspace.getWorkspaceFolder(uri);
    // If there is a client registered for this workspace, use that client.
    if (clients.has(folder.uri.toString())) {
      const client = clients.get(folder.uri.toString());
      client.sendRequest('workspace/executeCommand', cmd).then(hints => {
        return true;
      }, e => {
        console.error(e);
      });
    }
  });
  context.subscriptions.push(editorCmd);
}

It gets the current file, then looks up the workspace folder. It uses this folder.uri.toString() as the key for the language server.

Then to get rid of the command already exists, I simply check if commands have been registered, else I register them. E.g. a global let hieCommandsRegistered: boolean = false;, and then check if (!hieCommandsRegistered) { ...; hieCommandsRegistered = true; }.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
info-needed Issue requires more information from poster question
Projects
None yet
Development

No branches or pull requests

4 participants