diff options
author | Aleksey Kladov <[email protected]> | 2020-02-17 12:54:33 +0000 |
---|---|---|
committer | GitHub <[email protected]> | 2020-02-17 12:54:33 +0000 |
commit | 6167101302bcc2d7f1a345e0ee44e1411056b4b3 (patch) | |
tree | df40b6265f303b8fba5f804a7f7ff370e844dea0 | |
parent | fcf15cc05afaeda6880664777ff2a3db342ea088 (diff) | |
parent | d24e612106867c4bb6a1e59bf99aabfb7bc27823 (diff) |
Merge pull request #3190 from matklad/reload
Simplify TS reload logic
-rw-r--r-- | editors/code/src/commands/index.ts | 7 | ||||
-rw-r--r-- | editors/code/src/ctx.ts | 18 | ||||
-rw-r--r-- | editors/code/src/highlighting.ts | 5 | ||||
-rw-r--r-- | editors/code/src/inlay_hints.ts | 23 | ||||
-rw-r--r-- | editors/code/src/main.ts | 38 | ||||
-rw-r--r-- | editors/code/src/status_display.ts | 13 |
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 | |||
55 | export 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 @@ | |||
1 | import * as vscode from 'vscode'; | 1 | import * as vscode from 'vscode'; |
2 | import * as lc from 'vscode-languageclient'; | 2 | import * as lc from 'vscode-languageclient'; |
3 | import { strict as assert } from "assert"; | ||
3 | 4 | ||
4 | import { Config } from './config'; | 5 | import { Config } from './config'; |
5 | import { createClient } from './client'; | 6 | import { 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 | ||
80 | export interface Disposable { | 70 | export 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 | ||
8 | export function activateHighlighting(ctx: Ctx) { | 8 | export 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 | ||
35 | interface InlayHintsParams { | 41 | interface 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; | |||
11 | export async function activate(context: vscode.ExtensionContext) { | 11 | export 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 | ||
48 | export async function deactivate() { | 65 | export 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 = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', ' | |||
9 | export function activateStatusDisplay(ctx: Ctx) { | 9 | export 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 | ||
19 | class StatusDisplay implements Disposable { | 22 | class StatusDisplay implements Disposable { |