aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2020-05-17 20:24:33 +0100
committerAleksey Kladov <[email protected]>2020-05-19 19:28:27 +0100
commita752853350639a915178ea900a51f3c45443795e (patch)
tree53fe8ac7cc20109436fb54dfde9ed1c4baba1ad2
parentfa2e5299c3332b99fcd09fd54e8d812a6c34b0cc (diff)
Add snippetTextEdit protocol extension
-rw-r--r--crates/rust-analyzer/src/config.rs9
-rw-r--r--docs/dev/lsp-extensions.md34
-rw-r--r--editors/code/src/client.ts19
3 files changed, 57 insertions, 5 deletions
diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs
index 063b1b316..d75c48597 100644
--- a/crates/rust-analyzer/src/config.rs
+++ b/crates/rust-analyzer/src/config.rs
@@ -275,6 +275,7 @@ impl Config {
275 { 275 {
276 self.client_caps.code_action_literals = value; 276 self.client_caps.code_action_literals = value;
277 } 277 }
278
278 self.completion.allow_snippets(false); 279 self.completion.allow_snippets(false);
279 if let Some(completion) = &doc_caps.completion { 280 if let Some(completion) = &doc_caps.completion {
280 if let Some(completion_item) = &completion.completion_item { 281 if let Some(completion_item) = &completion.completion_item {
@@ -283,7 +284,6 @@ impl Config {
283 } 284 }
284 } 285 }
285 } 286 }
286 self.assist.allow_snippets(false);
287 } 287 }
288 288
289 if let Some(window_caps) = caps.window.as_ref() { 289 if let Some(window_caps) = caps.window.as_ref() {
@@ -291,5 +291,12 @@ impl Config {
291 self.client_caps.work_done_progress = value; 291 self.client_caps.work_done_progress = value;
292 } 292 }
293 } 293 }
294
295 self.assist.allow_snippets(false);
296 if let Some(experimental) = &caps.experimental {
297 let enable =
298 experimental.get("snippetTextEdit").and_then(|it| it.as_bool()) == Some(true);
299 self.assist.allow_snippets(enable);
300 }
294 } 301 }
295} 302}
diff --git a/docs/dev/lsp-extensions.md b/docs/dev/lsp-extensions.md
new file mode 100644
index 000000000..d2ec6c021
--- /dev/null
+++ b/docs/dev/lsp-extensions.md
@@ -0,0 +1,34 @@
1# LSP Extensions
2
3This document describes LSP extensions used by rust-analyzer.
4It's a best effort document, when in doubt, consult the source (and send a PR with clarification ;-) ).
5We aim to upstream all non Rust-specific extensions to the protocol, but this is not a top priority.
6All capabilities are enabled via `experimental` field of `ClientCapabilities`.
7
8## `SnippetTextEdit`
9
10**Capability**
11
12```typescript
13{
14 "snippetTextEdit": boolean
15}
16```
17
18If this capability is set, `WorkspaceEdit`s returned from `codeAction` requests might contain `SnippetTextEdit`s instead of usual `TextEdit`s:
19
20```typescript
21interface SnippetTextEdit extends TextEdit {
22 insertTextFormat?: InsertTextFormat;
23}
24```
25
26```typescript
27export interface TextDocumentEdit {
28 textDocument: VersionedTextDocumentIdentifier;
29 edits: (TextEdit | SnippetTextEdit)[];
30}
31```
32
33When applying such code action, the editor should insert snippet, with tab stops and placeholder.
34At the moment, rust-analyzer guarantees that only a single edit will have `InsertTextFormat.Snippet`.
diff --git a/editors/code/src/client.ts b/editors/code/src/client.ts
index cffdcf11a..2067738ea 100644
--- a/editors/code/src/client.ts
+++ b/editors/code/src/client.ts
@@ -35,7 +35,7 @@ export function createClient(serverPath: string, cwd: string): lc.LanguageClient
35 } as any 35 } as any
36 }; 36 };
37 37
38 const res = new lc.LanguageClient( 38 const client = new lc.LanguageClient(
39 'rust-analyzer', 39 'rust-analyzer',
40 'Rust Analyzer Language Server', 40 'Rust Analyzer Language Server',
41 serverOptions, 41 serverOptions,
@@ -47,8 +47,19 @@ export function createClient(serverPath: string, cwd: string): lc.LanguageClient
47 // since they are available on stable. 47 // since they are available on stable.
48 // Note that while these features are stable in vscode their LSP protocol 48 // Note that while these features are stable in vscode their LSP protocol
49 // implementations are still in the "proposed" category for 3.16. 49 // implementations are still in the "proposed" category for 3.16.
50 res.registerFeature(new CallHierarchyFeature(res)); 50 client.registerFeature(new CallHierarchyFeature(client));
51 res.registerFeature(new SemanticTokensFeature(res)); 51 client.registerFeature(new SemanticTokensFeature(client));
52 client.registerFeature(new SnippetTextEditFeature());
52 53
53 return res; 54 return client;
55}
56
57class SnippetTextEditFeature implements lc.StaticFeature {
58 fillClientCapabilities(capabilities: lc.ClientCapabilities): void {
59 const caps: any = capabilities.experimental ?? {};
60 caps.snippetTextEdit = true;
61 capabilities.experimental = caps
62 }
63 initialize(_capabilities: lc.ServerCapabilities<any>, _documentSelector: lc.DocumentSelector | undefined): void {
64 }
54} 65}