Skip to content

Commit 6167101

Browse files
authored
Merge pull request #3190 from matklad/reload
Simplify TS reload logic
2 parents fcf15cc + d24e612 commit 6167101

File tree

6 files changed

+62
-42
lines changed

6 files changed

+62
-42
lines changed

editors/code/src/commands/index.ts

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,3 @@ export function selectAndApplySourceChange(ctx: Ctx): Cmd {
5151
}
5252
};
5353
}
54-
55-
export function reload(ctx: Ctx): Cmd {
56-
return async () => {
57-
vscode.window.showInformationMessage('Reloading rust-analyzer...');
58-
await ctx.restartServer();
59-
};
60-
}

editors/code/src/ctx.ts

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import * as vscode from 'vscode';
22
import * as lc from 'vscode-languageclient';
3+
import { strict as assert } from "assert";
34

45
import { Config } from './config';
56
import { createClient } from './client';
@@ -16,19 +17,15 @@ export class Ctx {
1617
// on the event loop to get a better picture of what we can do here)
1718
client: lc.LanguageClient | null = null;
1819
private extCtx: vscode.ExtensionContext;
19-
private onDidRestartHooks: Array<(client: lc.LanguageClient) => void> = [];
2020

2121
constructor(extCtx: vscode.ExtensionContext) {
2222
this.config = new Config(extCtx);
2323
this.extCtx = extCtx;
2424
}
2525

26-
async restartServer() {
27-
const old = this.client;
28-
if (old) {
29-
await old.stop();
30-
}
31-
this.client = null;
26+
async startServer() {
27+
assert(this.client == null);
28+
3229
const client = await createClient(this.config);
3330
if (!client) {
3431
throw new Error(
@@ -41,9 +38,6 @@ export class Ctx {
4138
await client.onReady();
4239

4340
this.client = client;
44-
for (const hook of this.onDidRestartHooks) {
45-
hook(client);
46-
}
4741
}
4842

4943
get activeRustEditor(): vscode.TextEditor | undefined {
@@ -71,10 +65,6 @@ export class Ctx {
7165
pushCleanup(d: Disposable) {
7266
this.extCtx.subscriptions.push(d);
7367
}
74-
75-
onDidRestart(hook: (client: lc.LanguageClient) => void) {
76-
this.onDidRestartHooks.push(hook);
77-
}
7868
}
7969

8070
export interface Disposable {

editors/code/src/highlighting.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ import { Ctx, sendRequestWithRetry } from './ctx';
77

88
export function activateHighlighting(ctx: Ctx) {
99
const highlighter = new Highlighter(ctx);
10-
ctx.onDidRestart(client => {
10+
const client = ctx.client;
11+
if (client != null) {
1112
client.onNotification(
1213
'rust-analyzer/publishDecorations',
1314
(params: PublishDecorationsParams) => {
@@ -28,7 +29,7 @@ export function activateHighlighting(ctx: Ctx) {
2829
highlighter.setHighlights(targetEditor, params.decorations);
2930
},
3031
);
31-
});
32+
};
3233

3334
vscode.workspace.onDidChangeConfiguration(
3435
_ => highlighter.removeHighlights(),

editors/code/src/inlay_hints.ts

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,15 @@ export function activateInlayHints(ctx: Ctx) {
2727
ctx.subscriptions
2828
);
2929

30-
// We pass async function though it will not be awaited when called,
31-
// thus Promise rejections won't be handled, but this should never throw in fact...
32-
ctx.onDidRestart(async _ => hintsUpdater.setEnabled(ctx.config.displayInlayHints));
30+
ctx.pushCleanup({
31+
dispose() {
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)
3339
}
3440

3541
interface InlayHintsParams {
@@ -61,16 +67,23 @@ class HintsUpdater {
6167

6268
constructor(ctx: Ctx) {
6369
this.ctx = ctx;
64-
this.enabled = ctx.config.displayInlayHints;
70+
this.enabled = false;
6571
}
6672

6773
async setEnabled(enabled: boolean): Promise<void> {
74+
console.log({ enabled, prev: this.enabled });
75+
6876
if (this.enabled == enabled) return;
6977
this.enabled = enabled;
7078

7179
if (this.enabled) {
7280
return await this.refresh();
81+
} else {
82+
return this.clear();
7383
}
84+
}
85+
86+
clear() {
7487
this.allEditors.forEach(it => {
7588
this.setTypeDecorations(it, []);
7689
this.setParameterDecorations(it, []);
@@ -79,6 +92,8 @@ class HintsUpdater {
7992

8093
async refresh() {
8194
if (!this.enabled) return;
95+
console.log("freshin!");
96+
8297
await Promise.all(this.allEditors.map(it => this.refreshEditor(it)));
8398
}
8499

editors/code/src/main.ts

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,34 @@ let ctx: Ctx | undefined;
1111
export async function activate(context: vscode.ExtensionContext) {
1212
ctx = new Ctx(context);
1313

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+
1424
// 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+
1542
ctx.registerCommand('analyzerStatus', commands.analyzerStatus);
1643
ctx.registerCommand('collectGarbage', commands.collectGarbage);
1744
ctx.registerCommand('matchingBrace', commands.matchingBrace);
@@ -20,7 +47,6 @@ export async function activate(context: vscode.ExtensionContext) {
2047
ctx.registerCommand('syntaxTree', commands.syntaxTree);
2148
ctx.registerCommand('expandMacro', commands.expandMacro);
2249
ctx.registerCommand('run', commands.run);
23-
ctx.registerCommand('reload', commands.reload);
2450
ctx.registerCommand('onEnter', commands.onEnter);
2551
ctx.registerCommand('ssr', commands.ssr)
2652

@@ -33,18 +59,10 @@ export async function activate(context: vscode.ExtensionContext) {
3359
activateStatusDisplay(ctx);
3460

3561
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-
}
4562
activateInlayHints(ctx);
4663
}
4764

4865
export async function deactivate() {
4966
await ctx?.client?.stop();
67+
ctx = undefined;
5068
}

editors/code/src/status_display.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,14 @@ const spinnerFrames = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '
99
export function activateStatusDisplay(ctx: Ctx) {
1010
const statusDisplay = new StatusDisplay(ctx.config.cargoWatchOptions.command);
1111
ctx.pushCleanup(statusDisplay);
12-
ctx.onDidRestart(client => ctx.pushCleanup(client.onProgress(
13-
WorkDoneProgress.type,
14-
'rustAnalyzer/cargoWatcher',
15-
params => statusDisplay.handleProgressNotification(params)
16-
)));
12+
const client = ctx.client;
13+
if (client != null) {
14+
ctx.pushCleanup(client.onProgress(
15+
WorkDoneProgress.type,
16+
'rustAnalyzer/cargoWatcher',
17+
params => statusDisplay.handleProgressNotification(params)
18+
))
19+
}
1720
}
1821

1922
class StatusDisplay implements Disposable {

0 commit comments

Comments
 (0)