vscode-languageclient#BaseLanguageClient TypeScript Examples

The following examples show how to use vscode-languageclient#BaseLanguageClient. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: activeSelection.ts    From volar with MIT License 6 votes vote down vote up
export async function activate(context: vscode.ExtensionContext, languageClient: BaseLanguageClient) {
	context.subscriptions.push(languageClient.onRequest(shared.GetEditorSelectionRequest.type, () => {
		const editor = vscode.window.activeTextEditor;
		if (editor) {
			return {
				textDocument: {
					uri: languageClient.code2ProtocolConverter.asUri(editor.document.uri),
				},
				position: editor.selection.end,
			};
		}
	}));
}
Example #2
Source File: callGraph.ts    From volar with MIT License 6 votes vote down vote up
export async function activate(context: vscode.ExtensionContext, languageClient: BaseLanguageClient) {
	context.subscriptions.push(vscode.commands.registerCommand('volar.action.showCallGraph', async () => {
		const document = vscode.window.activeTextEditor?.document;
		if (!document) return;
		let param = languageClient.code2ProtocolConverter.asTextDocumentIdentifier(document);
		const d3 = await languageClient.sendRequest(shared.D3Request.type, param);

		const panel = vscode.window.createWebviewPanel(
			'vueCallGraph',
			'Vue Call Graph',
			vscode.ViewColumn.One,
			{
				enableScripts: true
			}
		);
		panel.webview.html = `
<script src="https://d3js.org/d3.v5.min.js"></script>
<script src="https://unpkg.com/[email protected]/viz.js" type="javascript/worker"></script>
<script src="https://unpkg.com/[email protected]/build/d3-graphviz.min.js"></script>
<div id="graph" style="text-align: center;"></div>
<script>

    var dotIndex = 0;
    var graphviz = d3.select("#graph").graphviz()
        .zoom(false)
        .on("initEnd", render)

    function render() {
        var dot = \`${d3}\`;
        graphviz
            .renderDot(dot)
    }

</script>
`;
	}));
}
Example #3
Source File: documentContent.ts    From volar with MIT License 6 votes vote down vote up
export async function activate(context: vscode.ExtensionContext, languageClient: BaseLanguageClient) {

	const schemaDocuments: { [uri: string]: boolean; } = {};

	context.subscriptions.push(languageClient.onRequest(shared.GetDocumentContentRequest.type, handle => {
		const uri = vscode.Uri.parse(handle.uri);
		if (uri.scheme === 'untitled') {
			return Promise.reject(new ResponseError(3, localize('untitled.schema', 'Unable to load {0}', uri.toString())));
		}
		if (uri.scheme !== 'http' && uri.scheme !== 'https') {
			return vscode.workspace.openTextDocument(uri).then(doc => {
				schemaDocuments[uri.toString()] = true;
				return doc.getText();
			}, error => {
				return Promise.reject(new ResponseError(2, error.toString()));
			});
		}
		// else if (schemaDownloadEnabled) {
		//     if (runtime.telemetry && uri.authority === 'schema.management.azure.com') {
		//         /* __GDPR__
		//             "json.schema" : {
		//                 "schemaURL" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
		//             }
		//          */
		//         runtime.telemetry.sendTelemetryEvent('json.schema', { schemaURL: uriPath });
		//     }
		//     return runtime.http.getContent(uriPath);
		// }
		else {
			// return Promise.reject(new ResponseError(1, localize('schemaDownloadDisabled', 'Downloading schemas is disabled through setting \'{0}\'', SettingIds.enableSchemaDownload)));
			return Promise.reject(new ResponseError(0, 'Downloading schemas is not support yet'));
		}
	}));
}
Example #4
Source File: showReferences.ts    From volar with MIT License 6 votes vote down vote up
export async function activate(context: vscode.ExtensionContext, languageClient: BaseLanguageClient) {
	context.subscriptions.push(languageClient.onNotification(shared.ShowReferencesNotification.type, handler => {
		const uri = handler.textDocument.uri;
		const pos = handler.position;
		const refs = handler.references;
		vscode.commands.executeCommand(
			'editor.action.showReferences',
			vscode.Uri.parse(uri),
			new vscode.Position(pos.line, pos.character),
			refs.map(ref => new vscode.Location(
				vscode.Uri.parse(ref.uri),
				new vscode.Range(ref.range.start.line, ref.range.start.character, ref.range.end.line, ref.range.end.character),
			)),
		);
	}));
}
Example #5
Source File: languageServerClient.test.ts    From vscode-stripe with MIT License 6 votes vote down vote up
class TestLanguageClient extends BaseLanguageClient {
  protected getLocale(): string {
    throw new Error('Method not implemented.');
  }
  constructor() {
    super('foo', 'foo', {});
  }
  protected createMessageTransports(): Promise<MessageTransports> {
    throw new Error('Method not implemented.');
  }
  start() {
    return {dispose: () => {}};
  }

