Description
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 :)