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.ts65
1 files changed, 60 insertions, 5 deletions
diff --git a/editors/code/src/client.ts b/editors/code/src/client.ts
index cffdcf11a..fac1a0be3 100644
--- a/editors/code/src/client.ts
+++ b/editors/code/src/client.ts
@@ -31,24 +31,79 @@ export function createClient(serverPath: string, cwd: string): lc.LanguageClient
31 const res = await next(document, token); 31 const res = await next(document, token);
32 if (res === undefined) throw new Error('busy'); 32 if (res === undefined) throw new Error('busy');
33 return res; 33 return res;
34 },
35 async provideCodeActions(document: vscode.TextDocument, range: vscode.Range, context: vscode.CodeActionContext, token: vscode.CancellationToken, _next: lc.ProvideCodeActionsSignature) {
36 const params: lc.CodeActionParams = {
37 textDocument: client.code2ProtocolConverter.asTextDocumentIdentifier(document),
38 range: client.code2ProtocolConverter.asRange(range),
39 context: client.code2ProtocolConverter.asCodeActionContext(context)
40 };
41 return client.sendRequest(lc.CodeActionRequest.type, params, token).then((values) => {
42 if (values === null) return undefined;
43 const result: (vscode.CodeAction | vscode.Command)[] = [];
44 for (const item of values) {
45 if (lc.CodeAction.is(item)) {
46 const action = client.protocol2CodeConverter.asCodeAction(item);
47 if (isSnippetEdit(item)) {
48 action.command = {
49 command: "rust-analyzer.applySnippetWorkspaceEdit",
50 title: "",
51 arguments: [action.edit],
52 };
53 action.edit = undefined;
54 }
55 result.push(action);
56 } else {
57 const command = client.protocol2CodeConverter.asCommand(item);
58 result.push(command);
59 }
60 }
61 return result;
62 },
63 (_error) => undefined
64 );
34 } 65 }
66
35 } as any 67 } as any
36 }; 68 };
37 69
38 const res = new lc.LanguageClient( 70 const client = new lc.LanguageClient(
39 'rust-analyzer', 71 'rust-analyzer',
40 'Rust Analyzer Language Server', 72 'Rust Analyzer Language Server',
41 serverOptions, 73 serverOptions,
42 clientOptions, 74 clientOptions,
43 ); 75 );
44 76
45 // To turn on all proposed features use: res.registerProposedFeatures(); 77 // To turn on all proposed features use: client.registerProposedFeatures();
46 // Here we want to enable CallHierarchyFeature and SemanticTokensFeature 78 // Here we want to enable CallHierarchyFeature and SemanticTokensFeature
47 // since they are available on stable. 79 // since they are available on stable.
48 // Note that while these features are stable in vscode their LSP protocol 80 // Note that while these features are stable in vscode their LSP protocol
49 // implementations are still in the "proposed" category for 3.16. 81 // implementations are still in the "proposed" category for 3.16.
50 res.registerFeature(new CallHierarchyFeature(res)); 82 client.registerFeature(new CallHierarchyFeature(client));
51 res.registerFeature(new SemanticTokensFeature(res)); 83 client.registerFeature(new SemanticTokensFeature(client));
84 client.registerFeature(new SnippetTextEditFeature());
85
86 return client;
87}
52 88
53 return res; 89class SnippetTextEditFeature implements lc.StaticFeature {
90 fillClientCapabilities(capabilities: lc.ClientCapabilities): void {
91 const caps: any = capabilities.experimental ?? {};
92 caps.snippetTextEdit = true;
93 capabilities.experimental = caps;
94 }
95 initialize(_capabilities: lc.ServerCapabilities<any>, _documentSelector: lc.DocumentSelector | undefined): void {
96 }
97}
98
99function isSnippetEdit(action: lc.CodeAction): boolean {
100 const documentChanges = action.edit?.documentChanges ?? [];
101 for (const edit of documentChanges) {
102 if (lc.TextDocumentEdit.is(edit)) {
103 if (edit.edits.some((indel) => (indel as any).insertTextFormat === lc.InsertTextFormat.Snippet)) {
104 return true;
105 }
106 }
107 }
108 return false;
54} 109}