aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2020-02-17 12:54:33 +0000
committerGitHub <[email protected]>2020-02-17 12:54:33 +0000
commit6167101302bcc2d7f1a345e0ee44e1411056b4b3 (patch)
treedf40b6265f303b8fba5f804a7f7ff370e844dea0
parentfcf15cc05afaeda6880664777ff2a3db342ea088 (diff)
parentd24e612106867c4bb6a1e59bf99aabfb7bc27823 (diff)
Merge pull request #3190 from matklad/reload
Simplify TS reload logic
-rw-r--r--editors/code/src/commands/index.ts7
-rw-r--r--editors/code/src/ctx.ts18
-rw-r--r--editors/code/src/highlighting.ts5
-rw-r--r--editors/code/src/inlay_hints.ts23
-rw-r--r--editors/code/src/main.ts38
-rw-r--r--editors/code/src/status_display.ts13
6 files changed, 62 insertions, 42 deletions
diff --git a/editors/code/src/commands/index.ts b/editors/code/src/commands/index.ts
index b5ebec117..d05f40d67 100644
--- a/editors/code/src/commands/index.ts
+++ b/editors/code/src/commands/index.ts
@@ -51,10 +51,3 @@ export function selectAndApplySourceChange(ctx: Ctx): Cmd {
51 } 51 }
52 }; 52 };
53} 53}
54
55export function reload(ctx: Ctx): Cmd {
56 return async () => {
57 vscode.window.showInformationMessage('Reloading rust-analyzer...');
58 await ctx.restartServer();
59 };
60}
diff --git a/editors/code/src/ctx.ts b/editors/code/src/ctx.ts
index ff6245f78..c06d8ac31 100644
--- a/editors/code/src/ctx.ts
+++ b/editors/code/src/ctx.ts
@@ -1,5 +1,6 @@
1import * as vscode from 'vscode'; 1import * as vscode from 'vscode';
2import * as lc from 'vscode-languageclient'; 2import * as lc from 'vscode-languageclient';
3import { strict as assert } from "assert";
3 4
4import { Config } from './config'; 5import { Config } from './config';
5import { createClient } from './client'; 6import { createClient } from './client';
@@ -16,19 +17,15 @@ export class Ctx {
16 // on the event loop to get a better picture of what we can do here) 17 // on the event loop to get a better picture of what we can do here)
17 client: lc.LanguageClient | null = null; 18 client: lc.LanguageClient | null = null;
18 private extCtx: vscode.ExtensionContext; 19 private extCtx: vscode.ExtensionContext;
19 private onDidRestartHooks: Array<(client: lc.LanguageClient) => void> = [];
20 20
21 constructor(extCtx: vscode.ExtensionContext) { 21 constructor(extCtx: vscode.ExtensionContext) {
22 this.config = new Config(extCtx); 22 this.config = new Config(extCtx);
23 this.extCtx = extCtx; 23 this.extCtx = extCtx;
24 } 24 }
25 25
26 async restartServer() { 26 async startServer() {
27 const old = this.client; 27 assert(this.client == null);
28 if (old) { 28
29 await old.stop();
30 }
31 this.client = null;
32 const client = await createClient(this.config); 29 const client = await createClient(this.config);
33 if (!client) { 30 if (!client) {
34 throw new Error( 31 throw new Error(
@@ -41,9 +38,6 @@ export class Ctx {
41 await client.onReady(); 38 await client.onReady();
42 39
43 this.client = client; 40 this.client = client;
44 for (const hook of this.onDidRestartHooks) {
45 hook(client);
46 }
47 } 41 }
48 42
49 get activeRustEditor(): vscode.TextEditor | undefined { 43 get activeRustEditor(): vscode.TextEditor | undefined {
@@ -71,10 +65,6 @@ export class Ctx {
71 pushCleanup(d: Disposable) { 65 pushCleanup(d: Disposable) {
72 this.extCtx.subscriptions.push(d); 66 this.extCtx.subscriptions.push(d);
73 } 67 }
74
75 onDidRestart(hook: (client: lc.LanguageClient) => void) {
76 this.onDidRestartHooks.push(hook);
77 }
78} 68}
79 69
80export interface Disposable { 70export interface Disposable {
diff --git a/editors/code/src/highlighting.ts b/editors/code/src/highlighting.ts
index 4fbbe3ddc..a2db04de8 100644
--- a/editors/code/src/highlighting.ts
+++ b/editors/code/src/highlighting.ts
@@ -7,7 +7,8 @@ import { Ctx, sendRequestWithRetry } from './ctx';
7 7
8export function activateHighlighting(ctx: Ctx) { 8export function activateHighlighting(ctx: Ctx) {
9 const highlighter = new Highlighter(ctx); 9 const highlighter = new Highlighter(ctx);
10 ctx.onDidRestart(client => { 10 const client = ctx.client;
11 if (client != null) {
11 client.onNotification( 12 client.onNotification(
12 'rust-analyzer/publishDecorations', 13 'rust-analyzer/publishDecorations',
13 (params: PublishDecorationsParams) => { 14 (params: PublishDecorationsParams) => {
@@ -28,7 +29,7 @@ export function activateHighlighting(ctx: Ctx) {
28 highlighter.setHighlights(targetEditor, params.decorations); 29 highlighter.setHighlights(targetEditor, params.decorations);
29 }, 30 },
30 ); 31 );
31 }); 32 };
32 33
33 vscode.workspace.onDidChangeConfiguration( 34 vscode.workspace.onDidChangeConfiguration(
34 _ => highlighter.removeHighlights(), 35 _ => highlighter.removeHighlights(),
diff --git a/editors/code/src/inlay_hints.ts b/editors/code/src/inlay_hints.ts
index 3896878cd..55bbd7f00 100644
--- a/editors/code/src/inlay_hints.ts
+++ b/editors/code/src/inlay_hints.ts
@@ -27,9 +27,15 @@ export function activateInlayHints(ctx: Ctx) {
27 ctx.subscriptions 27 ctx.subscriptions
28 ); 28 );
29 29
30 // We pass async function though it will not be awaited when called, 30 ctx.pushCleanup({
31 // thus Promise rejections won't be handled, but this should never throw in fact... 31 dispose() {
32 ctx.onDidRestart(async _ => hintsUpdater.setEnabled(ctx.config.displayInlayHints)); 32 hintsUpdater.clear()
33 }
34 })
35
36 // XXX: we don't await this, thus Promise rejections won't be handled, but
37 // this should never throw in fact...
38 hintsUpdater.setEnabled(ctx.config.displayInlayHints)
33} 39}
34 40
35interface InlayHintsParams { 41interface InlayHintsParams {
@@ -61,16 +67,23 @@ class HintsUpdater {
61 67
62 constructor(ctx: Ctx) { 68 constructor(ctx: Ctx) {
63 this.ctx = ctx; 69 this.ctx = ctx;
64 this.enabled = ctx.config.displayInlayHints; 70 this.enabled = false;
65 } 71 }
66 72
67 async setEnabled(enabled: boolean): Promise<void> { 73 async setEnabled(enabled: boolean): Promise<void> {
74 console.log({ enabled, prev: this.enabled });
75
68 if (this.enabled == enabled) return; 76 if (this.enabled == enabled) return;
69 this.enabled = enabled; 77 this.enabled = enabled;
70 78
71 if (this.enabled) { 79 if (this.enabled) {
72 return await this.refresh(); 80 return await this.refresh();
81 } else {
82 return this.clear();
73 } 83 }
84 }
85
86 clear() {
74 this.allEditors.forEach(it => { 87 this.allEditors.forEach(it => {
75 this.setTypeDecorations(it, []); 88 this.setTypeDecorations(it, []);
76 this.setParameterDecorations(it, []); 89 this.setParameterDecorations(it, []);
@@ -79,6 +92,8 @@ class HintsUpdater {
79 92
80 async refresh() { 93 async refresh() {
81 if (!this.enabled) return; 94 if (!this.enabled) return;
95 console.log("freshin!");
96
82 await Promise.all(this.allEditors.map(it => this.refreshEditor(it))); 97 await Promise.all(this.allEditors.map(it => this.refreshEditor(it)));
83 } 98 }
84 99
diff --git a/editors/code/src/main.ts b/editors/code/src/main.ts
index 5a99e96f0..0bf2c4829 100644
--- a/editors/code/src/main.ts
+++ b/editors/code/src/main.ts
@@ -11,7 +11,34 @@ let ctx: Ctx | undefined;
11export async function activate(context: vscode.ExtensionContext) { 11export async function activate(context: vscode.ExtensionContext) {
12 ctx = new Ctx(context); 12 ctx = new Ctx(context);
13 13
14 // Note: we try to start the server before we activate type hints so that it
15 // registers its `onDidChangeDocument` handler before us.
16 //
17 // This a horribly, horribly wrong way to deal with this problem.
18 try {
19 await ctx.startServer();
20 } catch (e) {
21 vscode.window.showErrorMessage(e.message);
22 }
23
14 // Commands which invokes manually via command palette, shortcut, etc. 24 // Commands which invokes manually via command palette, shortcut, etc.
25 ctx.registerCommand('reload', (ctx) => {
26 return async () => {
27 vscode.window.showInformationMessage('Reloading rust-analyzer...');
28 // @DanTup maneuver
29 // https://github.com/microsoft/vscode/issues/45774#issuecomment-373423895
30 await deactivate()
31 for (const sub of ctx.subscriptions) {
32 try {
33 sub.dispose();
34 } catch (e) {
35 console.error(e);
36 }
37 }
38 await activate(context)
39 }
40 })
41
15 ctx.registerCommand('analyzerStatus', commands.analyzerStatus); 42 ctx.registerCommand('analyzerStatus', commands.analyzerStatus);
16 ctx.registerCommand('collectGarbage', commands.collectGarbage); 43 ctx.registerCommand('collectGarbage', commands.collectGarbage);
17 ctx.registerCommand('matchingBrace', commands.matchingBrace); 44 ctx.registerCommand('matchingBrace', commands.matchingBrace);
@@ -20,7 +47,6 @@ export async function activate(context: vscode.ExtensionContext) {
20 ctx.registerCommand('syntaxTree', commands.syntaxTree); 47 ctx.registerCommand('syntaxTree', commands.syntaxTree);
21 ctx.registerCommand('expandMacro', commands.expandMacro); 48 ctx.registerCommand('expandMacro', commands.expandMacro);
22 ctx.registerCommand('run', commands.run); 49 ctx.registerCommand('run', commands.run);
23 ctx.registerCommand('reload', commands.reload);
24 ctx.registerCommand('onEnter', commands.onEnter); 50 ctx.registerCommand('onEnter', commands.onEnter);
25 ctx.registerCommand('ssr', commands.ssr) 51 ctx.registerCommand('ssr', commands.ssr)
26 52
@@ -33,18 +59,10 @@ export async function activate(context: vscode.ExtensionContext) {
33 activateStatusDisplay(ctx); 59 activateStatusDisplay(ctx);
34 60
35 activateHighlighting(ctx); 61 activateHighlighting(ctx);
36 // Note: we try to start the server before we activate type hints so that it
37 // registers its `onDidChangeDocument` handler before us.
38 //
39 // This a horribly, horribly wrong way to deal with this problem.
40 try {
41 await ctx.restartServer();
42 } catch (e) {
43 vscode.window.showErrorMessage(e.message);
44 }
45 activateInlayHints(ctx); 62 activateInlayHints(ctx);
46} 63}
47 64
48export async function deactivate() { 65export async function deactivate() {
49 await ctx?.client?.stop(); 66 await ctx?.client?.stop();
67 ctx = undefined;
50} 68}
diff --git a/editors/code/src/status_display.ts b/editors/code/src/status_display.ts
index 993e79d70..ed0d82166 100644
--- a/editors/code/src/status_display.ts
+++ b/editors/code/src/status_display.ts
@@ -9,11 +9,14 @@ const spinnerFrames = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '
9export function activateStatusDisplay(ctx: Ctx) { 9export function activateStatusDisplay(ctx: Ctx) {
10 const statusDisplay = new StatusDisplay(ctx.config.cargoWatchOptions.command); 10 const statusDisplay = new StatusDisplay(ctx.config.cargoWatchOptions.command);
11 ctx.pushCleanup(statusDisplay); 11 ctx.pushCleanup(statusDisplay);
12 ctx.onDidRestart(client => ctx.pushCleanup(client.onProgress( 12 const client = ctx.client;
13 WorkDoneProgress.type, 13 if (client != null) {
14 'rustAnalyzer/cargoWatcher', 14 ctx.pushCleanup(client.onProgress(
15 params => statusDisplay.handleProgressNotification(params) 15 WorkDoneProgress.type,
16 ))); 16 'rustAnalyzer/cargoWatcher',
17 params => statusDisplay.handleProgressNotification(params)
18 ))
19 }
17} 20}
18 21
19class StatusDisplay implements Disposable { 22class StatusDisplay implements Disposable {