aboutsummaryrefslogtreecommitdiff
path: root/editors/code/src
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2019-12-30 18:08:23 +0000
committerGitHub <[email protected]>2019-12-30 18:08:23 +0000
commit7c1634a9c2d76ea8c152c368775391090d62db8f (patch)
tree3879a92160f2313f54e738812d698d62e298f1a0 /editors/code/src
parentb42d3ee3cc22aaa892d15c4ba2219a3bc53907a1 (diff)
parent260df66b7742e76c76184388253552c5055b1945 (diff)
Merge #2691
2691: Cleanup imports r=matklad a=matklad Co-authored-by: Aleksey Kladov <[email protected]>
Diffstat (limited to 'editors/code/src')
-rw-r--r--editors/code/src/commands/analyzer_status.ts17
-rw-r--r--editors/code/src/commands/index.ts18
-rw-r--r--editors/code/src/commands/join_lines.ts45
-rw-r--r--editors/code/src/commands/matching_brace.ts15
-rw-r--r--editors/code/src/commands/on_enter.ts51
-rw-r--r--editors/code/src/commands/parent_module.ts54
-rw-r--r--editors/code/src/commands/syntaxTree.ts76
-rw-r--r--editors/code/src/commands/syntax_tree.ts106
-rw-r--r--editors/code/src/ctx.ts26
-rw-r--r--editors/code/src/events/change_active_text_editor.ts9
-rw-r--r--editors/code/src/events/change_text_document.ts24
-rw-r--r--editors/code/src/events/index.ts3
-rw-r--r--editors/code/src/main.ts64
-rw-r--r--editors/code/src/source_change.ts (renamed from editors/code/src/commands/apply_source_change.ts)10
14 files changed, 239 insertions, 279 deletions
diff --git a/editors/code/src/commands/analyzer_status.ts b/editors/code/src/commands/analyzer_status.ts
index c9d32fe07..b2b624b75 100644
--- a/editors/code/src/commands/analyzer_status.ts
+++ b/editors/code/src/commands/analyzer_status.ts
@@ -1,4 +1,5 @@
1import * as vscode from 'vscode'; 1import * as vscode from 'vscode';
2
2import { Ctx, Cmd } from '../ctx'; 3import { Ctx, Cmd } from '../ctx';
3// Shows status of rust-analyzer (for debugging) 4// Shows status of rust-analyzer (for debugging)
4 5
@@ -23,10 +24,7 @@ export function analyzerStatus(ctx: Ctx): Cmd {
23 24
24 return async function handle() { 25 return async function handle() {
25 if (poller == null) { 26 if (poller == null) {
26 poller = setInterval( 27 poller = setInterval(() => tdcp.eventEmitter.fire(tdcp.uri), 1000);
27 () => tdcp.eventEmitter.fire(tdcp.uri),
28 1000,
29 );
30 } 28 }
31 const document = await vscode.workspace.openTextDocument(tdcp.uri); 29 const document = await vscode.workspace.openTextDocument(tdcp.uri);
32 return vscode.window.showTextDocument( 30 return vscode.window.showTextDocument(
@@ -39,23 +37,20 @@ export function analyzerStatus(ctx: Ctx): Cmd {
39 37
40class TextDocumentContentProvider 38class TextDocumentContentProvider
41 implements vscode.TextDocumentContentProvider { 39 implements vscode.TextDocumentContentProvider {
42 40 ctx: Ctx;
43 uri = vscode.Uri.parse('rust-analyzer-status://status'); 41 uri = vscode.Uri.parse('rust-analyzer-status://status');
44 eventEmitter = new vscode.EventEmitter<vscode.Uri>(); 42 eventEmitter = new vscode.EventEmitter<vscode.Uri>();
45 43
46 ctx: Ctx
47
48 constructor(ctx: Ctx) { 44 constructor(ctx: Ctx) {
49 this.ctx = ctx 45 this.ctx = ctx;
50 } 46 }
51 47
52 provideTextDocumentContent( 48 provideTextDocumentContent(
53 _uri: vscode.Uri, 49 _uri: vscode.Uri,
54 ): vscode.ProviderResult<string> { 50 ): vscode.ProviderResult<string> {
55 const editor = vscode.window.activeTextEditor; 51 const editor = vscode.window.activeTextEditor;
56 if (editor == null) { 52 if (editor == null) return '';
57 return ''; 53
58 }
59 return this.ctx.client.sendRequest<string>( 54 return this.ctx.client.sendRequest<string>(
60 'rust-analyzer/analyzerStatus', 55 'rust-analyzer/analyzerStatus',
61 null, 56 null,
diff --git a/editors/code/src/commands/index.ts b/editors/code/src/commands/index.ts
index 9d9b9c575..8f91b3b7d 100644
--- a/editors/code/src/commands/index.ts
+++ b/editors/code/src/commands/index.ts
@@ -1,23 +1,23 @@
1import { Ctx, Cmd } from '../ctx' 1import { Ctx, Cmd } from '../ctx';
2 2
3import { analyzerStatus } from './analyzer_status'; 3import { analyzerStatus } from './analyzer_status';
4import { matchingBrace } from './matching_brace'; 4import { matchingBrace } from './matching_brace';
5import * as applySourceChange from './apply_source_change'; 5import { joinLines } from './join_lines';
6import { onEnter } from './on_enter';
7import { parentModule } from './parent_module';
8import { syntaxTree } from './syntax_tree';
6import * as expandMacro from './expand_macro'; 9import * as expandMacro from './expand_macro';
7import * as inlayHints from './inlay_hints'; 10import * as inlayHints from './inlay_hints';
8import * as joinLines from './join_lines';
9import * as onEnter from './on_enter';
10import * as parentModule from './parent_module';
11import * as runnables from './runnables'; 11import * as runnables from './runnables';
12import * as syntaxTree from './syntaxTree';
13 12
14function collectGarbage(ctx: Ctx): Cmd { 13function collectGarbage(ctx: Ctx): Cmd {
15 return async () => { ctx.client.sendRequest<null>('rust-analyzer/collectGarbage', null) } 14 return async () => {
15 ctx.client.sendRequest<null>('rust-analyzer/collectGarbage', null);
16 };
16} 17}
17 18
18export { 19export {
19 analyzerStatus, 20 analyzerStatus,
20 applySourceChange,
21 expandMacro, 21 expandMacro,
22 joinLines, 22 joinLines,
23 matchingBrace, 23 matchingBrace,
@@ -26,5 +26,5 @@ export {
26 syntaxTree, 26 syntaxTree,
27 onEnter, 27 onEnter,
28 inlayHints, 28 inlayHints,
29 collectGarbage 29 collectGarbage,
30}; 30};
diff --git a/editors/code/src/commands/join_lines.ts b/editors/code/src/commands/join_lines.ts
index 134ddc801..f4f902cf9 100644
--- a/editors/code/src/commands/join_lines.ts
+++ b/editors/code/src/commands/join_lines.ts
@@ -1,29 +1,26 @@
1import * as vscode from 'vscode'; 1import * as lc from 'vscode-languageclient';
2 2
3import { Range, TextDocumentIdentifier } from 'vscode-languageclient'; 3import { Ctx, Cmd } from '../ctx';
4import { Server } from '../server'; 4import { applySourceChange, SourceChange } from '../source_change';
5import {
6 handle as applySourceChange,
7 SourceChange,
8} from './apply_source_change';
9 5
10interface JoinLinesParams { 6export function joinLines(ctx: Ctx): Cmd {
11 textDocument: TextDocumentIdentifier; 7 return async () => {
12 range: Range; 8 const editor = ctx.activeRustEditor;
13} 9 if (!editor) return;
14 10
15export async function handle() { 11 const request: JoinLinesParams = {
16 const editor = vscode.window.activeTextEditor; 12 range: ctx.client.code2ProtocolConverter.asRange(editor.selection),
17 if (editor == null || editor.document.languageId !== 'rust') { 13 textDocument: { uri: editor.document.uri.toString() },
18 return; 14 };
19 } 15 const change = await ctx.client.sendRequest<SourceChange>(
20 const request: JoinLinesParams = { 16 'rust-analyzer/joinLines',
21 range: Server.client.code2ProtocolConverter.asRange(editor.selection), 17 request,
22 textDocument: { uri: editor.document.uri.toString() }, 18 );
19 await applySourceChange(ctx, change);
23 }; 20 };
24 const change = await Server.client.sendRequest<SourceChange>( 21}
25 'rust-analyzer/joinLines', 22
26 request, 23interface JoinLinesParams {
27 ); 24 textDocument: lc.TextDocumentIdentifier;
28 await applySourceChange(change); 25 range: lc.Range;
29} 26}
diff --git a/editors/code/src/commands/matching_brace.ts b/editors/code/src/commands/matching_brace.ts
index 665b0c33c..59c253f88 100644
--- a/editors/code/src/commands/matching_brace.ts
+++ b/editors/code/src/commands/matching_brace.ts
@@ -1,5 +1,6 @@
1import * as vscode from 'vscode'; 1import * as vscode from 'vscode';
2import { Position, TextDocumentIdentifier } from 'vscode-languageclient'; 2import * as lc from 'vscode-languageclient';
3
3import { Ctx, Cmd } from '../ctx'; 4import { Ctx, Cmd } from '../ctx';
4 5
5export function matchingBrace(ctx: Ctx): Cmd { 6export function matchingBrace(ctx: Ctx): Cmd {
@@ -10,9 +11,11 @@ export function matchingBrace(ctx: Ctx): Cmd {
10 } 11 }
11 const request: FindMatchingBraceParams = { 12 const request: FindMatchingBraceParams = {
12 textDocument: { uri: editor.document.uri.toString() }, 13 textDocument: { uri: editor.document.uri.toString() },
13 offsets: editor.selections.map(s => ctx.client.code2ProtocolConverter.asPosition(s.active)), 14 offsets: editor.selections.map(s =>
15 ctx.client.code2ProtocolConverter.asPosition(s.active),
16 ),
14 }; 17 };
15 const response = await ctx.client.sendRequest<Position[]>( 18 const response = await ctx.client.sendRequest<lc.Position[]>(
16 'rust-analyzer/findMatchingBrace', 19 'rust-analyzer/findMatchingBrace',
17 request, 20 request,
18 ); 21 );
@@ -24,10 +27,10 @@ export function matchingBrace(ctx: Ctx): Cmd {
24 return new vscode.Selection(anchor, active); 27 return new vscode.Selection(anchor, active);
25 }); 28 });
26 editor.revealRange(editor.selection); 29 editor.revealRange(editor.selection);
27 } 30 };
28} 31}
29 32
30interface FindMatchingBraceParams { 33interface FindMatchingBraceParams {
31 textDocument: TextDocumentIdentifier; 34 textDocument: lc.TextDocumentIdentifier;
32 offsets: Position[]; 35 offsets: lc.Position[];
33} 36}
diff --git a/editors/code/src/commands/on_enter.ts b/editors/code/src/commands/on_enter.ts
index 772c64b3c..8324060e8 100644
--- a/editors/code/src/commands/on_enter.ts
+++ b/editors/code/src/commands/on_enter.ts
@@ -1,33 +1,26 @@
1import * as vscode from 'vscode';
2import * as lc from 'vscode-languageclient'; 1import * as lc from 'vscode-languageclient';
3import { Server } from '../server';
4import {
5 handle as applySourceChange,
6 SourceChange,
7} from './apply_source_change';
8 2
9export async function handle(event: { text: string }): Promise<boolean> { 3import { applySourceChange, SourceChange } from '../source_change';
10 const editor = vscode.window.activeTextEditor; 4import { Cmd, Ctx } from '../ctx';
11 if ( 5
12 editor == null || 6export function onEnter(ctx: Ctx): Cmd {
13 editor.document.languageId !== 'rust' || 7 return async (event: { text: string }) => {
14 event.text !== '\n' 8 const editor = ctx.activeRustEditor;
15 ) { 9 if (!editor || event.text !== '\n') return false;
16 return false; 10
17 } 11 const request: lc.TextDocumentPositionParams = {
18 const request: lc.TextDocumentPositionParams = { 12 textDocument: { uri: editor.document.uri.toString() },
19 textDocument: { uri: editor.document.uri.toString() }, 13 position: ctx.client.code2ProtocolConverter.asPosition(
20 position: Server.client.code2ProtocolConverter.asPosition( 14 editor.selection.active,
21 editor.selection.active, 15 ),
22 ), 16 };
17 const change = await ctx.client.sendRequest<undefined | SourceChange>(
18 'rust-analyzer/onEnter',
19 request,
20 );
21 if (!change) return false;
22
23 await applySourceChange(ctx, change);
24 return true;
23 }; 25 };
24 const change = await Server.client.sendRequest<undefined | SourceChange>(
25 'rust-analyzer/onEnter',
26 request,
27 );
28 if (!change) {
29 return false;
30 }
31 await applySourceChange(change);
32 return true;
33} 26}
diff --git a/editors/code/src/commands/parent_module.ts b/editors/code/src/commands/parent_module.ts
index ad49e1bdb..258b61b21 100644
--- a/editors/code/src/commands/parent_module.ts
+++ b/editors/code/src/commands/parent_module.ts
@@ -1,32 +1,32 @@
1import * as vscode from 'vscode'; 1import * as vscode from 'vscode';
2
3import * as lc from 'vscode-languageclient'; 2import * as lc from 'vscode-languageclient';
4import { Server } from '../server';
5 3
6export async function handle() { 4import { Ctx, Cmd } from '../ctx';
7 const editor = vscode.window.activeTextEditor; 5
8 if (editor == null || editor.document.languageId !== 'rust') { 6export function parentModule(ctx: Ctx): Cmd {
9 return; 7 return async () => {
10 } 8 const editor = ctx.activeRustEditor;
11 const request: lc.TextDocumentPositionParams = { 9 if (!editor) return;
12 textDocument: { uri: editor.document.uri.toString() },
13 position: Server.client.code2ProtocolConverter.asPosition(
14 editor.selection.active,
15 ),
16 };
17 const response = await Server.client.sendRequest<lc.Location[]>(
18 'rust-analyzer/parentModule',
19 request,
20 );
21 const loc = response[0];
22 if (loc == null) {
23 return;
24 }
25 const uri = Server.client.protocol2CodeConverter.asUri(loc.uri);
26 const range = Server.client.protocol2CodeConverter.asRange(loc.range);
27 10
28 const doc = await vscode.workspace.openTextDocument(uri); 11 const request: lc.TextDocumentPositionParams = {
29 const e = await vscode.window.showTextDocument(doc); 12 textDocument: { uri: editor.document.uri.toString() },
30 e.selection = new vscode.Selection(range.start, range.start); 13 position: ctx.client.code2ProtocolConverter.asPosition(
31 e.revealRange(range, vscode.TextEditorRevealType.InCenter); 14 editor.selection.active,
15 ),
16 };
17 const response = await ctx.client.sendRequest<lc.Location[]>(
18 'rust-analyzer/parentModule',
19 request,
20 );
21 const loc = response[0];
22 if (loc == null) return;
23
24 const uri = ctx.client.protocol2CodeConverter.asUri(loc.uri);
25 const range = ctx.client.protocol2CodeConverter.asRange(loc.range);
26
27 const doc = await vscode.workspace.openTextDocument(uri);
28 const e = await vscode.window.showTextDocument(doc);
29 e.selection = new vscode.Selection(range.start, range.start);
30 e.revealRange(range, vscode.TextEditorRevealType.InCenter);
31 };
32} 32}
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 @@
1import * as vscode from 'vscode';
2import { Range, TextDocumentIdentifier } from 'vscode-languageclient';
3
4import { Server } from '../server';
5
6export const syntaxTreeUri = vscode.Uri.parse('rust-analyzer://syntaxtree');
7
8export 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
47interface SyntaxTreeParams {
48 textDocument: TextDocumentIdentifier;
49 range?: Range;
50}
51
52type 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`
57export 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 @@
1import * as vscode from 'vscode';
2import * as lc from 'vscode-languageclient';
3
4import { 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`
9export 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.
58function afterLs(f: () => any) {
59 setTimeout(f, 10);
60}
61
62interface SyntaxTreeParams {
63 textDocument: lc.TextDocumentIdentifier;
64 range?: lc.Range;
65}
66
67export 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}
diff --git a/editors/code/src/ctx.ts b/editors/code/src/ctx.ts
index 712337fe7..c3a3583b5 100644
--- a/editors/code/src/ctx.ts
+++ b/editors/code/src/ctx.ts
@@ -27,6 +27,32 @@ export class Ctx {
27 this.pushCleanup(d); 27 this.pushCleanup(d);
28 } 28 }
29 29
30 overrideCommand(name: string, factory: (ctx: Ctx) => Cmd) {
31 const defaultCmd = `default:${name}`;
32 const override = factory(this);
33 const original = (...args: any[]) =>
34 vscode.commands.executeCommand(defaultCmd, ...args);
35 try {
36 const d = vscode.commands.registerCommand(
37 name,
38 async (...args: any[]) => {
39 if (!(await override(...args))) {
40 return await original(...args);
41 }
42 },
43 );
44 this.pushCleanup(d);
45 } catch (_) {
46 vscode.window.showWarningMessage(
47 'Enhanced typing feature is disabled because of incompatibility with VIM extension, consider turning off rust-analyzer.enableEnhancedTyping: https://github.com/rust-analyzer/rust-analyzer/blob/master/docs/user/README.md#settings',
48 );
49 }
50 }
51
52 get subscriptions(): { dispose(): any }[] {
53 return this.extCtx.subscriptions;
54 }
55
30 pushCleanup(d: { dispose(): any }) { 56 pushCleanup(d: { dispose(): any }) {
31 this.extCtx.subscriptions.push(d); 57 this.extCtx.subscriptions.push(d);
32 } 58 }
diff --git a/editors/code/src/events/change_active_text_editor.ts b/editors/code/src/events/change_active_text_editor.ts
index 74b91bd48..4384ee567 100644
--- a/editors/code/src/events/change_active_text_editor.ts
+++ b/editors/code/src/events/change_active_text_editor.ts
@@ -1,21 +1,14 @@
1import { TextEditor } from 'vscode'; 1import { TextEditor } from 'vscode';
2import { TextDocumentIdentifier } from 'vscode-languageclient'; 2import { TextDocumentIdentifier } from 'vscode-languageclient';
3
4import {
5 SyntaxTreeContentProvider,
6 syntaxTreeUri,
7} from '../commands/syntaxTree';
8import { Decoration } from '../highlighting'; 3import { Decoration } from '../highlighting';
9import { Server } from '../server'; 4import { Server } from '../server';
10 5
11export function makeHandler(syntaxTreeProvider: SyntaxTreeContentProvider) { 6export function makeHandler() {
12 return async function handle(editor: TextEditor | undefined) { 7 return async function handle(editor: TextEditor | undefined) {
13 if (!editor || editor.document.languageId !== 'rust') { 8 if (!editor || editor.document.languageId !== 'rust') {
14 return; 9 return;
15 } 10 }
16 11
17 syntaxTreeProvider.eventEmitter.fire(syntaxTreeUri);
18
19 if (!Server.config.highlightingOn) { 12 if (!Server.config.highlightingOn) {
20 return; 13 return;
21 } 14 }
diff --git a/editors/code/src/events/change_text_document.ts b/editors/code/src/events/change_text_document.ts
deleted file mode 100644
index 2e998e889..000000000
--- a/editors/code/src/events/change_text_document.ts
+++ /dev/null
@@ -1,24 +0,0 @@
1import * as vscode from 'vscode';
2
3import {
4 SyntaxTreeContentProvider,
5 syntaxTreeUri,
6} from '../commands/syntaxTree';
7
8export function createHandler(syntaxTreeProvider: SyntaxTreeContentProvider) {
9 return (event: vscode.TextDocumentChangeEvent) => {
10 const doc = event.document;
11 if (doc.languageId !== 'rust') {
12 return;
13 }
14 afterLs(() => {
15 syntaxTreeProvider.eventEmitter.fire(syntaxTreeUri);
16 });
17 };
18}
19
20// We need to order this after LS updates, but there's no API for that.
21// Hence, good old setTimeout.
22function afterLs(f: () => any) {
23 setTimeout(f, 10);
24}
diff --git a/editors/code/src/events/index.ts b/editors/code/src/events/index.ts
index 4c154563f..be135474d 100644
--- a/editors/code/src/events/index.ts
+++ b/editors/code/src/events/index.ts
@@ -1,4 +1,3 @@
1import * as changeActiveTextEditor from './change_active_text_editor'; 1import * as changeActiveTextEditor from './change_active_text_editor';
2import * as changeTextDocument from './change_text_document';
3 2
4export { changeActiveTextEditor, changeTextDocument }; 3export { changeActiveTextEditor };
diff --git a/editors/code/src/main.ts b/editors/code/src/main.ts
index a4149a059..d92cd164f 100644
--- a/editors/code/src/main.ts
+++ b/editors/code/src/main.ts
@@ -4,7 +4,6 @@ import * as lc from 'vscode-languageclient';
4import * as commands from './commands'; 4import * as commands from './commands';
5import { ExpandMacroContentProvider } from './commands/expand_macro'; 5import { ExpandMacroContentProvider } from './commands/expand_macro';
6import { HintsUpdater } from './commands/inlay_hints'; 6import { HintsUpdater } from './commands/inlay_hints';
7import { SyntaxTreeContentProvider } from './commands/syntaxTree';
8import { StatusDisplay } from './commands/watch_status'; 7import { StatusDisplay } from './commands/watch_status';
9import * as events from './events'; 8import * as events from './events';
10import * as notifications from './notifications'; 9import * as notifications from './notifications';
@@ -18,6 +17,9 @@ export async function activate(context: vscode.ExtensionContext) {
18 ctx.registerCommand('analyzerStatus', commands.analyzerStatus); 17 ctx.registerCommand('analyzerStatus', commands.analyzerStatus);
19 ctx.registerCommand('collectGarbage', commands.collectGarbage); 18 ctx.registerCommand('collectGarbage', commands.collectGarbage);
20 ctx.registerCommand('matchingBrace', commands.matchingBrace); 19 ctx.registerCommand('matchingBrace', commands.matchingBrace);
20 ctx.registerCommand('joinLines', commands.joinLines);
21 ctx.registerCommand('parentModule', commands.parentModule);
22 ctx.registerCommand('syntaxTree', commands.syntaxTree);
21 23
22 function disposeOnDeactivation(disposable: vscode.Disposable) { 24 function disposeOnDeactivation(disposable: vscode.Disposable) {
23 context.subscriptions.push(disposable); 25 context.subscriptions.push(disposable);
@@ -26,46 +28,12 @@ export async function activate(context: vscode.ExtensionContext) {
26 function registerCommand(name: string, f: any) { 28 function registerCommand(name: string, f: any) {
27 disposeOnDeactivation(vscode.commands.registerCommand(name, f)); 29 disposeOnDeactivation(vscode.commands.registerCommand(name, f));
28 } 30 }
29 function overrideCommand(
30 name: string,
31 f: (...args: any[]) => Promise<boolean>,
32 ) {
33 const defaultCmd = `default:${name}`;
34 const original = (...args: any[]) =>
35 vscode.commands.executeCommand(defaultCmd, ...args);
36
37 try {
38 registerCommand(name, async (...args: any[]) => {
39 const editor = vscode.window.activeTextEditor;
40 if (
41 !editor ||
42 !editor.document ||
43 editor.document.languageId !== 'rust'
44 ) {
45 return await original(...args);
46 }
47 if (!(await f(...args))) {
48 return await original(...args);
49 }
50 });
51 } catch (_) {
52 vscode.window.showWarningMessage(
53 'Enhanced typing feature is disabled because of incompatibility with VIM extension, consider turning off rust-analyzer.enableEnhancedTyping: https://github.com/rust-analyzer/rust-analyzer/blob/master/docs/user/README.md#settings',
54 );
55 }
56 }
57 31
58 // Commands are requests from vscode to the language server 32 // Commands are requests from vscode to the language server
59 registerCommand('rust-analyzer.joinLines', commands.joinLines.handle);
60 registerCommand('rust-analyzer.parentModule', commands.parentModule.handle);
61 registerCommand('rust-analyzer.run', commands.runnables.handle); 33 registerCommand('rust-analyzer.run', commands.runnables.handle);
62 // Unlike the above this does not send requests to the language server 34 // Unlike the above this does not send requests to the language server
63 registerCommand('rust-analyzer.runSingle', commands.runnables.handleSingle); 35 registerCommand('rust-analyzer.runSingle', commands.runnables.handleSingle);
64 registerCommand( 36 registerCommand(
65 'rust-analyzer.applySourceChange',
66 commands.applySourceChange.handle,
67 );
68 registerCommand(
69 'rust-analyzer.showReferences', 37 'rust-analyzer.showReferences',
70 (uri: string, position: lc.Position, locations: lc.Location[]) => { 38 (uri: string, position: lc.Position, locations: lc.Location[]) => {
71 vscode.commands.executeCommand( 39 vscode.commands.executeCommand(
@@ -78,7 +46,7 @@ export async function activate(context: vscode.ExtensionContext) {
78 ); 46 );
79 47
80 if (Server.config.enableEnhancedTyping) { 48 if (Server.config.enableEnhancedTyping) {
81 overrideCommand('type', commands.onEnter.handle); 49 ctx.overrideCommand('type', commands.onEnter);
82 } 50 }
83 51
84 const watchStatus = new StatusDisplay( 52 const watchStatus = new StatusDisplay(
@@ -87,10 +55,7 @@ export async function activate(context: vscode.ExtensionContext) {
87 disposeOnDeactivation(watchStatus); 55 disposeOnDeactivation(watchStatus);
88 56
89 // Notifications are events triggered by the language server 57 // Notifications are events triggered by the language server
90 const allNotifications: Iterable<[ 58 const allNotifications: [string, lc.GenericNotificationHandler][] = [
91 string,
92 lc.GenericNotificationHandler,
93 ]> = [
94 [ 59 [
95 'rust-analyzer/publishDecorations', 60 'rust-analyzer/publishDecorations',
96 notifications.publishDecorations.handle, 61 notifications.publishDecorations.handle,
@@ -100,42 +65,25 @@ export async function activate(context: vscode.ExtensionContext) {
100 params => watchStatus.handleProgressNotification(params), 65 params => watchStatus.handleProgressNotification(params),
101 ], 66 ],
102 ]; 67 ];
103 const syntaxTreeContentProvider = new SyntaxTreeContentProvider();
104 const expandMacroContentProvider = new ExpandMacroContentProvider(); 68 const expandMacroContentProvider = new ExpandMacroContentProvider();
105 69
106 // The events below are plain old javascript events, triggered and handled by vscode 70 // The events below are plain old javascript events, triggered and handled by vscode
107 vscode.window.onDidChangeActiveTextEditor( 71 vscode.window.onDidChangeActiveTextEditor(
108 events.changeActiveTextEditor.makeHandler(syntaxTreeContentProvider), 72 events.changeActiveTextEditor.makeHandler(),
109 ); 73 );
110 74
111 disposeOnDeactivation( 75 disposeOnDeactivation(
112 vscode.workspace.registerTextDocumentContentProvider( 76 vscode.workspace.registerTextDocumentContentProvider(
113 'rust-analyzer', 77 'rust-analyzer',
114 syntaxTreeContentProvider,
115 ),
116 );
117 disposeOnDeactivation(
118 vscode.workspace.registerTextDocumentContentProvider(
119 'rust-analyzer',
120 expandMacroContentProvider, 78 expandMacroContentProvider,
121 ), 79 ),
122 ); 80 );
123 81
124 registerCommand( 82 registerCommand(
125 'rust-analyzer.syntaxTree',
126 commands.syntaxTree.createHandle(syntaxTreeContentProvider),
127 );
128 registerCommand(
129 'rust-analyzer.expandMacro', 83 'rust-analyzer.expandMacro',
130 commands.expandMacro.createHandle(expandMacroContentProvider), 84 commands.expandMacro.createHandle(expandMacroContentProvider),
131 ); 85 );
132 86
133 vscode.workspace.onDidChangeTextDocument(
134 events.changeTextDocument.createHandler(syntaxTreeContentProvider),
135 null,
136 context.subscriptions,
137 );
138
139 const startServer = () => Server.start(allNotifications); 87 const startServer = () => Server.start(allNotifications);
140 const reloadCommand = () => reloadServer(startServer); 88 const reloadCommand = () => reloadServer(startServer);
141 89
diff --git a/editors/code/src/commands/apply_source_change.ts b/editors/code/src/source_change.ts
index 8167398b1..a4f9068b2 100644
--- a/editors/code/src/commands/apply_source_change.ts
+++ b/editors/code/src/source_change.ts
@@ -1,7 +1,7 @@
1import * as vscode from 'vscode'; 1import * as vscode from 'vscode';
2import * as lc from 'vscode-languageclient'; 2import * as lc from 'vscode-languageclient';
3 3
4import { Server } from '../server'; 4import { Ctx } from './ctx';
5 5
6export interface SourceChange { 6export interface SourceChange {
7 label: string; 7 label: string;
@@ -9,8 +9,8 @@ export interface SourceChange {
9 cursorPosition?: lc.TextDocumentPositionParams; 9 cursorPosition?: lc.TextDocumentPositionParams;
10} 10}
11 11
12export async function handle(change: SourceChange) { 12export async function applySourceChange(ctx: Ctx, change: SourceChange) {
13 const wsEdit = Server.client.protocol2CodeConverter.asWorkspaceEdit( 13 const wsEdit = ctx.client.protocol2CodeConverter.asWorkspaceEdit(
14 change.workspaceEdit, 14 change.workspaceEdit,
15 ); 15 );
16 let created; 16 let created;
@@ -32,10 +32,10 @@ export async function handle(change: SourceChange) {
32 const doc = await vscode.workspace.openTextDocument(toOpenUri); 32 const doc = await vscode.workspace.openTextDocument(toOpenUri);
33 await vscode.window.showTextDocument(doc); 33 await vscode.window.showTextDocument(doc);
34 } else if (toReveal) { 34 } else if (toReveal) {
35 const uri = Server.client.protocol2CodeConverter.asUri( 35 const uri = ctx.client.protocol2CodeConverter.asUri(
36 toReveal.textDocument.uri, 36 toReveal.textDocument.uri,
37 ); 37 );
38 const position = Server.client.protocol2CodeConverter.asPosition( 38 const position = ctx.client.protocol2CodeConverter.asPosition(
39 toReveal.position, 39 toReveal.position,
40 ); 40 );
41 const editor = vscode.window.activeTextEditor; 41 const editor = vscode.window.activeTextEditor;