diff options
Diffstat (limited to 'editors/code/src/commands')
-rw-r--r-- | editors/code/src/commands/index.ts | 2 | ||||
-rw-r--r-- | editors/code/src/commands/syntaxTree.ts | 76 | ||||
-rw-r--r-- | editors/code/src/commands/syntax_tree.ts | 106 |
3 files changed, 107 insertions, 77 deletions
diff --git a/editors/code/src/commands/index.ts b/editors/code/src/commands/index.ts index a7f3bc4c1..8f91b3b7d 100644 --- a/editors/code/src/commands/index.ts +++ b/editors/code/src/commands/index.ts | |||
@@ -5,10 +5,10 @@ import { matchingBrace } from './matching_brace'; | |||
5 | import { joinLines } from './join_lines'; | 5 | import { joinLines } from './join_lines'; |
6 | import { onEnter } from './on_enter'; | 6 | import { onEnter } from './on_enter'; |
7 | import { parentModule } from './parent_module'; | 7 | import { parentModule } from './parent_module'; |
8 | import { syntaxTree } from './syntax_tree'; | ||
8 | import * as expandMacro from './expand_macro'; | 9 | import * as expandMacro from './expand_macro'; |
9 | import * as inlayHints from './inlay_hints'; | 10 | import * as inlayHints from './inlay_hints'; |
10 | import * as runnables from './runnables'; | 11 | import * as runnables from './runnables'; |
11 | import * as syntaxTree from './syntaxTree'; | ||
12 | 12 | ||
13 | function collectGarbage(ctx: Ctx): Cmd { | 13 | function collectGarbage(ctx: Ctx): Cmd { |
14 | return async () => { | 14 | return async () => { |
diff --git a/editors/code/src/commands/syntaxTree.ts b/editors/code/src/commands/syntaxTree.ts deleted file mode 100644 index 89a80550c..000000000 --- a/editors/code/src/commands/syntaxTree.ts +++ /dev/null | |||
@@ -1,76 +0,0 @@ | |||
1 | import * as vscode from 'vscode'; | ||
2 | import { Range, TextDocumentIdentifier } from 'vscode-languageclient'; | ||
3 | |||
4 | import { Server } from '../server'; | ||
5 | |||
6 | export const syntaxTreeUri = vscode.Uri.parse('rust-analyzer://syntaxtree'); | ||
7 | |||
8 | export class SyntaxTreeContentProvider | ||
9 | implements vscode.TextDocumentContentProvider { | ||
10 | public eventEmitter = new vscode.EventEmitter<vscode.Uri>(); | ||
11 | public syntaxTree: string = 'Not available'; | ||
12 | |||
13 | public provideTextDocumentContent( | ||
14 | uri: vscode.Uri, | ||
15 | ): vscode.ProviderResult<string> { | ||
16 | const editor = vscode.window.activeTextEditor; | ||
17 | if (editor == null) { | ||
18 | return ''; | ||
19 | } | ||
20 | |||
21 | let range: Range | undefined; | ||
22 | |||
23 | // When the range based query is enabled we take the range of the selection | ||
24 | if (uri.query === 'range=true') { | ||
25 | range = editor.selection.isEmpty | ||
26 | ? undefined | ||
27 | : Server.client.code2ProtocolConverter.asRange( | ||
28 | editor.selection, | ||
29 | ); | ||
30 | } | ||
31 | |||
32 | const request: SyntaxTreeParams = { | ||
33 | textDocument: { uri: editor.document.uri.toString() }, | ||
34 | range, | ||
35 | }; | ||
36 | return Server.client.sendRequest<SyntaxTreeResult>( | ||
37 | 'rust-analyzer/syntaxTree', | ||
38 | request, | ||
39 | ); | ||
40 | } | ||
41 | |||
42 | get onDidChange(): vscode.Event<vscode.Uri> { | ||
43 | return this.eventEmitter.event; | ||
44 | } | ||
45 | } | ||
46 | |||
47 | interface SyntaxTreeParams { | ||
48 | textDocument: TextDocumentIdentifier; | ||
49 | range?: Range; | ||
50 | } | ||
51 | |||
52 | type SyntaxTreeResult = string; | ||
53 | |||
54 | // Opens the virtual file that will show the syntax tree | ||
55 | // | ||
56 | // The contents of the file come from the `TextDocumentContentProvider` | ||
57 | export function createHandle(provider: SyntaxTreeContentProvider) { | ||
58 | return async () => { | ||
59 | const editor = vscode.window.activeTextEditor; | ||
60 | const rangeEnabled = !!(editor && !editor.selection.isEmpty); | ||
61 | |||
62 | const uri = rangeEnabled | ||
63 | ? vscode.Uri.parse(`${syntaxTreeUri.toString()}?range=true`) | ||
64 | : syntaxTreeUri; | ||
65 | |||
66 | const document = await vscode.workspace.openTextDocument(uri); | ||
67 | |||
68 | provider.eventEmitter.fire(uri); | ||
69 | |||
70 | return vscode.window.showTextDocument( | ||
71 | document, | ||
72 | vscode.ViewColumn.Two, | ||
73 | true, | ||
74 | ); | ||
75 | }; | ||
76 | } | ||
diff --git a/editors/code/src/commands/syntax_tree.ts b/editors/code/src/commands/syntax_tree.ts new file mode 100644 index 000000000..e61fb36df --- /dev/null +++ b/editors/code/src/commands/syntax_tree.ts | |||
@@ -0,0 +1,106 @@ | |||
1 | import * as vscode from 'vscode'; | ||
2 | import * as lc from 'vscode-languageclient'; | ||
3 | |||
4 | import { Ctx, Cmd } from '../ctx'; | ||
5 | |||
6 | // Opens the virtual file that will show the syntax tree | ||
7 | // | ||
8 | // The contents of the file come from the `TextDocumentContentProvider` | ||
9 | export function syntaxTree(ctx: Ctx): Cmd { | ||
10 | const stcp = new SyntaxTreeContentProvider(ctx); | ||
11 | |||
12 | ctx.pushCleanup( | ||
13 | vscode.workspace.registerTextDocumentContentProvider( | ||
14 | 'rust-analyzer', | ||
15 | stcp, | ||
16 | ), | ||
17 | ); | ||
18 | |||
19 | vscode.workspace.onDidChangeTextDocument( | ||
20 | (event: vscode.TextDocumentChangeEvent) => { | ||
21 | const doc = event.document; | ||
22 | if (doc.languageId !== 'rust') return; | ||
23 | afterLs(() => stcp.eventEmitter.fire(stcp.uri)); | ||
24 | }, | ||
25 | ctx.subscriptions, | ||
26 | ); | ||
27 | |||
28 | vscode.window.onDidChangeActiveTextEditor( | ||
29 | (editor: vscode.TextEditor | undefined) => { | ||
30 | if (!editor || editor.document.languageId !== 'rust') return; | ||
31 | stcp.eventEmitter.fire(stcp.uri); | ||
32 | }, | ||
33 | ctx.subscriptions, | ||
34 | ); | ||
35 | |||
36 | return async () => { | ||
37 | const editor = vscode.window.activeTextEditor; | ||
38 | const rangeEnabled = !!(editor && !editor.selection.isEmpty); | ||
39 | |||
40 | const uri = rangeEnabled | ||
41 | ? vscode.Uri.parse(`${stcp.uri.toString()}?range=true`) | ||
42 | : stcp.uri; | ||
43 | |||
44 | const document = await vscode.workspace.openTextDocument(uri); | ||
45 | |||
46 | stcp.eventEmitter.fire(uri); | ||
47 | |||
48 | return vscode.window.showTextDocument( | ||
49 | document, | ||
50 | vscode.ViewColumn.Two, | ||
51 | true, | ||
52 | ); | ||
53 | }; | ||
54 | } | ||
55 | |||
56 | // We need to order this after LS updates, but there's no API for that. | ||
57 | // Hence, good old setTimeout. | ||
58 | function afterLs(f: () => any) { | ||
59 | setTimeout(f, 10); | ||
60 | } | ||
61 | |||
62 | interface SyntaxTreeParams { | ||
63 | textDocument: lc.TextDocumentIdentifier; | ||
64 | range?: lc.Range; | ||
65 | } | ||
66 | |||
67 | export class SyntaxTreeContentProvider | ||
68 | implements vscode.TextDocumentContentProvider { | ||
69 | ctx: Ctx; | ||
70 | uri = vscode.Uri.parse('rust-analyzer://syntaxtree'); | ||
71 | eventEmitter = new vscode.EventEmitter<vscode.Uri>(); | ||
72 | syntaxTree: string = 'Not available'; | ||
73 | |||
74 | constructor(ctx: Ctx) { | ||
75 | this.ctx = ctx; | ||
76 | } | ||
77 | |||
78 | provideTextDocumentContent(uri: vscode.Uri): vscode.ProviderResult<string> { | ||
79 | const editor = vscode.window.activeTextEditor; | ||
80 | if (editor == null) return ''; | ||
81 | |||
82 | let range: lc.Range | undefined; | ||
83 | |||
84 | // When the range based query is enabled we take the range of the selection | ||
85 | if (uri.query === 'range=true') { | ||
86 | range = editor.selection.isEmpty | ||
87 | ? undefined | ||
88 | : this.ctx.client.code2ProtocolConverter.asRange( | ||
89 | editor.selection, | ||
90 | ); | ||
91 | } | ||
92 | |||
93 | const request: SyntaxTreeParams = { | ||
94 | textDocument: { uri: editor.document.uri.toString() }, | ||
95 | range, | ||
96 | }; | ||
97 | return this.ctx.client.sendRequest<string>( | ||
98 | 'rust-analyzer/syntaxTree', | ||
99 | request, | ||
100 | ); | ||
101 | } | ||
102 | |||
103 | get onDidChange(): vscode.Event<vscode.Uri> { | ||
104 | return this.eventEmitter.event; | ||
105 | } | ||
106 | } | ||