From 7d2eb000b078143e9fa6225d00ef52fc7c606fdf Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 10 Nov 2020 18:20:01 +0100 Subject: 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. --- editors/code/src/client.ts | 21 ++++++++++++--------- editors/code/src/commands.ts | 11 ++++++----- editors/code/src/lsp_ext.ts | 6 ------ 3 files changed, 18 insertions(+), 20 deletions(-) (limited to 'editors') 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'; import * as Is from 'vscode-languageclient/lib/common/utils/is'; import { DocumentSemanticsTokensSignature, DocumentSemanticsTokensEditsSignature, DocumentRangeSemanticTokensSignature } from 'vscode-languageclient/lib/common/semanticTokens'; import { assert } from './util'; +import { WorkspaceEdit } from 'vscode'; function renderCommand(cmd: ra.CommandLink) { 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 return Promise.resolve(null); }); }, - // Using custom handling of CodeActions where each code action is resolved lazily - // That's why we are not waiting for any command or edits + // Using custom handling of CodeActions to support action groups and snippet edits. + // Note that this means we have to re-implement lazy edit resolving ourselves as well. 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), @@ -99,16 +100,15 @@ export function createClient(serverPath: string, cwd: string): lc.LanguageClient const kind = client.protocol2CodeConverter.asCodeActionKind((item as any).kind); const action = new vscode.CodeAction(item.title, kind); const group = (item as any).group; - const id = (item as any).id; - const resolveParams: ra.ResolveCodeActionParams = { - id: id, - codeActionParams: params - }; action.command = { command: "rust-analyzer.resolveCodeAction", title: item.title, - arguments: [resolveParams], + arguments: [item], }; + + // Set a dummy edit, so that VS Code doesn't try to resolve this. + action.edit = new WorkspaceEdit(); + if (group) { let entry = groups.get(group); if (!entry) { @@ -134,6 +134,10 @@ export function createClient(serverPath: string, cwd: string): lc.LanguageClient return { label: item.title, arguments: item.command!!.arguments!![0] }; })], }; + + // Set a dummy edit, so that VS Code doesn't try to resolve this. + action.edit = new WorkspaceEdit(); + result[index] = action; } } @@ -164,7 +168,6 @@ class ExperimentalFeatures implements lc.StaticFeature { const caps: any = capabilities.experimental ?? {}; caps.snippetTextEdit = true; caps.codeActionGroup = true; - caps.resolveCodeAction = true; caps.hoverActions = true; caps.statusNotification = true; 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 { } export function applyActionGroup(_ctx: Ctx): Cmd { - return async (actions: { label: string; arguments: ra.ResolveCodeActionParams }[]) => { + return async (actions: { label: string; arguments: lc.CodeAction }[]) => { const selectedAction = await vscode.window.showQuickPick(actions); if (!selectedAction) return; vscode.commands.executeCommand( @@ -442,12 +442,13 @@ export function openDocs(ctx: Ctx): Cmd { export function resolveCodeAction(ctx: Ctx): Cmd { const client = ctx.client; - return async (params: ra.ResolveCodeActionParams) => { - const item: lc.WorkspaceEdit = await client.sendRequest(ra.resolveCodeAction, params); - if (!item) { + return async (params: lc.CodeAction) => { + params.command = undefined; + const item = await client.sendRequest(lc.CodeActionResolveRequest.type, params); + if (!item.edit) { return; } - const edit = client.protocol2CodeConverter.asWorkspaceEdit(item); + const edit = client.protocol2CodeConverter.asWorkspaceEdit(item.edit); await applySnippetWorkspaceEdit(edit); }; } 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("experimental/parentModule"); -export interface ResolveCodeActionParams { - id: string; - codeActionParams: lc.CodeActionParams; -} -export const resolveCodeAction = new lc.RequestType('experimental/resolveCodeAction'); - export interface JoinLinesParams { textDocument: lc.TextDocumentIdentifier; ranges: lc.Range[]; -- cgit v1.2.3