Skip to content

Commit a95f695

Browse files
committed
Add support for SnippetTextEdit in code actions
1 parent a9144a7 commit a95f695

File tree

1 file changed

+61
-3
lines changed

1 file changed

+61
-3
lines changed

src/extension.ts

Lines changed: 61 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ import * as fse from 'fs-extra';
66
import * as os from 'os';
77
import * as path from 'path';
88
import * as semver from 'semver';
9-
import { CodeActionContext, commands, CompletionItem, ConfigurationTarget, Diagnostic, env, EventEmitter, ExtensionContext, extensions, IndentAction, InputBoxOptions, languages, MarkdownString, QuickPickItemKind, RelativePattern, TextDocument, TextEditorRevealType, UIKind, Uri, ViewColumn, window, workspace, WorkspaceConfiguration } from 'vscode';
10-
import { CancellationToken, CodeActionParams, CodeActionRequest, Command, CompletionRequest, DidChangeConfigurationNotification, ExecuteCommandParams, ExecuteCommandRequest, LanguageClientOptions, RevealOutputChannelOn } from 'vscode-languageclient';
9+
import { CodeActionContext, commands, CompletionItem, ConfigurationTarget, Diagnostic, env, EventEmitter, ExtensionContext, extensions, IndentAction, InputBoxOptions, languages, MarkdownString, QuickPickItemKind, Range, RelativePattern, SnippetString, SnippetTextEdit, TextDocument, TextEditorRevealType, UIKind, Uri, ViewColumn, window, workspace, WorkspaceConfiguration, WorkspaceEdit } from 'vscode';
10+
import { CancellationToken, CodeActionParams, CodeActionRequest, CodeActionResolveRequest, Command, CompletionRequest, DidChangeConfigurationNotification, ExecuteCommandParams, ExecuteCommandRequest, LanguageClientOptions, RevealOutputChannelOn } from 'vscode-languageclient';
1111
import { LanguageClient } from 'vscode-languageclient/node';
1212
import { apiManager } from './apiManager';
1313
import { ClientErrorHandler } from './clientErrorHandler';
@@ -235,6 +235,7 @@ export async function activate(context: ExtensionContext): Promise<ExtensionAPI>
235235
extractInterfaceSupport: true,
236236
advancedUpgradeGradleSupport: true,
237237
executeClientCommandSupport: true,
238+
snippetEditSupport: true,
238239
},
239240
triggerFiles,
240241
},
@@ -303,7 +304,60 @@ export async function activate(context: ExtensionContext): Promise<ExtensionAPI>
303304
}, (error) => {
304305
return client.handleFailedRequest(CodeActionRequest.type, token, error, []);
305306
});
306-
}
307+
},
308+
309+
resolveCodeAction: async (item, token, next) => {
310+
const client: LanguageClient = standardClient.getClient();
311+
const documentUris = [];
312+
const snippetEdits = [];
313+
const resolveCodeAction = async (item, token) => {
314+
return client.sendRequest(CodeActionResolveRequest.type, client.code2ProtocolConverter.asCodeActionSync(item), token).then(async (result) => {
315+
if (token.isCancellationRequested) {
316+
return item;
317+
}
318+
const docChanges = result.edit.documentChanges;
319+
for (const editType of docChanges) {
320+
if ("textDocument" in editType) {
321+
for (const edit of editType.edits) {
322+
if ("snippet" in edit) {
323+
documentUris.push(editType.textDocument.uri);
324+
snippetEdits.push(new SnippetTextEdit(asRange(edit.range), new SnippetString((edit as any).snippet.value)));
325+
}
326+
}
327+
}
328+
}
329+
const codeAction = await client.protocol2CodeConverter.asCodeAction(result, token);
330+
const docEdits = codeAction.edit.entries();
331+
const newWorkspaceEdit = new WorkspaceEdit();
332+
for (const doc of docEdits) {
333+
const uri = doc[0];
334+
if (documentUris.includes(uri.toString())) {
335+
const editList = [];
336+
for (const edit of doc[1]) {
337+
let isSnippet = false;
338+
snippetEdits.forEach((snippet, index) => {
339+
if (edit.range.isEqual(snippet.range) && documentUris[index] === uri.toString()) {
340+
editList.push(snippet);
341+
isSnippet = true;
342+
}
343+
});
344+
if (!isSnippet) {
345+
editList.push(edit);
346+
}
347+
}
348+
newWorkspaceEdit.set(uri, editList);
349+
} else {
350+
newWorkspaceEdit.set(uri, doc[1]);
351+
}
352+
}
353+
codeAction.edit = newWorkspaceEdit;
354+
return codeAction;
355+
}, (error) => {
356+
return client.handleFailedRequest(CodeActionResolveRequest.type, token, error, item);
357+
});
358+
};
359+
return resolveCodeAction(item, token);
360+
},
307361
},
308362
revealOutputChannelOn: RevealOutputChannelOn.Never,
309363
errorHandler: new ClientErrorHandler(extensionName),
@@ -1187,4 +1241,8 @@ function registerRestartJavaLanguageServerCommand(context: ExtensionContext) {
11871241
}));
11881242
}
11891243

1244+
function asRange(value) {
1245+
return value ? new Range(value.start.line, value.start.character, value.end.line, value.end.character) : undefined;
1246+
}
1247+
11901248

0 commit comments

Comments
 (0)