aboutsummaryrefslogtreecommitdiff
path: root/editors/code/src/client.ts
diff options
context:
space:
mode:
Diffstat (limited to 'editors/code/src/client.ts')
-rw-r--r--editors/code/src/client.ts41
1 files changed, 37 insertions, 4 deletions
diff --git a/editors/code/src/client.ts b/editors/code/src/client.ts
index fac1a0be3..d64f9a3f9 100644
--- a/editors/code/src/client.ts
+++ b/editors/code/src/client.ts
@@ -41,10 +41,12 @@ export function createClient(serverPath: string, cwd: string): lc.LanguageClient
41 return client.sendRequest(lc.CodeActionRequest.type, params, token).then((values) => { 41 return client.sendRequest(lc.CodeActionRequest.type, params, token).then((values) => {
42 if (values === null) return undefined; 42 if (values === null) return undefined;
43 const result: (vscode.CodeAction | vscode.Command)[] = []; 43 const result: (vscode.CodeAction | vscode.Command)[] = [];
44 const groups = new Map<string, { index: number; items: vscode.CodeAction[] }>();
44 for (const item of values) { 45 for (const item of values) {
45 if (lc.CodeAction.is(item)) { 46 if (lc.CodeAction.is(item)) {
46 const action = client.protocol2CodeConverter.asCodeAction(item); 47 const action = client.protocol2CodeConverter.asCodeAction(item);
47 if (isSnippetEdit(item)) { 48 const group = actionGroup(item);
49 if (isSnippetEdit(item) || group) {
48 action.command = { 50 action.command = {
49 command: "rust-analyzer.applySnippetWorkspaceEdit", 51 command: "rust-analyzer.applySnippetWorkspaceEdit",
50 title: "", 52 title: "",
@@ -52,12 +54,38 @@ export function createClient(serverPath: string, cwd: string): lc.LanguageClient
52 }; 54 };
53 action.edit = undefined; 55 action.edit = undefined;
54 } 56 }
55 result.push(action); 57
58 if (group) {
59 let entry = groups.get(group);
60 if (!entry) {
61 entry = { index: result.length, items: [] };
62 groups.set(group, entry);
63 result.push(action);
64 }
65 entry.items.push(action);
66 } else {
67 result.push(action);
68 }
56 } else { 69 } else {
57 const command = client.protocol2CodeConverter.asCommand(item); 70 const command = client.protocol2CodeConverter.asCommand(item);
58 result.push(command); 71 result.push(command);
59 } 72 }
60 } 73 }
74 for (const [group, { index, items }] of groups) {
75 if (items.length === 1) {
76 result[index] = items[0];
77 } else {
78 const action = new vscode.CodeAction(group);
79 action.command = {
80 command: "rust-analyzer.applyActionGroup",
81 title: "",
82 arguments: [items.map((item) => {
83 return { label: item.title, edit: item.command!!.arguments!![0] };
84 })],
85 };
86 result[index] = action;
87 }
88 }
61 return result; 89 return result;
62 }, 90 },
63 (_error) => undefined 91 (_error) => undefined
@@ -81,15 +109,16 @@ export function createClient(serverPath: string, cwd: string): lc.LanguageClient
81 // implementations are still in the "proposed" category for 3.16. 109 // implementations are still in the "proposed" category for 3.16.
82 client.registerFeature(new CallHierarchyFeature(client)); 110 client.registerFeature(new CallHierarchyFeature(client));
83 client.registerFeature(new SemanticTokensFeature(client)); 111 client.registerFeature(new SemanticTokensFeature(client));
84 client.registerFeature(new SnippetTextEditFeature()); 112 client.registerFeature(new ExperimentalFeatures());
85 113
86 return client; 114 return client;
87} 115}
88 116
89class SnippetTextEditFeature implements lc.StaticFeature { 117class ExperimentalFeatures implements lc.StaticFeature {
90 fillClientCapabilities(capabilities: lc.ClientCapabilities): void { 118 fillClientCapabilities(capabilities: lc.ClientCapabilities): void {
91 const caps: any = capabilities.experimental ?? {}; 119 const caps: any = capabilities.experimental ?? {};
92 caps.snippetTextEdit = true; 120 caps.snippetTextEdit = true;
121 caps.codeActionGroup = true;
93 capabilities.experimental = caps; 122 capabilities.experimental = caps;
94 } 123 }
95 initialize(_capabilities: lc.ServerCapabilities<any>, _documentSelector: lc.DocumentSelector | undefined): void { 124 initialize(_capabilities: lc.ServerCapabilities<any>, _documentSelector: lc.DocumentSelector | undefined): void {
@@ -107,3 +136,7 @@ function isSnippetEdit(action: lc.CodeAction): boolean {
107 } 136 }
108 return false; 137 return false;
109} 138}
139
140function actionGroup(action: lc.CodeAction): string | undefined {
141 return (action as any).group;
142}