diff options
Diffstat (limited to 'editors/code/src/client.ts')
-rw-r--r-- | editors/code/src/client.ts | 41 |
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 | ||
89 | class SnippetTextEditFeature implements lc.StaticFeature { | 117 | class 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 | |||
140 | function actionGroup(action: lc.CodeAction): string | undefined { | ||
141 | return (action as any).group; | ||
142 | } | ||