aboutsummaryrefslogtreecommitdiff
path: root/editors/code/src
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2020-11-10 17:20:01 +0000
committerAleksey Kladov <[email protected]>2020-11-10 17:48:46 +0000
commit7d2eb000b078143e9fa6225d00ef52fc7c606fdf (patch)
tree580d90bd250ffcd4b1c66570e5601761e58d1057 /editors/code/src
parentada5a88f8fd0a79af7ad6e0411acc1cce9ef32d5 (diff)
Switch to upstream protocol for resolving code action
Note that we have to maintain custom implementation on the client side: I don't see how to marry bulitin resolve support with groups and snippets.
Diffstat (limited to 'editors/code/src')
-rw-r--r--editors/code/src/client.ts21
-rw-r--r--editors/code/src/commands.ts11
-rw-r--r--editors/code/src/lsp_ext.ts6
3 files changed, 18 insertions, 20 deletions
diff --git a/editors/code/src/client.ts b/editors/code/src/client.ts
index d032b45b7..c9d032ead 100644
--- a/editors/code/src/client.ts
+++ b/editors/code/src/client.ts
@@ -4,6 +4,7 @@ import * as ra from '../src/lsp_ext';
4import * as Is from 'vscode-languageclient/lib/common/utils/is'; 4import * as Is from 'vscode-languageclient/lib/common/utils/is';
5import { DocumentSemanticsTokensSignature, DocumentSemanticsTokensEditsSignature, DocumentRangeSemanticTokensSignature } from 'vscode-languageclient/lib/common/semanticTokens'; 5import { DocumentSemanticsTokensSignature, DocumentSemanticsTokensEditsSignature, DocumentRangeSemanticTokensSignature } from 'vscode-languageclient/lib/common/semanticTokens';
6import { assert } from './util'; 6import { assert } from './util';
7import { WorkspaceEdit } from 'vscode';
7 8
8function renderCommand(cmd: ra.CommandLink) { 9function renderCommand(cmd: ra.CommandLink) {
9 return `[${cmd.title}](command:${cmd.command}?${encodeURIComponent(JSON.stringify(cmd.arguments))} '${cmd.tooltip!}')`; 10 return `[${cmd.title}](command:${cmd.command}?${encodeURIComponent(JSON.stringify(cmd.arguments))} '${cmd.tooltip!}')`;
@@ -75,8 +76,8 @@ export function createClient(serverPath: string, cwd: string): lc.LanguageClient
75 return Promise.resolve(null); 76 return Promise.resolve(null);
76 }); 77 });
77 }, 78 },
78 // Using custom handling of CodeActions where each code action is resolved lazily 79 // Using custom handling of CodeActions to support action groups and snippet edits.
79 // That's why we are not waiting for any command or edits 80 // Note that this means we have to re-implement lazy edit resolving ourselves as well.
80 async provideCodeActions(document: vscode.TextDocument, range: vscode.Range, context: vscode.CodeActionContext, token: vscode.CancellationToken, _next: lc.ProvideCodeActionsSignature) { 81 async provideCodeActions(document: vscode.TextDocument, range: vscode.Range, context: vscode.CodeActionContext, token: vscode.CancellationToken, _next: lc.ProvideCodeActionsSignature) {
81 const params: lc.CodeActionParams = { 82 const params: lc.CodeActionParams = {
82 textDocument: client.code2ProtocolConverter.asTextDocumentIdentifier(document), 83 textDocument: client.code2ProtocolConverter.asTextDocumentIdentifier(document),
@@ -99,16 +100,15 @@ export function createClient(serverPath: string, cwd: string): lc.LanguageClient
99 const kind = client.protocol2CodeConverter.asCodeActionKind((item as any).kind); 100 const kind = client.protocol2CodeConverter.asCodeActionKind((item as any).kind);
100 const action = new vscode.CodeAction(item.title, kind); 101 const action = new vscode.CodeAction(item.title, kind);
101 const group = (item as any).group; 102 const group = (item as any).group;
102 const id = (item as any).id;
103 const resolveParams: ra.ResolveCodeActionParams = {
104 id: id,
105 codeActionParams: params
106 };
107 action.command = { 103 action.command = {
108 command: "rust-analyzer.resolveCodeAction", 104 command: "rust-analyzer.resolveCodeAction",
109 title: item.title, 105 title: item.title,
110 arguments: [resolveParams], 106 arguments: [item],
111 }; 107 };
108
109 // Set a dummy edit, so that VS Code doesn't try to resolve this.
110 action.edit = new WorkspaceEdit();
111
112 if (group) { 112 if (group) {
113 let entry = groups.get(group); 113 let entry = groups.get(group);
114 if (!entry) { 114 if (!entry) {
@@ -134,6 +134,10 @@ export function createClient(serverPath: string, cwd: string): lc.LanguageClient
134 return { label: item.title, arguments: item.command!!.arguments!![0] }; 134 return { label: item.title, arguments: item.command!!.arguments!![0] };
135 })], 135 })],
136 }; 136 };
137
138 // Set a dummy edit, so that VS Code doesn't try to resolve this.
139 action.edit = new WorkspaceEdit();
140
137 result[index] = action; 141 result[index] = action;
138 } 142 }
139 } 143 }
@@ -164,7 +168,6 @@ class ExperimentalFeatures implements lc.StaticFeature {
164 const caps: any = capabilities.experimental ?? {}; 168 const caps: any = capabilities.experimental ?? {};
165 caps.snippetTextEdit = true; 169 caps.snippetTextEdit = true;
166 caps.codeActionGroup = true; 170 caps.codeActionGroup = true;
167 caps.resolveCodeAction = true;
168 caps.hoverActions = true; 171 caps.hoverActions = true;
169 caps.statusNotification = true; 172 caps.statusNotification = true;
170 capabilities.experimental = caps; 173 capabilities.experimental = caps;
diff --git a/editors/code/src/commands.ts b/editors/code/src/commands.ts
index 22509e874..cf34622c3 100644
--- a/editors/code/src/commands.ts
+++ b/editors/code/src/commands.ts
@@ -395,7 +395,7 @@ export function showReferences(ctx: Ctx): Cmd {
395} 395}
396 396
397export function applyActionGroup(_ctx: Ctx): Cmd { 397export function applyActionGroup(_ctx: Ctx): Cmd {
398 return async (actions: { label: string; arguments: ra.ResolveCodeActionParams }[]) => { 398 return async (actions: { label: string; arguments: lc.CodeAction }[]) => {
399 const selectedAction = await vscode.window.showQuickPick(actions); 399 const selectedAction = await vscode.window.showQuickPick(actions);
400 if (!selectedAction) return; 400 if (!selectedAction) return;
401 vscode.commands.executeCommand( 401 vscode.commands.executeCommand(
@@ -442,12 +442,13 @@ export function openDocs(ctx: Ctx): Cmd {
442 442
443export function resolveCodeAction(ctx: Ctx): Cmd { 443export function resolveCodeAction(ctx: Ctx): Cmd {
444 const client = ctx.client; 444 const client = ctx.client;
445 return async (params: ra.ResolveCodeActionParams) => { 445 return async (params: lc.CodeAction) => {
446 const item: lc.WorkspaceEdit = await client.sendRequest(ra.resolveCodeAction, params); 446 params.command = undefined;
447 if (!item) { 447 const item = await client.sendRequest(lc.CodeActionResolveRequest.type, params);
448 if (!item.edit) {
448 return; 449 return;
449 } 450 }
450 const edit = client.protocol2CodeConverter.asWorkspaceEdit(item); 451 const edit = client.protocol2CodeConverter.asWorkspaceEdit(item.edit);
451 await applySnippetWorkspaceEdit(edit); 452 await applySnippetWorkspaceEdit(edit);
452 }; 453 };
453} 454}
diff --git a/editors/code/src/lsp_ext.ts b/editors/code/src/lsp_ext.ts
index fc8e120b3..d320c3cd7 100644
--- a/editors/code/src/lsp_ext.ts
+++ b/editors/code/src/lsp_ext.ts
@@ -43,12 +43,6 @@ export const matchingBrace = new lc.RequestType<MatchingBraceParams, lc.Position
43 43
44export const parentModule = new lc.RequestType<lc.TextDocumentPositionParams, lc.LocationLink[], void>("experimental/parentModule"); 44export const parentModule = new lc.RequestType<lc.TextDocumentPositionParams, lc.LocationLink[], void>("experimental/parentModule");
45 45
46export interface ResolveCodeActionParams {
47 id: string;
48 codeActionParams: lc.CodeActionParams;
49}
50export const resolveCodeAction = new lc.RequestType<ResolveCodeActionParams, lc.WorkspaceEdit, unknown>('experimental/resolveCodeAction');
51
52export interface JoinLinesParams { 46export interface JoinLinesParams {
53 textDocument: lc.TextDocumentIdentifier; 47 textDocument: lc.TextDocumentIdentifier;
54 ranges: lc.Range[]; 48 ranges: lc.Range[];