  onReady() {
    return Promise.resolve();
  }
}
Example #6
Source File: documentVersion.ts    From volar with MIT License 5 votes vote down vote up
export async function activate(context: vscode.ExtensionContext, languageClient: BaseLanguageClient) {
	context.subscriptions.push(languageClient.onRequest(shared.GetDocumentVersionRequest.type, handler => {
		const doc = vscode.workspace.textDocuments.find(doc => doc.uri.toString() === handler.uri);
		return doc?.version;
	}));
}
Example #7
Source File: tsconfig.ts    From volar with MIT License 5 votes vote down vote up
export async function activate(context: vscode.ExtensionContext, languageClient: BaseLanguageClient) {

	const statusBar = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right);
	let currentTsconfig = '';

	updateStatusBar();

	vscode.window.onDidChangeActiveTextEditor(updateStatusBar, undefined, context.subscriptions);
	vscode.commands.registerCommand('volar.openTsconfig', async () => {
		const document = await vscode.workspace.openTextDocument(currentTsconfig);
		await vscode.window.showTextDocument(document);
	});

	async function updateStatusBar() {
		if (
			vscode.window.activeTextEditor?.document.languageId !== 'vue'
			&& !(
				takeOverModeEnabled()
				&& vscode.window.activeTextEditor
				&& ['javascript', 'typescript', 'javascriptreact', 'typescriptreact'].includes(vscode.window.activeTextEditor.document.languageId)
			)
		) {
			statusBar.hide();
		}
		else {
			const tsconfig = await languageClient.sendRequest(
				shared.GetMatchTsConfigRequest.type,
				languageClient.code2ProtocolConverter.asTextDocumentIdentifier(vscode.window.activeTextEditor.document),
			);
			if (tsconfig) {
				statusBar.text = path.relative(vscode.workspace.rootPath!, tsconfig);
				statusBar.command = 'volar.openTsconfig';
				currentTsconfig = tsconfig;
			}
			else {
				statusBar.text = 'No tsconfig';
				statusBar.command = undefined;
			}
			statusBar.show();
		}
	}
}
Example #8
Source File: verifyAll.ts    From volar with MIT License 5 votes vote down vote up
export async function activate(context: vscode.ExtensionContext, languageClient: BaseLanguageClient) {
	context.subscriptions.push(vscode.commands.registerCommand('volar.action.verifyAllScripts', () => {
		languageClient.sendNotification(shared.VerifyAllScriptsNotification.type);
	}));
}
Example #9
Source File: virtualFiles.ts    From volar with MIT License 5 votes vote down vote up
export async function activate(context: vscode.ExtensionContext, languageClient: BaseLanguageClient) {
	context.subscriptions.push(vscode.commands.registerCommand('volar.action.writeVirtualFiles', () => {
		languageClient.sendNotification(shared.WriteVirtualFilesNotification.type);
	}));
}
Example #10
Source File: editorHelper.ts    From coffeesense with MIT License 5 votes vote down vote up
sendLSRequest: BaseLanguageClient['sendRequest'] = (...args: any[]) => ext!.exports.sendRequest(...args)
Example #11
Source File: attrNameCase.ts    From volar with MIT License 4 votes vote down vote up
export async function activate(context: vscode.ExtensionContext, languageClient: BaseLanguageClient) {

	const attrCases = shared.createPathMap<'kebabCase' | 'camelCase'>();
	const statusBar = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right);
	statusBar.command = 'volar.action.attrNameCase';

	onChangeDocument(vscode.window.activeTextEditor?.document);
	const d_1 = vscode.window.onDidChangeActiveTextEditor(e => {
		onChangeDocument(e?.document);
	});
	const d_2 = vscode.workspace.onDidCloseTextDocument((doc) => {
		attrCases.uriDelete(doc.uri.toString());
	});
	const d_3 = vscode.commands.registerCommand('volar.action.attrNameCase', async () => {

		const crtDoc = vscode.window.activeTextEditor?.document;
		if (!crtDoc) return;

		const attrCase = attrCases.uriGet(crtDoc.uri.toString());
		const options: Record<string, vscode.QuickPickItem> = {};

		options[4] = { label: (attrCase === 'kebabCase' ? '• ' : '') + 'Prop Using kebab-case' };
		options[5] = { label: (attrCase === 'camelCase' ? '• ' : '') + 'Prop Using camelCase' };
		options[6] = { label: 'Detect Prop name from Content' };

		const select = await userPick(options);
		if (select === undefined)
			return; // cancel

		if (select === '4') {
			attrCases.uriSet(crtDoc.uri.toString(), 'kebabCase');
			updateStatusBarText('kebabCase');
		}
		if (select === '5') {
			attrCases.uriSet(crtDoc.uri.toString(), 'camelCase');
			updateStatusBarText('camelCase');
		}
		if (select === '6') {
			const detects = await languageClient.sendRequest(shared.DetectDocumentNameCasesRequest.type, languageClient.code2ProtocolConverter.asTextDocumentIdentifier(crtDoc));
			if (detects) {
				attrCases.uriSet(crtDoc.uri.toString(), getValidAttrCase(detects.attr));
				updateStatusBarText(getValidAttrCase(detects.attr));
			}
		}
	});

	languageClient.onDidChangeState(e => {
		if (e.newState === State.Stopped) {
			d_1.dispose();
			d_2.dispose();
			d_3.dispose();
			statusBar.dispose();
		}
	});

	return (uri: string) => {
		let attrCase = attrCases.uriGet(uri);
		if (uri.toLowerCase() === vscode.window.activeTextEditor?.document.uri.toString().toLowerCase()) {
			updateStatusBarText(attrCase);
		}
		return attrCase ?? 'kebabCase';
	};

	async function onChangeDocument(newDoc: vscode.TextDocument | undefined) {
		if (newDoc?.languageId === 'vue') {
			let attrCase = attrCases.uriGet(newDoc.uri.toString());
			if (!attrCase) {
				const attrMode = vscode.workspace.getConfiguration('volar').get<'auto-kebab' | 'auto-camel' | 'kebab' | 'camel'>('completion.preferredAttrNameCase');
				if (attrMode === 'kebab') {
					attrCase = 'kebabCase';
				}
				else if (attrMode === 'camel') {
					attrCase = 'camelCase';
				}
				else {
					const templateCases = await languageClient.sendRequest(shared.DetectDocumentNameCasesRequest.type, languageClient.code2ProtocolConverter.asTextDocumentIdentifier(newDoc));
					if (templateCases) {
						attrCase = getValidAttrCase(templateCases.attr);
						if (templateCases.attr === 'both') {
							if (attrMode === 'auto-kebab') {
								attrCase = 'kebabCase';
							}
							else if (attrMode === 'auto-camel') {
								attrCase = 'camelCase';
							}
						}
					}
				}
			}
			if (attrCase) {
				attrCases.uriSet(newDoc.uri.toString(), attrCase ?? 'unsure');
			}
			updateStatusBarText(attrCase);
			statusBar.show();
		}
		else {
			statusBar.hide();
		}
	}
	function getValidAttrCase(attrCase: 'both' | 'kebabCase' | 'camelCase' | 'unsure' | undefined): 'kebabCase' | 'camelCase' {
		if (attrCase === 'both' || attrCase === 'unsure') {
			const attrMode = vscode.workspace.getConfiguration('volar').get<'auto-kebab' | 'auto-camel' | 'kebab' | 'camel'>('completion.preferredAttrNameCase');
			if (attrMode === 'auto-kebab') {
				return 'kebabCase';
			}
			else if (attrMode === 'auto-camel') {
				return 'camelCase';
			}
			return 'kebabCase';
		}
		return attrCase ?? 'kebabCase';
	}
	function updateStatusBarText(
		attrCase: 'kebabCase' | 'camelCase' | undefined,
	) {
		let text = `Attr: `;
		if (attrCase === 'kebabCase' || attrCase === undefined) {
			text += `kebab-case`;
		}
		else if (attrCase === 'camelCase') {
			text += `camelCase`;
		}
		statusBar.text = text;
	}
}
Example #12
Source File: autoInsertion.ts    From volar with MIT License 4 votes vote down vote up
export async function activate(context: vscode.ExtensionContext, htmlClient: BaseLanguageClient, tsClient: BaseLanguageClient) {

	const supportedLanguages: Record<string, boolean> = {
		vue: true,
		javascript: true,
		typescript: true,
		javascriptreact: true,
		typescriptreact: true,
	};

	let disposables: vscode.Disposable[] = [];
	vscode.workspace.onDidChangeTextDocument(onDidChangeTextDocument, null, disposables);

	let isEnabled = false;
	updateEnabledState();
	vscode.window.onDidChangeActiveTextEditor(updateEnabledState, null, disposables);

	let timeout: NodeJS.Timeout | undefined;

	function updateEnabledState() {
		isEnabled = false;
		let editor = vscode.window.activeTextEditor;
		if (!editor) {
			return;
		}
		let document = editor.document;
		if (!supportedLanguages[document.languageId]) {
			return;
		}
		isEnabled = true;
	}

	function onDidChangeTextDocument({ document, contentChanges, reason }: vscode.TextDocumentChangeEvent) {
		if (!isEnabled || contentChanges.length === 0 || reason === vscode.TextDocumentChangeReason.Undo || reason === vscode.TextDocumentChangeReason.Redo) {
			return;
		}
		const activeDocument = vscode.window.activeTextEditor?.document;
		if (document !== activeDocument) {
			return;
		}
		if (timeout) {
			clearTimeout(timeout);
			timeout = undefined;
		}

		const lastChange = contentChanges[contentChanges.length - 1];

		doAutoInsert(document, lastChange, async (document, position, lastChange) => {

			const params = {
				...htmlClient.code2ProtocolConverter.asTextDocumentPositionParams(document, position),
				options: {
					lastChange: {
						...lastChange,
						range: htmlClient.code2ProtocolConverter.asRange(lastChange.range),
					},
				},
			};

			const result = await htmlClient.sendRequest(shared.AutoInsertRequest.type, params)
				?? await tsClient.sendRequest(shared.AutoInsertRequest.type, params);

			if (typeof result === 'string') {
				return result;
			}
			else {
				return htmlClient.protocol2CodeConverter.asTextEdit(result);
			}
		});
	}

	function doAutoInsert(
		document: vscode.TextDocument,
		lastChange: vscode.TextDocumentContentChangeEvent,
		provider: (document: vscode.TextDocument, position: vscode.Position, lastChange: vscode.TextDocumentContentChangeEvent) => Thenable<string | vscode.TextEdit | null | undefined>,
	) {
		const rangeStart = lastChange.range.start;
		const version = document.version;
		timeout = setTimeout(() => {
			const position = new vscode.Position(rangeStart.line, rangeStart.character + lastChange.text.length);
			provider(document, position, lastChange).then(text => {
				if (text && isEnabled) {
					const activeEditor = vscode.window.activeTextEditor;
					if (activeEditor) {
						const activeDocument = activeEditor.document;
						if (document === activeDocument && activeDocument.version === version) {
							if (typeof text === 'string') {
								const selections = activeEditor.selections;
								if (selections.length && selections.some(s => s.active.isEqual(position))) {
									activeEditor.insertSnippet(new vscode.SnippetString(text), selections.map(s => s.active));
								} else {
									activeEditor.insertSnippet(new vscode.SnippetString(text), position);
								}
							}
							else {
								activeEditor.insertSnippet(new vscode.SnippetString(text.newText), text.range);
							}
						}
					}
				}
			});
			timeout = undefined;
		}, 100);
	}

	return vscode.Disposable.from(...disposables);
}
Example #13
Source File: tagNameCase.ts    From volar with MIT License 4 votes vote down vote up
export async function activate(context: vscode.ExtensionContext, languageClient: BaseLanguageClient) {

	const tagCases = shared.createPathMap<'both' | 'kebabCase' | 'pascalCase' | 'unsure'>();
	const statusBar = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right);
	statusBar.command = 'volar.action.tagNameCase';

	onChangeDocument(vscode.window.activeTextEditor?.document);

	const d_1 = vscode.window.onDidChangeActiveTextEditor(e => {
		onChangeDocument(e?.document);
	});
	const d_2 = vscode.workspace.onDidCloseTextDocument((doc) => {
		tagCases.uriDelete(doc.uri.toString());
	});
	const d_3 = vscode.commands.registerCommand('volar.action.tagNameCase', async () => {

		const crtDoc = vscode.window.activeTextEditor?.document;
		if (!crtDoc) return;

		const tagCase = tagCases.uriGet(crtDoc.uri.toString());
		const options: Record<string, vscode.QuickPickItem> = {};

		options[0] = { label: (tagCase === 'both' ? '• ' : '') + 'Component Using kebab-case and PascalCase (Both)' };
		options[1] = { label: (tagCase === 'kebabCase' ? '• ' : '') + 'Component Using kebab-case' };
		options[2] = { label: (tagCase === 'pascalCase' ? '• ' : '') + 'Component Using PascalCase' };
		options[3] = { label: 'Detect Component name from Content' };
		options[7] = { label: 'Convert Component name to kebab-case' };
		options[8] = { label: 'Convert Component name to PascalCase' };

		const select = await userPick(options);
		if (select === undefined)
			return; // cancel

		if (select === '0') {
			tagCases.uriSet(crtDoc.uri.toString(), 'both');
			updateStatusBarText('both');
		}
		if (select === '1') {
			tagCases.uriSet(crtDoc.uri.toString(), 'kebabCase');
			updateStatusBarText('kebabCase');
		}
		if (select === '2') {
			tagCases.uriSet(crtDoc.uri.toString(), 'pascalCase');
			updateStatusBarText('pascalCase');
		}
		if (select === '3') {
			const detects = await languageClient.sendRequest(shared.DetectDocumentNameCasesRequest.type, languageClient.code2ProtocolConverter.asTextDocumentIdentifier(crtDoc));
			if (detects) {
				tagCases.uriSet(crtDoc.uri.toString(), detects.tag);
				updateStatusBarText(detects.tag);
			}
		}
		if (select === '7') {
			vscode.commands.executeCommand('volar.action.tagNameCase.convertToKebabCase');
		}
		if (select === '8') {
			vscode.commands.executeCommand('volar.action.tagNameCase.convertToPascalCase');
		}
	});
	const d_4 = vscode.commands.registerCommand('volar.action.tagNameCase.convertToKebabCase', async () => {
		if (vscode.window.activeTextEditor) {
			await vscode.commands.executeCommand('volar.server.convertTagNameCasing', vscode.window.activeTextEditor.document.uri.toString(), 'kebab');
			tagCases.uriSet(vscode.window.activeTextEditor.document.uri.toString(), 'kebabCase');
			updateStatusBarText('kebabCase');
		}
	});
	const d_5 = vscode.commands.registerCommand('volar.action.tagNameCase.convertToPascalCase', async () => {
		if (vscode.window.activeTextEditor) {
			await vscode.commands.executeCommand('volar.server.convertTagNameCasing', vscode.window.activeTextEditor.document.uri.toString(), 'pascal');
			tagCases.uriSet(vscode.window.activeTextEditor.document.uri.toString(), 'pascalCase');
			updateStatusBarText('pascalCase');
		}
	});

	languageClient.onDidChangeState(e => {
		if (e.newState === State.Stopped) {
			d_1.dispose();
			d_2.dispose();
			d_3.dispose();
			d_4.dispose();
			d_5.dispose();
			statusBar.dispose();
		}
	});

	return (uri: string) => {
		let tagCase = tagCases.uriGet(uri);
		if (uri.toLowerCase() === vscode.window.activeTextEditor?.document.uri.toString().toLowerCase()) {
			updateStatusBarText(tagCase);
		}
		return !tagCase || tagCase === 'unsure' ? 'both' : tagCase;
	};

	async function onChangeDocument(newDoc: vscode.TextDocument | undefined) {
		if (newDoc?.languageId === 'vue') {
			let tagCase = tagCases.uriGet(newDoc.uri.toString());
			if (!tagCase) {
				const tagMode = vscode.workspace.getConfiguration('volar').get<'auto' | 'both' | 'kebab' | 'pascal'>('completion.preferredTagNameCase');
				if (tagMode === 'both') {
					tagCase = 'both';
				}
				else if (tagMode === 'kebab') {
					tagCase = 'kebabCase';
				}
				else if (tagMode === 'pascal') {
					tagCase = 'pascalCase';
				}
				else {
					const templateCases = await languageClient.sendRequest(shared.DetectDocumentNameCasesRequest.type, languageClient.code2ProtocolConverter.asTextDocumentIdentifier(newDoc));
					tagCase = templateCases?.tag;
				}
			}
			if (tagCase) {
				tagCases.uriSet(newDoc.uri.toString(), tagCase);
			}
			updateStatusBarText(tagCase);
			statusBar.show();
		}
		else {
			statusBar.hide();
		}
	}
	function updateStatusBarText(tagCase: 'both' | 'kebabCase' | 'pascalCase' | 'unsure' | undefined) {
		let text = `Tag: `;
		if (tagCase === 'unsure' || tagCase === undefined) {
			text += `UNSURE`;
		}
		else if (tagCase === 'both') {
			text += `BOTH`;
		}
		else if (tagCase === 'kebabCase') {
			text += `kebab-case`;
		}
		else if (tagCase === 'pascalCase') {
			text += `PascalCase`;
		}
		statusBar.text = text;
	}
}
Example #14
Source File: tsVersion.ts    From volar with MIT License 4 votes vote down vote up
export async function activate(context: vscode.ExtensionContext, clients: BaseLanguageClient[]) {

	const statusBar = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right);
	statusBar.command = 'volar.selectTypeScriptVersion';

	const subscription = vscode.commands.registerCommand('volar.selectTypeScriptVersion', async () => {

		const useWorkspaceTsdk = getCurrentTsPaths(context).isWorkspacePath;
		const workspaceTsPaths = getWorkspaceTsPaths();
		const workspaceTsVersion = workspaceTsPaths ? shared.getTypeScriptVersion(workspaceTsPaths.serverPath) : undefined;
		const vscodeTsPaths = getVscodeTsPaths();
		const vscodeTsVersion = shared.getTypeScriptVersion(vscodeTsPaths.serverPath);
		const tsdk = getTsdk();
		const defaultTsServer = shared.getWorkspaceTypescriptPath(defaultTsdk, (vscode.workspace.workspaceFolders ?? []).map(folder => folder.uri.fsPath));
		const defaultTsVersion = defaultTsServer ? shared.getTypeScriptVersion(defaultTsServer) : undefined;

		const options: Record<string, vscode.QuickPickItem> = {};
		options[0] = {
			label: (!useWorkspaceTsdk ? '• ' : '') + "Use VS Code's Version",
			description: vscodeTsVersion,
		};
		if (tsdk) {
			options[1] = {
				label: (useWorkspaceTsdk ? '• ' : '') + 'Use Workspace Version',
				description: workspaceTsVersion ?? 'Could not load the TypeScript version at this path',
				detail: tsdk,
			};
		}
		if (tsdk !== defaultTsdk) {
			options[2] = {
				label: (useWorkspaceTsdk ? '• ' : '') + 'Use Workspace Version',
				description: defaultTsVersion ?? 'Could not load the TypeScript version at this path',
				detail: defaultTsdk,
			};
		}
		if (takeOverModeEnabled()) {
			options[3] = {
				label: 'What is Takeover Mode?',
			};
		}

		const select = await userPick(options);
		if (select === undefined)
			return; // cancel

		if (select === '3') {
			vscode.env.openExternal(vscode.Uri.parse('https://vuejs.org/guide/typescript/overview.html#takeover-mode'));
			return;
		}

		if (select === '2') {
			vscode.workspace.getConfiguration('typescript').update('tsdk', defaultTsdk);
		}

		const nowUseWorkspaceTsdk = select !== '0';
		if (nowUseWorkspaceTsdk !== isUseWorkspaceTsdk(context)) {
			context.workspaceState.update('typescript.useWorkspaceTsdk', nowUseWorkspaceTsdk);
			reloadServers();
		}

		updateStatusBar();
	});
	context.subscriptions.push(subscription);

	let tsdk = getTsdk();
	vscode.workspace.onDidChangeConfiguration(() => {
		const newTsdk = getTsdk();
		if (newTsdk !== tsdk) {
			tsdk = newTsdk;
			if (isUseWorkspaceTsdk(context)) {
				reloadServers();
			}
		}
	});

	updateStatusBar();
	vscode.window.onDidChangeActiveTextEditor(updateStatusBar, undefined, context.subscriptions);

	function updateStatusBar() {
		if (
			vscode.window.activeTextEditor?.document.languageId !== 'vue'
			&& !(
				takeOverModeEnabled()
				&& vscode.window.activeTextEditor
				&& ['javascript', 'typescript', 'javascriptreact', 'typescriptreact'].includes(vscode.window.activeTextEditor.document.languageId)
			)
		) {
			statusBar.hide();
		}
		else {
			const tsPaths = getCurrentTsPaths(context);
			const tsVersion = shared.getTypeScriptVersion(tsPaths.serverPath);
			statusBar.text = 'TS ' + tsVersion;
			if (takeOverModeEnabled()) {
				statusBar.text += ' (takeover)';
			}
			statusBar.show();
		}
	}
	async function reloadServers() {
		const tsPaths = getCurrentTsPaths(context);
		for (const client of clients) {
			const newInitOptions: shared.ServerInitializationOptions = {
				...client.clientOptions.initializationOptions,
				typescript: tsPaths,
			};
			client.clientOptions.initializationOptions = newInitOptions;
		}
		vscode.commands.executeCommand('volar.action.restartServer');
	}
}