Skip to content

Standardize LSP Command like 'references', 'implementations', 'triggetSuggest', 'openUri' #788

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
angelozerr opened this issue Jul 4, 2019 · 8 comments
Labels
code lens feature-request Request for new features or functionality
Milestone

Comments

@angelozerr
Copy link
Contributor

angelozerr commented Jul 4, 2019

A lot of language server provides references and implementations CodeLens. As there are no standardization about those 2 commands, it causes extra code:

  • On server side, it requires that :

    • CodeLens creates a custom references and implementations command name (ex: java.show.references for jdt.ls)
    • This command name is generated only if client can support references (click on references CodeLens must open the client references dialog). For instance client send a custom capability (ex : supportReferences) in the InitializeParams.
  • On client side:

    • Client send a custom capability (ex : supportReferences) in the InitializeParams.
    • Client implement the custom command (ex: java.show.references for jdt.ls) to open the references dialog.

To avoid doing those extra code (on server and client side) and give the capability to have references and implementations which works directly (without implementing custom command on client side and without implementing custom capability on server side), we could standardize the 2 commands. The idea is to consume a language server in a client and click on references and implementations works directly without extra code.

The idea is to provide for instance CodeLensKind (or perhaps a CommandKind) like this:

export namespace CodeLensKind {

	export const References: CodeLensKind = 'references';

	export const Implementations: CodeLensKind = 'implementations';

}
  • The client will send a CodeKindKindCapabilities in the InitializeParams with (references and implementations for instance).
  • vscode could implement those 2 commands by sending references or implementations request to the server. The only requirement is that server must return a CodeLens with the standardized Command name (ex: references, or implementations) and an argument list with the URI document and position.

Here the vscode implementation for references:

context.subscriptions.push(commands.registerCommand(CodeLensKind .References, (uriString: string, position: Position) => {
        const uri = Uri.parse(uriString);
        workspace.openTextDocument(uri).then(document => {
          // Consume references service from the Language Server
          let param = languageClient.code2ProtocolConverter.asTextDocumentPositionParams(document, position);
          languageClient.sendRequest(ReferencesRequest.type, param).then(locations => {
            commands.executeCommand('editor.action.showReferences' uri, languageClient.protocol2CodeConverter.asPosition(position), locations.map(languageClient.protocol2CodeConverter.asLocation));
          })
        })
      }));
  • on server side, Codelens must be created with a Command whit name CodeLensKind.References (only if client support it) and with the uri and position and that's all!
@dbaeumer dbaeumer added the feature-request Request for new features or functionality label Jul 5, 2019
@dbaeumer dbaeumer added this to the On Deck milestone Jul 5, 2019
@dbaeumer
Copy link
Member

dbaeumer commented Jul 5, 2019

Makes sense to me.

@dbaeumer dbaeumer modified the milestones: On Deck, Backlog Oct 31, 2019
@angelozerr
Copy link
Contributor Author

Here the default command that LSP could provide:

  • open references
  • open implementations
  • open URL (ex : in Java we can show URL of the REST services as codelens)

@angelozerr
Copy link
Contributor Author

@dbaeumer I retrigger the issue and I think the best thing is to standardize LSP commands because commands acn be used in Codelens, CodeAction, and Completion.

I discover today a new usecase with CSS language server when you open completion, it provides color completion item:;

{
            "label": "color",
            "documentation": {
                "kind": "markdown",
                "value": "Sets the color of an element's text\n\n(Edge 12, Firefox 1, Safari 1, Chrome 1, IE 3, Opera 3)\n\nSyntax: <color>\n\n[MDN Reference](https://developer.mozilla.org/docs/Web/CSS/color)"
            },
            "tags": [],
            "textEdit": {
                "range": {
                    "start": {
                        "line": 6,
                        "character": 12
                    },
                    "end": {
                        "line": 6,
                        "character": 13
                    }
                },
                "newText": "color: $0;"
            },
            "insertTextFormat": 2,
            "kind": 10,
            "command": {
                "title": "Suggest",
                "command": "editor.action.triggerSuggest"
            },
            "sortText": "d_a1"
        }

and when you apply completion, it generates color: |; and reopen the completion at | to show available colors as completion.

to do that it uses

"command": {
                "title": "Suggest",
                "command": "editor.action.triggerSuggest"
            },

As you can notice editor.action.triggerSuggest is a vscode command, so it will work only with vscode. If we standardize command like lsp.editor.action.triggerSuggest, any language servers could use it and all LSP client which implement the spec will benefit with this reopen completion when CSS color is applied.

We could have a CommandKind list and LSP client could set the list of CommandKind which are supported. Language servers could use this command kind list to know if iy should generate the command or not.

@angelozerr
Copy link
Contributor Author

angelozerr commented Jan 9, 2024

@aeschli what do you think with my LSP CommandKind lsp.editor.action.triggerSuggest proposition?

@aeschli
Copy link
Contributor

aeschli commented Jan 10, 2024

For the completion case mit might be easier to just add a property retrigger and use it as a hint for clients.

@rchl
Copy link
Contributor

rchl commented Jan 10, 2024

On the other hand, completion can include a command and in that case it might be less clear when the "retrigger" should trigger. I feel that a dedicated command might have more obvious semantics.

Also, if we have "retrigger" for completions then we'd still need something else for other cases anyway and we end up with more ways of doing the same.

Not saying that those points make you suggestion unfeasible but something to think about.

@angelozerr angelozerr changed the title Standardize Command for 'references' and 'implementations' for CodeLens Standardize LSP Command like 'references', 'implementations', 'triggetSuggest', 'openUri' Jan 10, 2024
@rcjsuen
Copy link
Contributor

rcjsuen commented Oct 12, 2024

We have two other issues that are related to this (#565 and #1611) and this one was most recently commented on (January 2024).

What is the best way to help move this forward and get some consensus? 🤔

@dbaeumer
Copy link
Member

I would propose the following:

  • for each command we define with arguments it takes in the spec
  • we add a client capability listing the default command the client supports
  • we add type definitions for the arguments to the Node implementation so that we can get them in the meta model
  • we implement the last two for at least one client.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
code lens feature-request Request for new features or functionality
Projects
None yet
Development

No branches or pull requests

5 participants