Skip to content

Commit

Permalink
feat(lsp_ext): ResolveCodeAction extension
Browse files Browse the repository at this point in the history
FYI #256
  • Loading branch information
fannheyward committed Jun 4, 2020
1 parent d9e8102 commit ddd83c5
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 15 deletions.
47 changes: 32 additions & 15 deletions src/client.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,26 @@
import { Executable, LanguageClient, LanguageClientOptions, ServerOptions, StaticFeature, Uri, workspace } from 'coc.nvim';
import { ClientCapabilities, CodeAction, CodeActionParams, CodeActionRequest, Command, InsertTextFormat, TextDocumentEdit } from 'vscode-languageserver-protocol';
import { ClientCapabilities, CodeAction, CodeActionParams, CodeActionRequest, Command } from 'vscode-languageserver-protocol';
import * as ra from './lsp_ext';

class ExperimentalFeatures implements StaticFeature {
fillClientCapabilities(capabilities: ClientCapabilities): void {
const caps: any = capabilities.experimental ?? {};
caps.snippetTextEdit = true;
caps.resolveCodeAction = true;
capabilities.experimental = caps;
}
initialize(): void {}
}

function isSnippetEdit(action: CodeAction): boolean {
const documentChanges = action.edit?.documentChanges ?? [];
for (const edit of documentChanges) {
if (TextDocumentEdit.is(edit)) {
if (edit.edits.some((indel) => (indel as any).insertTextFormat === InsertTextFormat.Snippet)) {
return true;
}
}
}
return false;
function isCodeActionWithoutEditsAndCommands(value: any): boolean {
const candidate: CodeAction = value;
return (
candidate &&
(candidate.diagnostics === void 0 || Array.isArray(candidate.diagnostics)) &&
(candidate.kind === void 0 || typeof candidate.kind === 'string') &&
candidate.edit === void 0 &&
candidate.command === void 0
);
}

export function createClient(bin: string): LanguageClient {
Expand Down Expand Up @@ -57,11 +58,27 @@ export function createClient(bin: string): LanguageClient {
if (values === null) return undefined;
const result: (CodeAction | Command)[] = [];
for (const item of values) {
if (CodeAction.is(item) && isSnippetEdit(item)) {
item.command = Command.create('', 'rust-analyzer.applySnippetWorkspaceEdit', item.edit);
item.edit = undefined;
// In our case we expect to get code edits only from diagnostics
if (CodeAction.is(item)) {
result.push(item);
continue;
}
result.push(item);

if (!isCodeActionWithoutEditsAndCommands(item)) {
console.error('isCodeActionWithoutEditsAndCommands:', item.title);
continue;
}

const resolveParams: ra.ResolveCodeActionParams = {
id: (item as any).id,
codeActionParams: params,
};
const command: Command = {
command: 'rust-analyzer.resolveCodeAction',
title: item.title,
arguments: [resolveParams],
};
result.push(CodeAction.create(item.title, command));
}
return result;
},
Expand Down
9 changes: 9 additions & 0 deletions src/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -313,3 +313,12 @@ export function applySnippetWorkspaceEditCommand(): Cmd {
await applySnippetWorkspaceEdit(edit);
};
}

export function resolveCodeAction(ctx: Ctx): Cmd {
const client = ctx.client;
return async (params: ra.ResolveCodeActionParams) => {
const edit: WorkspaceEdit = await client.sendRequest(ra.resolveCodeAction, params);
if (!edit) return;
await applySnippetWorkspaceEdit(edit);
};
}
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ export async function activate(context: ExtensionContext): Promise<void> {

ctx.registerCommand('analyzerStatus', cmds.analyzerStatus);
ctx.registerCommand('applySnippetWorkspaceEdit', cmds.applySnippetWorkspaceEditCommand);
ctx.registerCommand('resolveCodeAction', cmds.resolveCodeAction);
ctx.registerCommand('collectGarbage', cmds.collectGarbage);
ctx.registerCommand('expandMacro', cmds.expandMacro);
ctx.registerCommand('joinLines', cmds.joinLines);
Expand Down
6 changes: 6 additions & 0 deletions src/lsp_ext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,12 @@ export const matchingBrace = new lc.RequestType<MatchingBraceParams, lc.Position

export const parentModule = new lc.RequestType<lc.TextDocumentPositionParams, lc.LocationLink[], void>('experimental/parentModule');

export interface ResolveCodeActionParams {
id: string;
codeActionParams: lc.CodeActionParams;
}
export const resolveCodeAction = new lc.RequestType<ResolveCodeActionParams, lc.WorkspaceEdit, unknown>('experimental/resolveCodeAction');

export interface JoinLinesParams {
textDocument: lc.TextDocumentIdentifier;
ranges: lc.Range[];
Expand Down

0 comments on commit ddd83c5

Please sign in to comment.