Merge pull request #3190 from matklad/reload

Simplify TS reload logic
This commit is contained in:
Aleksey Kladov 2020-02-17 13:54:33 +01:00 committed by GitHub
commit 6167101302
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 62 additions and 42 deletions

View file

@ -51,10 +51,3 @@ export function selectAndApplySourceChange(ctx: Ctx): Cmd {
}
};
}
export function reload(ctx: Ctx): Cmd {
return async () => {
vscode.window.showInformationMessage('Reloading rust-analyzer...');
await ctx.restartServer();
};
}

View file

@ -1,5 +1,6 @@
import * as vscode from 'vscode';
import * as lc from 'vscode-languageclient';
import { strict as assert } from "assert";
import { Config } from './config';
import { createClient } from './client';
@ -16,19 +17,15 @@ export class Ctx {
// on the event loop to get a better picture of what we can do here)
client: lc.LanguageClient | null = null;
private extCtx: vscode.ExtensionContext;
private onDidRestartHooks: Array<(client: lc.LanguageClient) => void> = [];
constructor(extCtx: vscode.ExtensionContext) {
this.config = new Config(extCtx);
this.extCtx = extCtx;
}
async restartServer() {
const old = this.client;
if (old) {
await old.stop();
}
this.client = null;
async startServer() {
assert(this.client == null);
const client = await createClient(this.config);
if (!client) {
throw new Error(
@ -41,9 +38,6 @@ export class Ctx {
await client.onReady();
this.client = client;
for (const hook of this.onDidRestartHooks) {
hook(client);
}
}
get activeRustEditor(): vscode.TextEditor | undefined {
@ -71,10 +65,6 @@ export class Ctx {
pushCleanup(d: Disposable) {
this.extCtx.subscriptions.push(d);
}
onDidRestart(hook: (client: lc.LanguageClient) => void) {
this.onDidRestartHooks.push(hook);
}
}
export interface Disposable {

View file

@ -7,7 +7,8 @@ import { Ctx, sendRequestWithRetry } from './ctx';
export function activateHighlighting(ctx: Ctx) {
const highlighter = new Highlighter(ctx);
ctx.onDidRestart(client => {
const client = ctx.client;
if (client != null) {
client.onNotification(
'rust-analyzer/publishDecorations',
(params: PublishDecorationsParams) => {
@ -28,7 +29,7 @@ export function activateHighlighting(ctx: Ctx) {
highlighter.setHighlights(targetEditor, params.decorations);
},
);
});
};
vscode.workspace.onDidChangeConfiguration(
_ => highlighter.removeHighlights(),

View file

@ -27,9 +27,15 @@ export function activateInlayHints(ctx: Ctx) {
ctx.subscriptions
);
// We pass async function though it will not be awaited when called,
// thus Promise rejections won't be handled, but this should never throw in fact...
ctx.onDidRestart(async _ => hintsUpdater.setEnabled(ctx.config.displayInlayHints));
ctx.pushCleanup({
dispose() {
hintsUpdater.clear()
}
})
// XXX: we don't await this, thus Promise rejections won't be handled, but
// this should never throw in fact...
hintsUpdater.setEnabled(ctx.config.displayInlayHints)
}
interface InlayHintsParams {
@ -61,16 +67,23 @@ class HintsUpdater {
constructor(ctx: Ctx) {
this.ctx = ctx;
this.enabled = ctx.config.displayInlayHints;
this.enabled = false;
}
async setEnabled(enabled: boolean): Promise<void> {
console.log({ enabled, prev: this.enabled });
if (this.enabled == enabled) return;
this.enabled = enabled;
if (this.enabled) {
return await this.refresh();
} else {
return this.clear();
}
}
clear() {
this.allEditors.forEach(it => {
this.setTypeDecorations(it, []);
this.setParameterDecorations(it, []);
@ -79,6 +92,8 @@ class HintsUpdater {
async refresh() {
if (!this.enabled) return;
console.log("freshin!");
await Promise.all(this.allEditors.map(it => this.refreshEditor(it)));
}

View file

@ -11,7 +11,34 @@ let ctx: Ctx | undefined;
export async function activate(context: vscode.ExtensionContext) {
ctx = new Ctx(context);
// Note: we try to start the server before we activate type hints so that it
// registers its `onDidChangeDocument` handler before us.
//
// This a horribly, horribly wrong way to deal with this problem.
try {
await ctx.startServer();
} catch (e) {
vscode.window.showErrorMessage(e.message);
}
// Commands which invokes manually via command palette, shortcut, etc.
ctx.registerCommand('reload', (ctx) => {
return async () => {
vscode.window.showInformationMessage('Reloading rust-analyzer...');
// @DanTup maneuver
// https://github.com/microsoft/vscode/issues/45774#issuecomment-373423895
await deactivate()
for (const sub of ctx.subscriptions) {
try {
sub.dispose();
} catch (e) {
console.error(e);
}
}
await activate(context)
}
})
ctx.registerCommand('analyzerStatus', commands.analyzerStatus);
ctx.registerCommand('collectGarbage', commands.collectGarbage);
ctx.registerCommand('matchingBrace', commands.matchingBrace);
@ -20,7 +47,6 @@ export async function activate(context: vscode.ExtensionContext) {
ctx.registerCommand('syntaxTree', commands.syntaxTree);
ctx.registerCommand('expandMacro', commands.expandMacro);
ctx.registerCommand('run', commands.run);
ctx.registerCommand('reload', commands.reload);
ctx.registerCommand('onEnter', commands.onEnter);
ctx.registerCommand('ssr', commands.ssr)
@ -33,18 +59,10 @@ export async function activate(context: vscode.ExtensionContext) {
activateStatusDisplay(ctx);
activateHighlighting(ctx);
// Note: we try to start the server before we activate type hints so that it
// registers its `onDidChangeDocument` handler before us.
//
// This a horribly, horribly wrong way to deal with this problem.
try {
await ctx.restartServer();
} catch (e) {
vscode.window.showErrorMessage(e.message);
}
activateInlayHints(ctx);
}
export async function deactivate() {
await ctx?.client?.stop();
ctx = undefined;
}

View file

@ -9,11 +9,14 @@ const spinnerFrames = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '
export function activateStatusDisplay(ctx: Ctx) {
const statusDisplay = new StatusDisplay(ctx.config.cargoWatchOptions.command);
ctx.pushCleanup(statusDisplay);
ctx.onDidRestart(client => ctx.pushCleanup(client.onProgress(
WorkDoneProgress.type,
'rustAnalyzer/cargoWatcher',
params => statusDisplay.handleProgressNotification(params)
)));
const client = ctx.client;
if (client != null) {
ctx.pushCleanup(client.onProgress(
WorkDoneProgress.type,
'rustAnalyzer/cargoWatcher',
params => statusDisplay.handleProgressNotification(params)
))
}
}
class StatusDisplay implements Disposable {