about summary refs log tree commit diff
path: root/editors/code/src/client.ts
diff options
context:
space:
mode:
authorAleksey Kladov <aleksey.kladov@gmail.com>2020-05-18 01:53:55 +0200
committerAleksey Kladov <aleksey.kladov@gmail.com>2020-05-19 20:28:27 +0200
commit3dd68c1ba3e72a0959bcdaa46e730a7ae4d9ed4c (patch)
treee7794cbdea1ffb7f45d2d87330b6e15c16c3942b /editors/code/src/client.ts
parent2bf6b16a7f174ea3f581f26f642b4febff0b9ce8 (diff)
downloadrust-3dd68c1ba3e72a0959bcdaa46e730a7ae4d9ed4c.tar.gz
rust-3dd68c1ba3e72a0959bcdaa46e730a7ae4d9ed4c.zip
Implement client-side of SnippetTextEdit
Diffstat (limited to 'editors/code/src/client.ts')
-rw-r--r--editors/code/src/client.ts48
1 files changed, 46 insertions, 2 deletions
diff --git a/editors/code/src/client.ts b/editors/code/src/client.ts
index 2067738ea6c..fac1a0be318 100644
--- a/editors/code/src/client.ts
+++ b/editors/code/src/client.ts
@@ -31,7 +31,39 @@ export function createClient(serverPath: string, cwd: string): lc.LanguageClient
                 const res = await next(document, token);
                 if (res === undefined) throw new Error('busy');
                 return res;
+            },
+            async provideCodeActions(document: vscode.TextDocument, range: vscode.Range, context: vscode.CodeActionContext, token: vscode.CancellationToken, _next: lc.ProvideCodeActionsSignature) {
+                const params: lc.CodeActionParams = {
+                    textDocument: client.code2ProtocolConverter.asTextDocumentIdentifier(document),
+                    range: client.code2ProtocolConverter.asRange(range),
+                    context: client.code2ProtocolConverter.asCodeActionContext(context)
+                };
+                return client.sendRequest(lc.CodeActionRequest.type, params, token).then((values) => {
+                    if (values === null) return undefined;
+                    const result: (vscode.CodeAction | vscode.Command)[] = [];
+                    for (const item of values) {
+                        if (lc.CodeAction.is(item)) {
+                            const action = client.protocol2CodeConverter.asCodeAction(item);
+                            if (isSnippetEdit(item)) {
+                                action.command = {
+                                    command: "rust-analyzer.applySnippetWorkspaceEdit",
+                                    title: "",
+                                    arguments: [action.edit],
+                                };
+                                action.edit = undefined;
+                            }
+                            result.push(action);
+                        } else {
+                            const command = client.protocol2CodeConverter.asCommand(item);
+                            result.push(command);
+                        }
+                    }
+                    return result;
+                },
+                    (_error) => undefined
+                );
             }
+
         } as any
     };
 
@@ -42,7 +74,7 @@ export function createClient(serverPath: string, cwd: string): lc.LanguageClient
         clientOptions,
     );
 
-    // To turn on all proposed features use: res.registerProposedFeatures();
+    // To turn on all proposed features use: client.registerProposedFeatures();
     // Here we want to enable CallHierarchyFeature and SemanticTokensFeature
     // since they are available on stable.
     // Note that while these features are stable in vscode their LSP protocol
@@ -58,8 +90,20 @@ class SnippetTextEditFeature implements lc.StaticFeature {
     fillClientCapabilities(capabilities: lc.ClientCapabilities): void {
         const caps: any = capabilities.experimental ?? {};
         caps.snippetTextEdit = true;
-        capabilities.experimental = caps
+        capabilities.experimental = caps;
     }
     initialize(_capabilities: lc.ServerCapabilities<any>, _documentSelector: lc.DocumentSelector | undefined): void {
     }
 }
+
+function isSnippetEdit(action: lc.CodeAction): boolean {
+    const documentChanges = action.edit?.documentChanges ?? [];
+    for (const edit of documentChanges) {
+        if (lc.TextDocumentEdit.is(edit)) {
+            if (edit.edits.some((indel) => (indel as any).insertTextFormat === lc.InsertTextFormat.Snippet)) {
+                return true;
+            }
+        }
+    }
+    return false;
+}