Skip to content

Commit

Permalink
Add support for SnippetTextEdit in code actions (#3730)
Browse files Browse the repository at this point in the history
- Add snippetEditSupport extended client capability from JDT-LS
- Handle possible code action conversion (LSP to VS Code) in middleware.resolveCodeAction
  • Loading branch information
hopehadfield authored Sep 3, 2024
1 parent e3bc9b5 commit 1d7163f
Showing 1 changed file with 57 additions and 5 deletions.
62 changes: 57 additions & 5 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import * as fse from 'fs-extra';
import * as os from 'os';
import * as path from 'path';
import * as semver from 'semver';
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';
import { CancellationToken, CodeActionParams, CodeActionRequest, Command, CompletionRequest, DidChangeConfigurationNotification, ExecuteCommandParams, ExecuteCommandRequest, LanguageClientOptions, RevealOutputChannelOn } from 'vscode-languageclient';
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';
import { CancellationToken, CodeActionParams, CodeActionRequest, CodeActionResolveRequest, Command, CompletionRequest, DidChangeConfigurationNotification, ExecuteCommandParams, ExecuteCommandRequest, LanguageClientOptions, RevealOutputChannelOn } from 'vscode-languageclient';
import { LanguageClient } from 'vscode-languageclient/node';
import { apiManager } from './apiManager';
import { ClientErrorHandler } from './clientErrorHandler';
Expand Down Expand Up @@ -235,6 +235,7 @@ export async function activate(context: ExtensionContext): Promise<ExtensionAPI>
extractInterfaceSupport: true,
advancedUpgradeGradleSupport: true,
executeClientCommandSupport: true,
snippetEditSupport: true,
},
triggerFiles,
},
Expand Down Expand Up @@ -303,7 +304,60 @@ export async function activate(context: ExtensionContext): Promise<ExtensionAPI>
}, (error) => {
return client.handleFailedRequest(CodeActionRequest.type, token, error, []);
});
}
},

resolveCodeAction: async (item, token, next) => {
const client: LanguageClient = standardClient.getClient();
const documentUris = [];
const snippetEdits = [];
const resolveCodeAction = async (item, token) => {
return client.sendRequest(CodeActionResolveRequest.type, client.code2ProtocolConverter.asCodeActionSync(item), token).then(async (result) => {
if (token.isCancellationRequested) {
return item;
}
const docChanges = result.edit !== undefined ? result.edit.documentChanges : undefined;
if (docChanges !== undefined) {
for (const docChange of docChanges) {
if ("textDocument" in docChange) {
for (const edit of docChange.edits) {
if ("snippet" in edit) {
documentUris.push(docChange.textDocument.uri);
snippetEdits.push(new SnippetTextEdit(client.protocol2CodeConverter.asRange((edit as any).range), new SnippetString((edit as any).snippet.value)));
}
}
}
}
const codeAction = await client.protocol2CodeConverter.asCodeAction(result, token);
const docEdits = codeAction.edit !== undefined? codeAction.edit.entries() : [];
for (const docEdit of docEdits) {
const uri = docEdit[0];
if (documentUris.includes(uri.toString())) {
const editList = [];
for (const edit of docEdit[1]) {
let isSnippet = false;
snippetEdits.forEach((snippet, index) => {
if (edit.range.isEqual(snippet.range) && documentUris[index] === uri.toString()) {
editList.push(snippet);
isSnippet = true;
}
});
if (!isSnippet) {
editList.push(edit);
}
}
codeAction.edit.set(uri, null);
codeAction.edit.set(uri, editList);
}
}
return codeAction;
}
return await client.protocol2CodeConverter.asCodeAction(result, token);
}, (error) => {
return client.handleFailedRequest(CodeActionResolveRequest.type, token, error, item);
});
};
return resolveCodeAction(item, token);
},
},
revealOutputChannelOn: RevealOutputChannelOn.Never,
errorHandler: new ClientErrorHandler(extensionName),
Expand Down Expand Up @@ -1189,5 +1243,3 @@ function registerRestartJavaLanguageServerCommand(context: ExtensionContext) {
}
}));
}


0 comments on commit 1d7163f

Please sign in to comment.