Skip to content

Allow CodeActions to specify cursor position #724

Closed
microsoft/vscode-languageserver-node
#1343
@matklad

Description

@matklad

EDIT: We now documented this as a proper extension: https://github.com/rust-analyzer/rust-analyzer/blob/master/docs/dev/lsp-extensions.md#snippet-textedit. lsp-mode for emacs implements it: emacs-lsp/lsp-mode@9eb3324

WorkspaceEdit intentionally avoids speaking about cursor position, just like the rest of the protocol.

We however slightly bend this rule for completions, where we allow $0 snippets which is a way to place the cursor.

I want to argue that a similar feature is required for code actions.

Here are a couple of examples:

add derive

For add derive in rust-analyzer, I want to turn this (| is the cursor)

struct Foo {
    f: f64,|
}

into this

#[derive(|)]
struct Foo {
    f: f64,
}

It's pretty important that | is in the derive, such that the user can immediately type/complete #[derive(Debug, Clone, Copy)] incantation. Furthermore, the code action is available even if #[derive] already exists on the type: in this case, all the action does is it moves the cursor (which is still very convenient for the user)

create mod

Again, in rust-analyzer, for mod foo; I want to provide a fix which creates an foo.rs file, opens it in the editor and places the cursor at the start of the file (I can imagine an extension where the file is pre-filled with licensing boilerplate, and the cursor should be after it). Note that this is similar to #612

Note that, unlike the completions case, we can't just special-case code actions and add insertTextFormat on code-action itself: the reason is that lazy code-actions are resolved in a round-about way via a command and applyWorkspaceEdit request sent from the server to the client. So looks like we need to add this ability directly to WorkspaceEdit. Perhaps adding an

insertTextFormat?: InsertTextFormat

to the TextEdit (with a corresponding opt-in capability) will do the trick? The insertTextFormat on CompletionItem then becomes redundant though :)

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions