aboutsummaryrefslogtreecommitdiff
path: root/editors
diff options
context:
space:
mode:
Diffstat (limited to 'editors')
-rw-r--r--editors/code/rust.tmGrammar.json32
-rw-r--r--editors/code/src/client.ts17
-rw-r--r--editors/code/src/snippets.ts23
3 files changed, 51 insertions, 21 deletions
diff --git a/editors/code/rust.tmGrammar.json b/editors/code/rust.tmGrammar.json
index 77595aa00..b3a10795e 100644
--- a/editors/code/rust.tmGrammar.json
+++ b/editors/code/rust.tmGrammar.json
@@ -50,7 +50,7 @@
50 { 50 {
51 "comment": "macro type metavariables", 51 "comment": "macro type metavariables",
52 "name": "meta.macro.metavariable.type.rust", 52 "name": "meta.macro.metavariable.type.rust",
53 "match": "(\\$)((crate)|([A-Z][A-Za-z0-9_]*))((:)(block|expr|ident|item|lifetime|literal|meta|pat|path|stmt|tt|ty|vis))?", 53 "match": "(\\$)((crate)|([A-Z][A-Za-z0-9_]*))((:)(block|expr|ident|item|lifetime|literal|meta|path?|stmt|tt|ty|vis))?",
54 "captures": { 54 "captures": {
55 "1": { 55 "1": {
56 "name": "keyword.operator.macro.dollar.rust" 56 "name": "keyword.operator.macro.dollar.rust"
@@ -77,7 +77,7 @@
77 { 77 {
78 "comment": "macro metavariables", 78 "comment": "macro metavariables",
79 "name": "meta.macro.metavariable.rust", 79 "name": "meta.macro.metavariable.rust",
80 "match": "(\\$)([a-z][A-Za-z0-9_]*)((:)(block|expr|ident|item|lifetime|literal|meta|pat|path|stmt|tt|ty|vis))?", 80 "match": "(\\$)([a-z][A-Za-z0-9_]*)((:)(block|expr|ident|item|lifetime|literal|meta|path?|stmt|tt|ty|vis))?",
81 "captures": { 81 "captures": {
82 "1": { 82 "1": {
83 "name": "keyword.operator.macro.dollar.rust" 83 "name": "keyword.operator.macro.dollar.rust"
@@ -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": ";",
@@ -342,7 +342,7 @@
342 "match": "\\b(const)\\s+([A-Z][A-Za-z0-9_]*)\\b", 342 "match": "\\b(const)\\s+([A-Z][A-Za-z0-9_]*)\\b",
343 "captures": { 343 "captures": {
344 "1": { 344 "1": {
345 "name": "keyword.control.rust" 345 "name": "storage.type.rust"
346 }, 346 },
347 "2": { 347 "2": {
348 "name": "constant.other.caps.rust" 348 "name": "constant.other.caps.rust"
@@ -450,7 +450,7 @@
450 "begin": "\\b(fn)\\s+((?:r#(?!crate|[Ss]elf|super))?[A-Za-z0-9_]+)((\\()|(<))", 450 "begin": "\\b(fn)\\s+((?:r#(?!crate|[Ss]elf|super))?[A-Za-z0-9_]+)((\\()|(<))",
451 "beginCaptures": { 451 "beginCaptures": {
452 "1": { 452 "1": {
453 "name": "keyword.control.fn.rust" 453 "name": "keyword.other.fn.rust"
454 }, 454 },
455 "2": { 455 "2": {
456 "name": "entity.name.function.rust" 456 "name": "entity.name.function.rust"
@@ -643,7 +643,7 @@
643 { 643 {
644 "comment": "control flow keywords", 644 "comment": "control flow keywords",
645 "name": "keyword.control.rust", 645 "name": "keyword.control.rust",
646 "match": "\\b(async|await|break|continue|do|else|for|if|loop|match|move|return|try|where|while|yield)\\b" 646 "match": "\\b(await|break|continue|do|else|for|if|loop|match|return|try|while|yield)\\b"
647 }, 647 },
648 { 648 {
649 "comment": "storage keywords", 649 "comment": "storage keywords",
@@ -658,7 +658,7 @@
658 { 658 {
659 "comment": "other keywords", 659 "comment": "other keywords",
660 "name": "keyword.other.rust", 660 "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" 661 "match": "\\b(as|async|become|box|dyn|move|final|impl|in|override|priv|pub|ref|typeof|union|unsafe|unsized|use|virtual|where)\\b"
662 }, 662 },
663 { 663 {
664 "comment": "fn", 664 "comment": "fn",
@@ -676,11 +676,6 @@
676 "match": "\\bmut\\b" 676 "match": "\\bmut\\b"
677 }, 677 },
678 { 678 {
679 "comment": "math operators",
680 "name": "keyword.operator.math.rust",
681 "match": "(([+%]|(\\*(?!\\w)))(?!=))|(-(?!>))|(/(?!/))"
682 },
683 {
684 "comment": "logical operators", 679 "comment": "logical operators",
685 "name": "keyword.operator.logical.rust", 680 "name": "keyword.operator.logical.rust",
686 "match": "(\\^|\\||\\|\\||&&|<<|>>|!)(?!=)" 681 "match": "(\\^|\\||\\|\\||&&|<<|>>|!)(?!=)"
@@ -693,7 +688,7 @@
693 { 688 {
694 "comment": "assignment operators", 689 "comment": "assignment operators",
695 "name": "keyword.operator.assignment.rust", 690 "name": "keyword.operator.assignment.rust",
696 "match": "(-=|\\*=|/=|%=|\\^=|&=|\\|=|<<=|>>=)" 691 "match": "(\\+=|-=|\\*=|/=|%=|\\^=|&=|\\|=|<<=|>>=)"
697 }, 692 },
698 { 693 {
699 "comment": "single equal", 694 "comment": "single equal",
@@ -706,6 +701,11 @@
706 "match": "(=(=)?(?!>)|!=|<=|(?<!=)>=)" 701 "match": "(=(=)?(?!>)|!=|<=|(?<!=)>=)"
707 }, 702 },
708 { 703 {
704 "comment": "math operators",
705 "name": "keyword.operator.math.rust",
706 "match": "(([+%]|(\\*(?!\\w)))(?!=))|(-(?!>))|(/(?!/))"
707 },
708 {
709 "comment": "less than, greater than (special case)", 709 "comment": "less than, greater than (special case)",
710 "match": "(?:\\b|(?:(\\))|(\\])|(\\})))[ \\t]+([<>])[ \\t]+(?:\\b|(?:(\\()|(\\[)|(\\{)))", 710 "match": "(?:\\b|(?:(\\))|(\\])|(\\})))[ \\t]+([<>])[ \\t]+(?:\\b|(?:(\\()|(\\[)|(\\{)))",
711 "captures": { 711 "captures": {
@@ -1127,7 +1127,7 @@
1127 { 1127 {
1128 "comment": "variables", 1128 "comment": "variables",
1129 "name": "variable.other.rust", 1129 "name": "variable.other.rust",
1130 "match": "\\b(?<!\\.)(?:r#(?!(crate|[Ss]elf|super)))?[a-z0-9_]+\\b" 1130 "match": "\\b(?<!(?<!\\.)\\.)(?:r#(?!(crate|[Ss]elf|super)))?[a-z0-9_]+\\b"
1131 } 1131 }
1132 ] 1132 ]
1133 } 1133 }
diff --git a/editors/code/src/client.ts b/editors/code/src/client.ts
index 1ba2352ee..d032b45b7 100644
--- a/editors/code/src/client.ts
+++ b/editors/code/src/client.ts
@@ -2,6 +2,7 @@ import * as lc from 'vscode-languageclient/node';
2import * as vscode from 'vscode'; 2import * as vscode from 'vscode';
3import * as ra from '../src/lsp_ext'; 3import * 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 { assert } from './util'; 6import { assert } from './util';
6 7
7function renderCommand(cmd: ra.CommandLink) { 8function renderCommand(cmd: ra.CommandLink) {
@@ -18,6 +19,13 @@ function renderHoverActions(actions: ra.CommandLinkGroup[]): vscode.MarkdownStri
18 return result; 19 return result;
19} 20}
20 21
22// Workaround for https://github.com/microsoft/vscode-languageserver-node/issues/576
23async function semanticHighlightingWorkaround<R, F extends (...args: any[]) => vscode.ProviderResult<R>>(next: F, ...args: Parameters<F>): Promise<R> {
24 const res = await next(...args);
25 if (res == null) throw new Error('busy');
26 return res;
27}
28
21export function createClient(serverPath: string, cwd: string): lc.LanguageClient { 29export function createClient(serverPath: string, cwd: string): lc.LanguageClient {
22 // '.' Is the fallback if no folder is open 30 // '.' Is the fallback if no folder is open
23 // TODO?: Workspace folders support Uri's (eg: file://test.txt). 31 // TODO?: Workspace folders support Uri's (eg: file://test.txt).
@@ -41,6 +49,15 @@ export function createClient(serverPath: string, cwd: string): lc.LanguageClient
41 diagnosticCollectionName: "rustc", 49 diagnosticCollectionName: "rustc",
42 traceOutputChannel, 50 traceOutputChannel,
43 middleware: { 51 middleware: {
52 provideDocumentSemanticTokens(document: vscode.TextDocument, token: vscode.CancellationToken, next: DocumentSemanticsTokensSignature): vscode.ProviderResult<vscode.SemanticTokens> {
53 return semanticHighlightingWorkaround(next, document, token);
54 },
55 provideDocumentSemanticTokensEdits(document: vscode.TextDocument, previousResultId: string, token: vscode.CancellationToken, next: DocumentSemanticsTokensEditsSignature): vscode.ProviderResult<vscode.SemanticTokensEdits | vscode.SemanticTokens> {
56 return semanticHighlightingWorkaround(next, document, previousResultId, token);
57 },
58 provideDocumentRangeSemanticTokens(document: vscode.TextDocument, range: vscode.Range, token: vscode.CancellationToken, next: DocumentRangeSemanticTokensSignature): vscode.ProviderResult<vscode.SemanticTokens> {
59 return semanticHighlightingWorkaround(next, document, range, token);
60 },
44 async provideHover(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken, _next: lc.ProvideHoverSignature) { 61 async provideHover(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken, _next: lc.ProvideHoverSignature) {
45 return client.sendRequest(lc.HoverRequest.type, client.code2ProtocolConverter.asTextDocumentPositionParams(document, position), token).then( 62 return client.sendRequest(lc.HoverRequest.type, client.code2ProtocolConverter.asTextDocumentPositionParams(document, position), token).then(
46 (result) => { 63 (result) => {
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[]) {