mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-13 13:48:50 +00:00
Add snippetTextEdit protocol extension
This commit is contained in:
parent
fa2e5299c3
commit
a752853350
3 changed files with 57 additions and 5 deletions
|
@ -275,6 +275,7 @@ impl Config {
|
||||||
{
|
{
|
||||||
self.client_caps.code_action_literals = value;
|
self.client_caps.code_action_literals = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.completion.allow_snippets(false);
|
self.completion.allow_snippets(false);
|
||||||
if let Some(completion) = &doc_caps.completion {
|
if let Some(completion) = &doc_caps.completion {
|
||||||
if let Some(completion_item) = &completion.completion_item {
|
if let Some(completion_item) = &completion.completion_item {
|
||||||
|
@ -283,7 +284,6 @@ impl Config {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.assist.allow_snippets(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(window_caps) = caps.window.as_ref() {
|
if let Some(window_caps) = caps.window.as_ref() {
|
||||||
|
@ -291,5 +291,12 @@ impl Config {
|
||||||
self.client_caps.work_done_progress = value;
|
self.client_caps.work_done_progress = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.assist.allow_snippets(false);
|
||||||
|
if let Some(experimental) = &caps.experimental {
|
||||||
|
let enable =
|
||||||
|
experimental.get("snippetTextEdit").and_then(|it| it.as_bool()) == Some(true);
|
||||||
|
self.assist.allow_snippets(enable);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
34
docs/dev/lsp-extensions.md
Normal file
34
docs/dev/lsp-extensions.md
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
# LSP Extensions
|
||||||
|
|
||||||
|
This document describes LSP extensions used by rust-analyzer.
|
||||||
|
It's a best effort document, when in doubt, consult the source (and send a PR with clarification ;-) ).
|
||||||
|
We aim to upstream all non Rust-specific extensions to the protocol, but this is not a top priority.
|
||||||
|
All capabilities are enabled via `experimental` field of `ClientCapabilities`.
|
||||||
|
|
||||||
|
## `SnippetTextEdit`
|
||||||
|
|
||||||
|
**Capability**
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
{
|
||||||
|
"snippetTextEdit": boolean
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
If this capability is set, `WorkspaceEdit`s returned from `codeAction` requests might contain `SnippetTextEdit`s instead of usual `TextEdit`s:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
interface SnippetTextEdit extends TextEdit {
|
||||||
|
insertTextFormat?: InsertTextFormat;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
export interface TextDocumentEdit {
|
||||||
|
textDocument: VersionedTextDocumentIdentifier;
|
||||||
|
edits: (TextEdit | SnippetTextEdit)[];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
When applying such code action, the editor should insert snippet, with tab stops and placeholder.
|
||||||
|
At the moment, rust-analyzer guarantees that only a single edit will have `InsertTextFormat.Snippet`.
|
|
@ -35,7 +35,7 @@ export function createClient(serverPath: string, cwd: string): lc.LanguageClient
|
||||||
} as any
|
} as any
|
||||||
};
|
};
|
||||||
|
|
||||||
const res = new lc.LanguageClient(
|
const client = new lc.LanguageClient(
|
||||||
'rust-analyzer',
|
'rust-analyzer',
|
||||||
'Rust Analyzer Language Server',
|
'Rust Analyzer Language Server',
|
||||||
serverOptions,
|
serverOptions,
|
||||||
|
@ -47,8 +47,19 @@ export function createClient(serverPath: string, cwd: string): lc.LanguageClient
|
||||||
// since they are available on stable.
|
// since they are available on stable.
|
||||||
// Note that while these features are stable in vscode their LSP protocol
|
// Note that while these features are stable in vscode their LSP protocol
|
||||||
// implementations are still in the "proposed" category for 3.16.
|
// implementations are still in the "proposed" category for 3.16.
|
||||||
res.registerFeature(new CallHierarchyFeature(res));
|
client.registerFeature(new CallHierarchyFeature(client));
|
||||||
res.registerFeature(new SemanticTokensFeature(res));
|
client.registerFeature(new SemanticTokensFeature(client));
|
||||||
|
client.registerFeature(new SnippetTextEditFeature());
|
||||||
|
|
||||||
return res;
|
return client;
|
||||||
|
}
|
||||||
|
|
||||||
|
class SnippetTextEditFeature implements lc.StaticFeature {
|
||||||
|
fillClientCapabilities(capabilities: lc.ClientCapabilities): void {
|
||||||
|
const caps: any = capabilities.experimental ?? {};
|
||||||
|
caps.snippetTextEdit = true;
|
||||||
|
capabilities.experimental = caps
|
||||||
|
}
|
||||||
|
initialize(_capabilities: lc.ServerCapabilities<any>, _documentSelector: lc.DocumentSelector | undefined): void {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue