Skip to content

Commit 563c3ff

Browse files
mjbvzandrewbranch
andauthored
Don't require VSCode ext host restart on change (#1722)
Co-authored-by: Andrew Branch <[email protected]>
1 parent acc1667 commit 563c3ff

File tree

5 files changed

+76
-43
lines changed

5 files changed

+76
-43
lines changed

_extension/src/client.ts

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -81,12 +81,12 @@ export class Client {
8181
};
8282
}
8383

84-
async initialize(context: vscode.ExtensionContext): Promise<void> {
84+
async initialize(context: vscode.ExtensionContext): Promise<vscode.Disposable> {
8585
const exe = await getExe(context);
86-
this.start(context, exe);
86+
return this.start(context, exe);
8787
}
8888

89-
async start(context: vscode.ExtensionContext, exe: { path: string; version: string; }): Promise<void> {
89+
async start(context: vscode.ExtensionContext, exe: { path: string; version: string; }): Promise<vscode.Disposable> {
9090
this.exe = exe;
9191
this.outputChannel.appendLine(`Resolved to ${this.exe.path}`);
9292

@@ -119,14 +119,12 @@ export class Client {
119119
await this.client.start();
120120
vscode.commands.executeCommand("setContext", "typescript.native-preview.serverRunning", true);
121121
this.onStartedCallbacks.forEach(callback => callback());
122-
context.subscriptions.push(
123-
new vscode.Disposable(() => {
124-
if (this.client) {
125-
this.client.stop();
126-
}
127-
vscode.commands.executeCommand("setContext", "typescript.native-preview.serverRunning", false);
128-
}),
129-
);
122+
return new vscode.Disposable(() => {
123+
if (this.client) {
124+
this.client.stop();
125+
}
126+
vscode.commands.executeCommand("setContext", "typescript.native-preview.serverRunning", false);
127+
});
130128
}
131129

132130
getCurrentExe(): { path: string; version: string; } | undefined {
@@ -145,7 +143,7 @@ export class Client {
145143
});
146144
}
147145

148-
async restart(context: vscode.ExtensionContext): Promise<void> {
146+
async restart(context: vscode.ExtensionContext): Promise<vscode.Disposable> {
149147
if (!this.client) {
150148
return Promise.reject(new Error("Language client is not initialized"));
151149
}
@@ -157,6 +155,7 @@ export class Client {
157155
}
158156

159157
this.outputChannel.appendLine(`Restarting language server...`);
160-
return this.client.restart();
158+
this.client.restart();
159+
return new vscode.Disposable(() => {});
161160
}
162161
}

_extension/src/commands.ts

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import * as vscode from "vscode";
22
import { Client } from "./client";
33

4-
export function registerCommands(context: vscode.ExtensionContext, client: Client, outputChannel: vscode.OutputChannel, traceOutputChannel: vscode.OutputChannel): void {
4+
export function registerEnablementCommands(context: vscode.ExtensionContext): void {
55
context.subscriptions.push(vscode.commands.registerCommand("typescript.native-preview.enable", () => {
66
// Fire and forget, because this will restart the extension host and cause an error if we await
77
updateUseTsgoSetting(true);
@@ -11,23 +11,29 @@ export function registerCommands(context: vscode.ExtensionContext, client: Clien
1111
// Fire and forget, because this will restart the extension host and cause an error if we await
1212
updateUseTsgoSetting(false);
1313
}));
14+
}
15+
16+
export function registerLanguageCommands(context: vscode.ExtensionContext, client: Client, outputChannel: vscode.OutputChannel, traceOutputChannel: vscode.OutputChannel): vscode.Disposable[] {
17+
const disposables: vscode.Disposable[] = [];
1418

15-
context.subscriptions.push(vscode.commands.registerCommand("typescript.native-preview.restart", () => {
19+
disposables.push(vscode.commands.registerCommand("typescript.native-preview.restart", () => {
1620
return client.restart(context);
1721
}));
1822

19-
context.subscriptions.push(vscode.commands.registerCommand("typescript.native-preview.output.focus", () => {
23+
disposables.push(vscode.commands.registerCommand("typescript.native-preview.output.focus", () => {
2024
outputChannel.show();
2125
}));
2226

23-
context.subscriptions.push(vscode.commands.registerCommand("typescript.native-preview.lsp-trace.focus", () => {
27+
disposables.push(vscode.commands.registerCommand("typescript.native-preview.lsp-trace.focus", () => {
2428
traceOutputChannel.show();
2529
}));
2630

27-
context.subscriptions.push(vscode.commands.registerCommand("typescript.native-preview.selectVersion", async () => {
31+
disposables.push(vscode.commands.registerCommand("typescript.native-preview.selectVersion", async () => {
2832
}));
2933

30-
context.subscriptions.push(vscode.commands.registerCommand("typescript.native-preview.showMenu", showCommands));
34+
disposables.push(vscode.commands.registerCommand("typescript.native-preview.showMenu", showCommands));
35+
36+
return disposables;
3137
}
3238

3339
/**

_extension/src/extension.ts

Lines changed: 43 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,48 @@
11
import * as vscode from "vscode";
22

33
import { Client } from "./client";
4-
import { registerCommands } from "./commands";
4+
import {
5+
registerEnablementCommands,
6+
registerLanguageCommands,
7+
} from "./commands";
58
import { setupStatusBar } from "./statusBar";
69
import { setupVersionStatusItem } from "./versionStatusItem";
710

811
export async function activate(context: vscode.ExtensionContext) {
912
await vscode.commands.executeCommand("setContext", "typescript.native-preview.serverRunning", false);
10-
13+
registerEnablementCommands(context);
1114
const output = vscode.window.createOutputChannel("typescript-native-preview", "log");
1215
const traceOutput = vscode.window.createOutputChannel("typescript-native-preview (LSP)");
13-
const client = new Client(output, traceOutput);
14-
registerCommands(context, client, output, traceOutput);
16+
context.subscriptions.push(output, traceOutput);
1517

16-
context.subscriptions.push(vscode.workspace.onDidChangeConfiguration(event => {
18+
const majorVersion = parseInt(vscode.version.split(".")[0]);
19+
const minorVersion = parseInt(vscode.version.split(".")[1]);
20+
const needsExtHostRestartOnChange = majorVersion <= 1 && minorVersion < 105;
21+
let disposeLanguageFeatures: vscode.Disposable | undefined;
22+
23+
context.subscriptions.push(vscode.workspace.onDidChangeConfiguration(async event => {
1724
if (event.affectsConfiguration("typescript.experimental.useTsgo")) {
18-
// Delay because the command to change the config setting will restart
19-
// the extension host, so no need to show a message
20-
setTimeout(async () => {
21-
const selected = await vscode.window.showInformationMessage("TypeScript Native Preview setting has changed. Restart extensions to apply changes.", "Restart Extensions");
22-
if (selected) {
23-
vscode.commands.executeCommand("workbench.action.restartExtensionHost");
25+
if (needsExtHostRestartOnChange) {
26+
// Delay because the command to change the config setting will restart
27+
// the extension host, so no need to show a message
28+
setTimeout(async () => {
29+
const selected = await vscode.window.showInformationMessage("TypeScript Native Preview setting has changed. Restart extensions to apply changes.", "Restart Extensions");
30+
if (selected) {
31+
vscode.commands.executeCommand("workbench.action.restartExtensionHost");
32+
}
33+
}, 100);
34+
}
35+
else {
36+
const useTsgo = vscode.workspace.getConfiguration("typescript").get<boolean>("experimental.useTsgo");
37+
if (useTsgo) {
38+
disposeLanguageFeatures = await activateLanguageFeatures(context, output, traceOutput);
39+
context.subscriptions.push(disposeLanguageFeatures);
2440
}
25-
}, 100);
41+
else {
42+
disposeLanguageFeatures?.dispose();
43+
disposeLanguageFeatures = undefined;
44+
}
45+
}
2646
}
2747
}));
2848

@@ -41,10 +61,17 @@ export async function activate(context: vscode.ExtensionContext) {
4161
}
4262
}
4363

44-
await client.initialize(context);
45-
setupStatusBar(context);
46-
setupVersionStatusItem(context, client);
64+
disposeLanguageFeatures = await activateLanguageFeatures(context, output, traceOutput);
65+
context.subscriptions.push(disposeLanguageFeatures);
4766
}
4867

49-
export async function deactivate(): Promise<void> {
68+
async function activateLanguageFeatures(context: vscode.ExtensionContext, output: vscode.OutputChannel, traceOutput: vscode.OutputChannel): Promise<vscode.Disposable> {
69+
const disposables: vscode.Disposable[] = [];
70+
71+
const client = new Client(output, traceOutput);
72+
disposables.push(...registerLanguageCommands(context, client, output, traceOutput));
73+
disposables.push(await client.initialize(context));
74+
disposables.push(setupStatusBar());
75+
disposables.push(...setupVersionStatusItem(client));
76+
return vscode.Disposable.from(...disposables);
5077
}

_extension/src/statusBar.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import * as vscode from "vscode";
22

3-
export function setupStatusBar(context: vscode.ExtensionContext): void {
3+
export function setupStatusBar(): vscode.Disposable {
44
const statusBarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right, 100);
55
statusBarItem.text = "$(beaker) tsgo";
66
statusBarItem.tooltip = "TypeScript Native Preview Language Server";
77
statusBarItem.command = "typescript.native-preview.showMenu";
88
statusBarItem.backgroundColor = new vscode.ThemeColor("statusBarItem.warningBackground");
99
statusBarItem.show();
10-
context.subscriptions.push(statusBarItem);
10+
return statusBarItem;
1111
}

_extension/src/versionStatusItem.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,15 @@ import { Client } from "./client";
33
import { jsTsLanguageModes } from "./util";
44

55
export function setupVersionStatusItem(
6-
context: vscode.ExtensionContext,
76
client: Client,
8-
): void {
7+
): vscode.Disposable[] {
98
const statusItem = vscode.languages.createLanguageStatusItem("typescript.native-preview.version", jsTsLanguageModes);
109
statusItem.name = "TypeScript Native Preview version";
1110
statusItem.detail = "TypeScript Native Preview version";
12-
context.subscriptions.push(client.onStarted(() => {
13-
statusItem.text = client.getCurrentExe()!.version;
14-
}));
15-
context.subscriptions.push(statusItem);
11+
return [
12+
statusItem,
13+
client.onStarted(() => {
14+
statusItem.text = client.getCurrentExe()!.version;
15+
}),
16+
];
1617
}

0 commit comments

Comments
 (0)