aboutsummaryrefslogtreecommitdiff
path: root/editors/code
diff options
context:
space:
mode:
Diffstat (limited to 'editors/code')
-rw-r--r--editors/code/package-lock.json22
-rw-r--r--editors/code/package.json36
-rw-r--r--editors/code/rust.tmGrammar.json31
-rw-r--r--editors/code/src/client.ts23
-rw-r--r--editors/code/src/commands.ts32
-rw-r--r--editors/code/src/lsp_ext.ts12
-rw-r--r--editors/code/src/main.ts1
-rw-r--r--editors/code/src/snippets.ts23
8 files changed, 124 insertions, 56 deletions
diff --git a/editors/code/package-lock.json b/editors/code/package-lock.json
index 83ef00058..a60d3668b 100644
--- a/editors/code/package-lock.json
+++ b/editors/code/package-lock.json
@@ -2414,27 +2414,27 @@
2414 "integrity": "sha512-1nG+6cuTtpzmXe7yYfO9GCkYlyV6Ai+jDnwidHiT2T7zhc+bJM+VTtc0T/CdTlDyTNTqIcCj0V1nD4TcVjJ7Ug==" 2414 "integrity": "sha512-1nG+6cuTtpzmXe7yYfO9GCkYlyV6Ai+jDnwidHiT2T7zhc+bJM+VTtc0T/CdTlDyTNTqIcCj0V1nD4TcVjJ7Ug=="
2415 }, 2415 },
2416 "vscode-languageclient": { 2416 "vscode-languageclient": {
2417 "version": "7.0.0-next.12", 2417 "version": "7.0.0-next.14",
2418 "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-7.0.0-next.12.tgz", 2418 "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-7.0.0-next.14.tgz",
2419 "integrity": "sha512-OrzvOvhS5o26C0KctTJC7hkwh3avCwkVhllzy42AqwpIUZ3p2aVqkSG2uVxaeodq8ThBb3TLgtg50vxyWs6FEg==", 2419 "integrity": "sha512-QUccfXK2F6AXXRFR8QJCaIz7N2BhJK6ok8E1aO8LHq2IBU33+5hTSJBXs7nEqrqZ/cY2VlDDbMWtMvCxz+/y1w==",
2420 "requires": { 2420 "requires": {
2421 "semver": "^6.3.0", 2421 "semver": "^6.3.0",
2422 "vscode-languageserver-protocol": "3.16.0-next.10" 2422 "vscode-languageserver-protocol": "3.16.0-next.11"
2423 } 2423 }
2424 }, 2424 },
2425 "vscode-languageserver-protocol": { 2425 "vscode-languageserver-protocol": {
2426 "version": "3.16.0-next.10", 2426 "version": "3.16.0-next.11",
2427 "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.16.0-next.10.tgz", 2427 "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.16.0-next.11.tgz",
2428 "integrity": "sha512-YRTctHUZvts0Z1xXKNYU0ha0o+Tlgtwr+6O8OmDquM086N8exiSKBMwMC+Ra1QtIE+1mfW43Wxsme2FnMkAS9A==", 2428 "integrity": "sha512-31FmupmSmfznuMuGp7qN6h3d/hKUbexbvcwTvrUE/igqRlzFU542s8MtGICx1ERbVuDOLGp96W2Z92qbUbmBPA==",
2429 "requires": { 2429 "requires": {
2430 "vscode-jsonrpc": "6.0.0-next.7", 2430 "vscode-jsonrpc": "6.0.0-next.7",
2431 "vscode-languageserver-types": "3.16.0-next.4" 2431 "vscode-languageserver-types": "3.16.0-next.5"
2432 } 2432 }
2433 }, 2433 },
2434 "vscode-languageserver-types": { 2434 "vscode-languageserver-types": {
2435 "version": "3.16.0-next.4", 2435 "version": "3.16.0-next.5",
2436 "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.16.0-next.4.tgz", 2436 "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.16.0-next.5.tgz",
2437 "integrity": "sha512-NlKJyGcET/ZBCCLBYIPaGo2c37R03bPYeWXozUtnjyye7+9dhlbMSODyoG2INcQf8zFmB4qhm2UOJjgYEgPCNA==" 2437 "integrity": "sha512-lf8Y1XXMtF1r2oDDAmJe+drizNXkybSRXAQQk5dPy2rYJsY9SPXYNO074L3THu9zNYepzV5fRJZUPo/V/TLBRQ=="
2438 }, 2438 },
2439 "vscode-test": { 2439 "vscode-test": {
2440 "version": "1.4.0", 2440 "version": "1.4.0",
diff --git a/editors/code/package.json b/editors/code/package.json
index fa8cf90f8..c3f1a0d8d 100644
--- a/editors/code/package.json
+++ b/editors/code/package.json
@@ -21,7 +21,7 @@
21 "Programming Languages" 21 "Programming Languages"
22 ], 22 ],
23 "engines": { 23 "engines": {
24 "vscode": "^1.47.1" 24 "vscode": "^1.51.0"
25 }, 25 },
26 "enableProposedApi": true, 26 "enableProposedApi": true,
27 "scripts": { 27 "scripts": {
@@ -36,7 +36,7 @@
36 }, 36 },
37 "dependencies": { 37 "dependencies": {
38 "node-fetch": "^2.6.1", 38 "node-fetch": "^2.6.1",
39 "vscode-languageclient": "7.0.0-next.12" 39 "vscode-languageclient": "7.0.0-next.14"
40 }, 40 },
41 "devDependencies": { 41 "devDependencies": {
42 "@rollup/plugin-commonjs": "^13.0.2", 42 "@rollup/plugin-commonjs": "^13.0.2",
@@ -187,6 +187,11 @@
187 "command": "rust-analyzer.openDocs", 187 "command": "rust-analyzer.openDocs",
188 "title": "Open docs under cursor", 188 "title": "Open docs under cursor",
189 "category": "Rust Analyzer" 189 "category": "Rust Analyzer"
190 },
191 {
192 "command": "rust-analyzer.openCargoToml",
193 "title": "Open Cargo.toml",
194 "category": "Rust Analyzer"
190 } 195 }
191 ], 196 ],
192 "keybindings": [ 197 "keybindings": [
@@ -278,6 +283,11 @@
278 "default": null, 283 "default": null,
279 "description": "Specify the compilation target" 284 "description": "Specify the compilation target"
280 }, 285 },
286 "rust-analyzer.noSysroot": {
287 "markdownDescription": "Internal config for debugging, disables loading of sysroot crates",
288 "type": "boolean",
289 "default": false
290 },
281 "rust-analyzer.rustfmt.extraArgs": { 291 "rust-analyzer.rustfmt.extraArgs": {
282 "type": "array", 292 "type": "array",
283 "items": { 293 "items": {
@@ -450,6 +460,11 @@
450 "default": true, 460 "default": true,
451 "markdownDescription": "Whether to show postfix snippets like `dbg`, `if`, `not`, etc." 461 "markdownDescription": "Whether to show postfix snippets like `dbg`, `if`, `not`, etc."
452 }, 462 },
463 "rust-analyzer.completion.enableExperimental": {
464 "type": "boolean",
465 "default": true,
466 "markdownDescription": "Display additional completions with potential false positives and performance issues"
467 },
453 "rust-analyzer.callInfo.full": { 468 "rust-analyzer.callInfo.full": {
454 "type": "boolean", 469 "type": "boolean",
455 "default": true, 470 "default": true,
@@ -600,11 +615,6 @@
600 }, 615 },
601 "default": null 616 "default": null
602 }, 617 },
603 "rust-analyzer.withSysroot": {
604 "markdownDescription": "Internal config for debugging, disables loading of sysroot crates",
605 "type": "boolean",
606 "default": true
607 },
608 "rust-analyzer.diagnostics.enable": { 618 "rust-analyzer.diagnostics.enable": {
609 "type": "boolean", 619 "type": "boolean",
610 "default": true, 620 "default": true,
@@ -687,6 +697,14 @@
687 }, 697 },
688 "default": [], 698 "default": [],
689 "description": "Additional arguments to be passed to cargo for runnables such as tests or binaries.\nFor example, it may be '--release'" 699 "description": "Additional arguments to be passed to cargo for runnables such as tests or binaries.\nFor example, it may be '--release'"
700 },
701 "rust-analyzer.rustcSource": {
702 "type": [
703 "null",
704 "string"
705 ],
706 "default": null,
707 "description": "Path to the rust compiler sources, for usage in rustc_private projects."
690 } 708 }
691 } 709 }
692 }, 710 },
@@ -1054,6 +1072,10 @@
1054 { 1072 {
1055 "command": "rust-analyzer.openDocs", 1073 "command": "rust-analyzer.openDocs",
1056 "when": "inRustProject" 1074 "when": "inRustProject"
1075 },
1076 {
1077 "command": "rust-analyzer.openCargoToml",
1078 "when": "inRustProject"
1057 } 1079 }
1058 ] 1080 ]
1059 } 1081 }
diff --git a/editors/code/rust.tmGrammar.json b/editors/code/rust.tmGrammar.json
index 608a3354e..4759bb116 100644
--- a/editors/code/rust.tmGrammar.json
+++ b/editors/code/rust.tmGrammar.json
@@ -167,7 +167,7 @@
167 "match": "(mod)\\s+((?:r#(?!crate|[Ss]elf|super))?[a-z][A-Za-z0-9_]*)", 167 "match": "(mod)\\s+((?:r#(?!crate|[Ss]elf|super))?[a-z][A-Za-z0-9_]*)",
168 "captures": { 168 "captures": {
169 "1": { 169 "1": {
170 "name": "keyword.control.rust" 170 "name": "storage.type.rust"
171 }, 171 },
172 "2": { 172 "2": {
173 "name": "entity.name.module.rust" 173 "name": "entity.name.module.rust"
@@ -180,7 +180,7 @@
180 "begin": "\\b(extern)\\s+(crate)", 180 "begin": "\\b(extern)\\s+(crate)",
181 "beginCaptures": { 181 "beginCaptures": {
182 "1": { 182 "1": {
183 "name": "keyword.control.rust" 183 "name": "storage.type.rust"
184 }, 184 },
185 "2": { 185 "2": {
186 "name": "keyword.other.crate.rust" 186 "name": "keyword.other.crate.rust"
@@ -213,7 +213,7 @@
213 "begin": "\\b(use)\\s", 213 "begin": "\\b(use)\\s",
214 "beginCaptures": { 214 "beginCaptures": {
215 "1": { 215 "1": {
216 "name": "keyword.control.rust" 216 "name": "keyword.other.rust"
217 } 217 }
218 }, 218 },
219 "end": ";", 219 "end": ";",
@@ -307,9 +307,14 @@
307 "block-comments": { 307 "block-comments": {
308 "patterns": [ 308 "patterns": [
309 { 309 {
310 "comment": "block comments", 310 "comment": "empty block comments",
311 "name": "comment.block.rust", 311 "name": "comment.block.rust",
312 "begin": "/\\*(?!\\*)", 312 "match": "/\\*\\*/"
313 },
314 {
315 "comment": "block documentation comments",
316 "name": "comment.block.documentation.rust",
317 "begin": "/\\*\\*",
313 "end": "\\*/", 318 "end": "\\*/",
314 "patterns": [ 319 "patterns": [
315 { 320 {
@@ -318,9 +323,9 @@
318 ] 323 ]
319 }, 324 },
320 { 325 {
321 "comment": "block documentation comments", 326 "comment": "block comments",
322 "name": "comment.block.documentation.rust", 327 "name": "comment.block.rust",
323 "begin": "/\\*\\*", 328 "begin": "/\\*(?!\\*)",
324 "end": "\\*/", 329 "end": "\\*/",
325 "patterns": [ 330 "patterns": [
326 { 331 {
@@ -342,7 +347,7 @@
342 "match": "\\b(const)\\s+([A-Z][A-Za-z0-9_]*)\\b", 347 "match": "\\b(const)\\s+([A-Z][A-Za-z0-9_]*)\\b",
343 "captures": { 348 "captures": {
344 "1": { 349 "1": {
345 "name": "keyword.control.rust" 350 "name": "storage.type.rust"
346 }, 351 },
347 "2": { 352 "2": {
348 "name": "constant.other.caps.rust" 353 "name": "constant.other.caps.rust"
@@ -404,7 +409,7 @@
404 { 409 {
405 "comment": "booleans", 410 "comment": "booleans",
406 "name": "constant.language.bool.rust", 411 "name": "constant.language.bool.rust",
407 "match": "\\btrue|false\\b" 412 "match": "\\b(true|false)\\b"
408 } 413 }
409 ] 414 ]
410 }, 415 },
@@ -450,7 +455,7 @@
450 "begin": "\\b(fn)\\s+((?:r#(?!crate|[Ss]elf|super))?[A-Za-z0-9_]+)((\\()|(<))", 455 "begin": "\\b(fn)\\s+((?:r#(?!crate|[Ss]elf|super))?[A-Za-z0-9_]+)((\\()|(<))",
451 "beginCaptures": { 456 "beginCaptures": {
452 "1": { 457 "1": {
453 "name": "keyword.control.fn.rust" 458 "name": "keyword.other.fn.rust"
454 }, 459 },
455 "2": { 460 "2": {
456 "name": "entity.name.function.rust" 461 "name": "entity.name.function.rust"
@@ -643,7 +648,7 @@
643 { 648 {
644 "comment": "control flow keywords", 649 "comment": "control flow keywords",
645 "name": "keyword.control.rust", 650 "name": "keyword.control.rust",
646 "match": "\\b(async|await|break|continue|do|else|for|if|loop|match|move|return|try|where|while|yield)\\b" 651 "match": "\\b(await|break|continue|do|else|for|if|loop|match|return|try|while|yield)\\b"
647 }, 652 },
648 { 653 {
649 "comment": "storage keywords", 654 "comment": "storage keywords",
@@ -658,7 +663,7 @@
658 { 663 {
659 "comment": "other keywords", 664 "comment": "other keywords",
660 "name": "keyword.other.rust", 665 "name": "keyword.other.rust",
661 "match": "\\b(as|become|box|dyn|final|impl|in|override|priv|pub|ref|typeof|union|unsafe|unsized|use|virtual)\\b" 666 "match": "\\b(as|async|become|box|dyn|move|final|impl|in|override|priv|pub|ref|typeof|union|unsafe|unsized|use|virtual|where)\\b"
662 }, 667 },
663 { 668 {
664 "comment": "fn", 669 "comment": "fn",
diff --git a/editors/code/src/client.ts b/editors/code/src/client.ts
index d032b45b7..63ab82dde 100644
--- a/editors/code/src/client.ts
+++ b/editors/code/src/client.ts
@@ -4,6 +4,7 @@ import * as ra from '../src/lsp_ext';
4import * as Is from 'vscode-languageclient/lib/common/utils/is'; 4import * as Is from 'vscode-languageclient/lib/common/utils/is';
5import { DocumentSemanticsTokensSignature, DocumentSemanticsTokensEditsSignature, DocumentRangeSemanticTokensSignature } from 'vscode-languageclient/lib/common/semanticTokens'; 5import { DocumentSemanticsTokensSignature, DocumentSemanticsTokensEditsSignature, DocumentRangeSemanticTokensSignature } from 'vscode-languageclient/lib/common/semanticTokens';
6import { assert } from './util'; 6import { assert } from './util';
7import { WorkspaceEdit } from 'vscode';
7 8
8function renderCommand(cmd: ra.CommandLink) { 9function renderCommand(cmd: ra.CommandLink) {
9 return `[${cmd.title}](command:${cmd.command}?${encodeURIComponent(JSON.stringify(cmd.arguments))} '${cmd.tooltip!}')`; 10 return `[${cmd.title}](command:${cmd.command}?${encodeURIComponent(JSON.stringify(cmd.arguments))} '${cmd.tooltip!}')`;
@@ -75,8 +76,8 @@ export function createClient(serverPath: string, cwd: string): lc.LanguageClient
75 return Promise.resolve(null); 76 return Promise.resolve(null);
76 }); 77 });
77 }, 78 },
78 // Using custom handling of CodeActions where each code action is resolved lazily 79 // Using custom handling of CodeActions to support action groups and snippet edits.
79 // That's why we are not waiting for any command or edits 80 // Note that this means we have to re-implement lazy edit resolving ourselves as well.
80 async provideCodeActions(document: vscode.TextDocument, range: vscode.Range, context: vscode.CodeActionContext, token: vscode.CancellationToken, _next: lc.ProvideCodeActionsSignature) { 81 async provideCodeActions(document: vscode.TextDocument, range: vscode.Range, context: vscode.CodeActionContext, token: vscode.CancellationToken, _next: lc.ProvideCodeActionsSignature) {
81 const params: lc.CodeActionParams = { 82 const params: lc.CodeActionParams = {
82 textDocument: client.code2ProtocolConverter.asTextDocumentIdentifier(document), 83 textDocument: client.code2ProtocolConverter.asTextDocumentIdentifier(document),
@@ -99,16 +100,15 @@ export function createClient(serverPath: string, cwd: string): lc.LanguageClient
99 const kind = client.protocol2CodeConverter.asCodeActionKind((item as any).kind); 100 const kind = client.protocol2CodeConverter.asCodeActionKind((item as any).kind);
100 const action = new vscode.CodeAction(item.title, kind); 101 const action = new vscode.CodeAction(item.title, kind);
101 const group = (item as any).group; 102 const group = (item as any).group;
102 const id = (item as any).id;
103 const resolveParams: ra.ResolveCodeActionParams = {
104 id: id,
105 codeActionParams: params
106 };
107 action.command = { 103 action.command = {
108 command: "rust-analyzer.resolveCodeAction", 104 command: "rust-analyzer.resolveCodeAction",
109 title: item.title, 105 title: item.title,
110 arguments: [resolveParams], 106 arguments: [item],
111 }; 107 };
108
109 // Set a dummy edit, so that VS Code doesn't try to resolve this.
110 action.edit = new WorkspaceEdit();
111
112 if (group) { 112 if (group) {
113 let entry = groups.get(group); 113 let entry = groups.get(group);
114 if (!entry) { 114 if (!entry) {
@@ -134,6 +134,10 @@ export function createClient(serverPath: string, cwd: string): lc.LanguageClient
134 return { label: item.title, arguments: item.command!!.arguments!![0] }; 134 return { label: item.title, arguments: item.command!!.arguments!![0] };
135 })], 135 })],
136 }; 136 };
137
138 // Set a dummy edit, so that VS Code doesn't try to resolve this.
139 action.edit = new WorkspaceEdit();
140
137 result[index] = action; 141 result[index] = action;
138 } 142 }
139 } 143 }
@@ -164,13 +168,14 @@ class ExperimentalFeatures implements lc.StaticFeature {
164 const caps: any = capabilities.experimental ?? {}; 168 const caps: any = capabilities.experimental ?? {};
165 caps.snippetTextEdit = true; 169 caps.snippetTextEdit = true;
166 caps.codeActionGroup = true; 170 caps.codeActionGroup = true;
167 caps.resolveCodeAction = true;
168 caps.hoverActions = true; 171 caps.hoverActions = true;
169 caps.statusNotification = true; 172 caps.statusNotification = true;
170 capabilities.experimental = caps; 173 capabilities.experimental = caps;
171 } 174 }
172 initialize(_capabilities: lc.ServerCapabilities<any>, _documentSelector: lc.DocumentSelector | undefined): void { 175 initialize(_capabilities: lc.ServerCapabilities<any>, _documentSelector: lc.DocumentSelector | undefined): void {
173 } 176 }
177 dispose(): void {
178 }
174} 179}
175 180
176function isCodeActionWithoutEditsAndCommands(value: any): boolean { 181function isCodeActionWithoutEditsAndCommands(value: any): boolean {
diff --git a/editors/code/src/commands.ts b/editors/code/src/commands.ts
index 22509e874..92bc4d7f7 100644
--- a/editors/code/src/commands.ts
+++ b/editors/code/src/commands.ts
@@ -188,6 +188,27 @@ export function parentModule(ctx: Ctx): Cmd {
188 }; 188 };
189} 189}
190 190
191export function openCargoToml(ctx: Ctx): Cmd {
192 return async () => {
193 const editor = ctx.activeRustEditor;
194 const client = ctx.client;
195 if (!editor || !client) return;
196
197 const response = await client.sendRequest(ra.openCargoToml, {
198 textDocument: ctx.client.code2ProtocolConverter.asTextDocumentIdentifier(editor.document),
199 });
200 if (!response) return;
201
202 const uri = client.protocol2CodeConverter.asUri(response.uri);
203 const range = client.protocol2CodeConverter.asRange(response.range);
204
205 const doc = await vscode.workspace.openTextDocument(uri);
206 const e = await vscode.window.showTextDocument(doc);
207 e.selection = new vscode.Selection(range.start, range.start);
208 e.revealRange(range, vscode.TextEditorRevealType.InCenter);
209 };
210}
211
191export function ssr(ctx: Ctx): Cmd { 212export function ssr(ctx: Ctx): Cmd {
192 return async () => { 213 return async () => {
193 const editor = vscode.window.activeTextEditor; 214 const editor = vscode.window.activeTextEditor;
@@ -395,7 +416,7 @@ export function showReferences(ctx: Ctx): Cmd {
395} 416}
396 417
397export function applyActionGroup(_ctx: Ctx): Cmd { 418export function applyActionGroup(_ctx: Ctx): Cmd {
398 return async (actions: { label: string; arguments: ra.ResolveCodeActionParams }[]) => { 419 return async (actions: { label: string; arguments: lc.CodeAction }[]) => {
399 const selectedAction = await vscode.window.showQuickPick(actions); 420 const selectedAction = await vscode.window.showQuickPick(actions);
400 if (!selectedAction) return; 421 if (!selectedAction) return;
401 vscode.commands.executeCommand( 422 vscode.commands.executeCommand(
@@ -442,12 +463,13 @@ export function openDocs(ctx: Ctx): Cmd {
442 463
443export function resolveCodeAction(ctx: Ctx): Cmd { 464export function resolveCodeAction(ctx: Ctx): Cmd {
444 const client = ctx.client; 465 const client = ctx.client;
445 return async (params: ra.ResolveCodeActionParams) => { 466 return async (params: lc.CodeAction) => {
446 const item: lc.WorkspaceEdit = await client.sendRequest(ra.resolveCodeAction, params); 467 params.command = undefined;
447 if (!item) { 468 const item = await client.sendRequest(lc.CodeActionResolveRequest.type, params);
469 if (!item.edit) {
448 return; 470 return;
449 } 471 }
450 const edit = client.protocol2CodeConverter.asWorkspaceEdit(item); 472 const edit = client.protocol2CodeConverter.asWorkspaceEdit(item.edit);
451 await applySnippetWorkspaceEdit(edit); 473 await applySnippetWorkspaceEdit(edit);
452 }; 474 };
453} 475}
diff --git a/editors/code/src/lsp_ext.ts b/editors/code/src/lsp_ext.ts
index fc8e120b3..5e877ce65 100644
--- a/editors/code/src/lsp_ext.ts
+++ b/editors/code/src/lsp_ext.ts
@@ -43,12 +43,6 @@ export const matchingBrace = new lc.RequestType<MatchingBraceParams, lc.Position
43 43
44export const parentModule = new lc.RequestType<lc.TextDocumentPositionParams, lc.LocationLink[], void>("experimental/parentModule"); 44export const parentModule = new lc.RequestType<lc.TextDocumentPositionParams, lc.LocationLink[], void>("experimental/parentModule");
45 45
46export interface ResolveCodeActionParams {
47 id: string;
48 codeActionParams: lc.CodeActionParams;
49}
50export const resolveCodeAction = new lc.RequestType<ResolveCodeActionParams, lc.WorkspaceEdit, unknown>('experimental/resolveCodeAction');
51
52export interface JoinLinesParams { 46export interface JoinLinesParams {
53 textDocument: lc.TextDocumentIdentifier; 47 textDocument: lc.TextDocumentIdentifier;
54 ranges: lc.Range[]; 48 ranges: lc.Range[];
@@ -120,3 +114,9 @@ export interface CommandLinkGroup {
120} 114}
121 115
122export const openDocs = new lc.RequestType<lc.TextDocumentPositionParams, string | void, void>('experimental/externalDocs'); 116export const openDocs = new lc.RequestType<lc.TextDocumentPositionParams, string | void, void>('experimental/externalDocs');
117
118export const openCargoToml = new lc.RequestType<OpenCargoTomlParams, lc.Location, void>("experimental/openCargoToml");
119
120export interface OpenCargoTomlParams {
121 textDocument: lc.TextDocumentIdentifier;
122}
diff --git a/editors/code/src/main.ts b/editors/code/src/main.ts
index 09543e348..2f3dde8ac 100644
--- a/editors/code/src/main.ts
+++ b/editors/code/src/main.ts
@@ -111,6 +111,7 @@ async function tryActivate(context: vscode.ExtensionContext) {
111 ctx.registerCommand('debug', commands.debug); 111 ctx.registerCommand('debug', commands.debug);
112 ctx.registerCommand('newDebugConfig', commands.newDebugConfig); 112 ctx.registerCommand('newDebugConfig', commands.newDebugConfig);
113 ctx.registerCommand('openDocs', commands.openDocs); 113 ctx.registerCommand('openDocs', commands.openDocs);
114 ctx.registerCommand('openCargoToml', commands.openCargoToml);
114 115
115 defaultOnEnter.dispose(); 116 defaultOnEnter.dispose();
116 ctx.registerCommand('onEnter', commands.onEnter); 117 ctx.registerCommand('onEnter', commands.onEnter);
diff --git a/editors/code/src/snippets.ts b/editors/code/src/snippets.ts
index 258b49982..fee736e7d 100644
--- a/editors/code/src/snippets.ts
+++ b/editors/code/src/snippets.ts
@@ -3,16 +3,29 @@ import * as vscode from 'vscode';
3import { assert } from './util'; 3import { assert } from './util';
4 4
5export async function applySnippetWorkspaceEdit(edit: vscode.WorkspaceEdit) { 5export async function applySnippetWorkspaceEdit(edit: vscode.WorkspaceEdit) {
6 assert(edit.entries().length === 1, `bad ws edit: ${JSON.stringify(edit)}`); 6 if (edit.entries().length === 1) {
7 const [uri, edits] = edit.entries()[0]; 7 const [uri, edits] = edit.entries()[0];
8 const editor = await editorFromUri(uri);
9 if (editor) await applySnippetTextEdits(editor, edits);
10 return;
11 }
12 for (const [uri, edits] of edit.entries()) {
13 const editor = await editorFromUri(uri);
14 if (editor) await editor.edit((builder) => {
15 for (const indel of edits) {
16 assert(!parseSnippet(indel.newText), `bad ws edit: snippet received with multiple edits: ${JSON.stringify(edit)}`);
17 builder.replace(indel.range, indel.newText);
18 }
19 });
20 }
21}
8 22
23async function editorFromUri(uri: vscode.Uri): Promise<vscode.TextEditor | undefined> {
9 if (vscode.window.activeTextEditor?.document.uri !== uri) { 24 if (vscode.window.activeTextEditor?.document.uri !== uri) {
10 // `vscode.window.visibleTextEditors` only contains editors whose contents are being displayed 25 // `vscode.window.visibleTextEditors` only contains editors whose contents are being displayed
11 await vscode.window.showTextDocument(uri, {}); 26 await vscode.window.showTextDocument(uri, {});
12 } 27 }
13 const editor = vscode.window.visibleTextEditors.find((it) => it.document.uri.toString() === uri.toString()); 28 return vscode.window.visibleTextEditors.find((it) => it.document.uri.toString() === uri.toString());
14 if (!editor) return;
15 await applySnippetTextEdits(editor, edits);
16} 29}
17 30
18export async function applySnippetTextEdits(editor: vscode.TextEditor, edits: vscode.TextEdit[]) { 31export async function applySnippetTextEdits(editor: vscode.TextEditor, edits: vscode.TextEdit[]) {