diff options
Diffstat (limited to 'editors')
-rw-r--r-- | editors/code/rust.tmGrammar.json | 32 | ||||
-rw-r--r-- | editors/code/src/client.ts | 17 | ||||
-rw-r--r-- | editors/code/src/snippets.ts | 23 |
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'; | |||
2 | import * as vscode from 'vscode'; | 2 | import * as vscode from 'vscode'; |
3 | import * as ra from '../src/lsp_ext'; | 3 | import * as ra from '../src/lsp_ext'; |
4 | import * as Is from 'vscode-languageclient/lib/common/utils/is'; | 4 | import * as Is from 'vscode-languageclient/lib/common/utils/is'; |
5 | import { DocumentSemanticsTokensSignature, DocumentSemanticsTokensEditsSignature, DocumentRangeSemanticTokensSignature } from 'vscode-languageclient/lib/common/semanticTokens'; | ||
5 | import { assert } from './util'; | 6 | import { assert } from './util'; |
6 | 7 | ||
7 | function renderCommand(cmd: ra.CommandLink) { | 8 | function 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 | ||
23 | async 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 | |||
21 | export function createClient(serverPath: string, cwd: string): lc.LanguageClient { | 29 | export 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'; | |||
3 | import { assert } from './util'; | 3 | import { assert } from './util'; |
4 | 4 | ||
5 | export async function applySnippetWorkspaceEdit(edit: vscode.WorkspaceEdit) { | 5 | export 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 | ||
23 | async 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 | ||
18 | export async function applySnippetTextEdits(editor: vscode.TextEditor, edits: vscode.TextEdit[]) { | 31 | export async function applySnippetTextEdits(editor: vscode.TextEditor, edits: vscode.TextEdit[]) { |