function realActivate()

in client/src/extension.ts [802:1493]


function realActivate(context: ExtensionContext): void {

	const statusBarItem = Window.createStatusBarItem('generalStatus', StatusBarAlignment.Right, 0);
	let serverRunning: boolean | undefined;

	const starting = 'ESLint server is starting.';
	const running = 'ESLint server is running.';
	const stopped = 'ESLint server stopped.';
	statusBarItem.name = 'ESLint';
	statusBarItem.text = 'ESLint';
	statusBarItem.command = 'eslint.showOutputChannel';

	const documentStatus: Map<string, Status> = new Map();

	function updateDocumentStatus(params: StatusParams): void {
		documentStatus.set(params.uri, params.state);
		updateStatusBar(params.uri);
	}

	function updateStatusBar(uri: string | undefined) {
		const status = function() {
			if (serverRunning === false) {
				return Status.error;
			}
			if (uri === undefined) {
				uri = Window.activeTextEditor?.document.uri.toString();
			}
			return (uri !== undefined ? documentStatus.get(uri) : undefined) ?? Status.ok;
		}();
		let icon: string| undefined;
		let tooltip: string | undefined;
		let text: string = 'ESLint';
		let backgroundColor: ThemeColor | undefined;
		let foregroundColor: ThemeColor | undefined;
		switch (status) {
			case Status.ok:
				icon = undefined;
				foregroundColor = new ThemeColor('statusBarItem.foreground');
				backgroundColor = new ThemeColor('statusBarItem.background');
				break;
			case Status.warn:
				icon = '$(alert)';
				foregroundColor = new ThemeColor('statusBarItem.warningForeground');
				backgroundColor = new ThemeColor('statusBarItem.warningBackground');
				break;
			case Status.error:
				icon = '$(issue-opened)';
				foregroundColor = new ThemeColor('statusBarItem.errorForeground');
				backgroundColor = new ThemeColor('statusBarItem.errorBackground');
				break;
		}
		statusBarItem.text = icon !== undefined ? `${icon} ${text}` : text;
		statusBarItem.color = foregroundColor;
		statusBarItem.backgroundColor = backgroundColor;
		statusBarItem.tooltip = tooltip ? tooltip : serverRunning === undefined ? starting : serverRunning === true ? running : stopped;
		const alwaysShow = Workspace.getConfiguration('eslint').get('alwaysShowStatus', false);
		if (alwaysShow || status !== Status.ok) {
			statusBarItem.show();
		} else {
			statusBarItem.hide();
		}
	}

	function readCodeActionsOnSaveSetting(document: TextDocument): boolean {
		let result: boolean | undefined = undefined;
		const languageConfig = Workspace.getConfiguration(undefined, document.uri).get<LanguageSettings>(`[${document.languageId}]`);

		function isEnabled(value: CodeActionsOnSave | string[]): boolean | undefined {
			if (value === undefined || value === null) {
				return undefined;
			}
			if (Array.isArray(value)) {
				const result = value.some((element) => { return element === 'source.fixAll.eslint' || element === 'source.fixAll'; });
				return result === true ? true : undefined;
			} else {
				return value['source.fixAll.eslint'] ?? value['source.fixAll'];
			}
		}

		if (languageConfig !== undefined) {
			const codeActionsOnSave = languageConfig?.['editor.codeActionsOnSave'];
			if (codeActionsOnSave !== undefined) {
				result = isEnabled(codeActionsOnSave);
			}
		}
		if (result === undefined) {
			const codeActionsOnSave = Workspace.getConfiguration('editor', document.uri).get<CodeActionsOnSave>('codeActionsOnSave');
			if (codeActionsOnSave !== undefined) {
				result = isEnabled(codeActionsOnSave);
			}
		}
		return result ?? false;
	}

	function migrationFailed(error: any): void {
		client.error(error.message ?? 'Unknown error', error);
		void Window.showErrorMessage('ESLint settings migration failed. Please see the ESLint output channel for further details', 'Open Channel').then((selected) => {
			if (selected === undefined) {
				return;
			}
			client.outputChannel.show();
		});

	}

	async function migrateSettings(): Promise<void> {
		const folders = Workspace.workspaceFolders;
		if (folders === undefined) {
			void Window.showErrorMessage('ESLint settings can only be converted if VS Code is opened on a workspace folder.');
			return;
		}

		const folder = await pickFolder(folders, 'Pick a folder to convert its settings');
		if (folder === undefined) {
			return;
		}
		const migration = new Migration(folder.uri);
		migration.record();
		if (migration.needsUpdate()) {
			try {
				await migration.update();
			} catch (error) {
				migrationFailed(error);
			}
		}
	}

	function sanitize<T, D>(value: T, type: 'bigint' | 'boolean' | 'function' | 'number' | 'object' | 'string' | 'symbol' | 'undefined', def: D): T | D {
		if (Array.isArray(value)) {
			return value.filter(item => typeof item === type) as unknown as T;
		} else if (typeof value !== type) {
			return def;
		}
		return value;
	}

	const serverModule = Uri.joinPath(context.extensionUri, 'server', 'out', 'eslintServer.js').fsPath;
	const eslintConfig = Workspace.getConfiguration('eslint');
	const debug = sanitize(eslintConfig.get<boolean>('debug', false) ?? false, 'boolean', false);
	const runtime = sanitize(eslintConfig.get<string | null>('runtime', null) ?? undefined, 'string', undefined);
	const execArgv = sanitize(eslintConfig.get<string[] | null>('execArgv', null) ?? undefined, 'string', undefined);
	const nodeEnv = sanitize(eslintConfig.get('nodeEnv', null) ?? undefined, 'string', undefined);

	let env: { [key: string]: string | number | boolean } | undefined;
	if (debug) {
		env = env || {};
		env.DEBUG = 'eslint:*,-eslint:code-path';
	}
	if (nodeEnv !== undefined) {
		env = env || {};
		env.NODE_ENV = nodeEnv;
	}
	const debugArgv = ['--nolazy', '--inspect=6011'];
	const serverOptions: ServerOptions = {
		run: { module: serverModule, transport: TransportKind.ipc, runtime, options: { execArgv, cwd: process.cwd(), env } },
		debug: { module: serverModule, transport: TransportKind.ipc, runtime, options: { execArgv: execArgv !== undefined ? execArgv.concat(debugArgv) : debugArgv, cwd: process.cwd(), env } }
	};

	let defaultErrorHandler: ErrorHandler;
	let serverCalledProcessExit: boolean = false;

	const packageJsonFilter: DocumentFilter = { scheme: 'file', pattern: '**/package.json' };
	const configFileFilter: DocumentFilter = { scheme: 'file', pattern: '**/.eslintr{c.js,c.yaml,c.yml,c,c.json}' };
	const syncedDocuments: Map<string, TextDocument> = new Map<string, TextDocument>();

	let migration: Migration | undefined;
	const migrationSemaphore: Semaphore<void> = new Semaphore<void>(1);
	let notNow: boolean = false;
	const supportedQuickFixKinds: Set<string> = new Set([CodeActionKind.Source.value, CodeActionKind.SourceFixAll.value, `${CodeActionKind.SourceFixAll.value}.eslint`, CodeActionKind.QuickFix.value]);
	const clientOptions: LanguageClientOptions = {
		documentSelector: [{ scheme: 'file' }, { scheme: 'untitled' }],
		diagnosticCollectionName: 'eslint',
		revealOutputChannelOn: RevealOutputChannelOn.Never,
		initializationOptions: {
		},
		progressOnInitialization: true,
		synchronize: {
			// configurationSection: 'eslint',
			fileEvents: [
				Workspace.createFileSystemWatcher('**/.eslintr{c.js,c.yaml,c.yml,c,c.json}'),
				Workspace.createFileSystemWatcher('**/.eslintignore'),
				Workspace.createFileSystemWatcher('**/package.json')
			]
		},
		initializationFailedHandler: (error) => {
			client.error('Server initialization failed.', error);
			client.outputChannel.show(true);
			return false;
		},
		errorHandler: {
			error: (error, message, count): ErrorHandlerResult => {
				return defaultErrorHandler.error(error, message, count);
			},
			closed: (): CloseHandlerResult => {
				if (serverCalledProcessExit) {
					return { action: CloseAction.DoNotRestart };
				}
				return defaultErrorHandler.closed();
			}
		},
		middleware: {
			didOpen: async (document, next) => {
				if (Languages.match(packageJsonFilter, document) || Languages.match(configFileFilter, document) || computeValidate(document) !== Validate.off) {
					const result = next(document);
					syncedDocuments.set(document.uri.toString(), document);
					return result;
				}
			},
			didChange: async (event, next) => {
				if (syncedDocuments.has(event.document.uri.toString())) {
					return next(event);
				}
			},
			willSave: async (event, next) => {
				if (syncedDocuments.has(event.document.uri.toString())) {
					return next(event);
				}
			},
			willSaveWaitUntil: (event, next) => {
				if (syncedDocuments.has(event.document.uri.toString())) {
					return next(event);
				} else {
					return Promise.resolve([]);
				}
			},
			didSave: async (document, next) => {
				if (syncedDocuments.has(document.uri.toString())) {
					return next(document);
				}
			},
			didClose: async (document, next) => {
				const uri = document.uri.toString();
				if (syncedDocuments.has(uri)) {
					syncedDocuments.delete(uri);
					return next(document);
				}
			},
			provideCodeActions: (document, range, context, token, next): ProviderResult<(Command | CodeAction)[]> => {
				if (!syncedDocuments.has(document.uri.toString())) {
					return [];
				}
				if (context.only !== undefined && !supportedQuickFixKinds.has(context.only.value)) {
					return [];
				}
				if (context.only === undefined && (!context.diagnostics || context.diagnostics.length === 0)) {
					return [];
				}
				const eslintDiagnostics: Diagnostic[] = [];
				for (const diagnostic of context.diagnostics) {
					if (diagnostic.source === 'eslint') {
						eslintDiagnostics.push(diagnostic);
					}
				}
				if (context.only === undefined && eslintDiagnostics.length === 0) {
					return [];
				}
				const newContext: CodeActionContext = Object.assign({}, context, { diagnostics: eslintDiagnostics });
				return next(document, range, newContext, token);
			},
			workspace: {
				didChangeWatchedFile: (event, next) => {
					probeFailed.clear();
					return next(event);
				},
				didChangeConfiguration: async (sections, next) => {
					if (migration !== undefined && (sections === undefined || sections.length === 0)) {
						migration.captureDidChangeSetting(() => {
							return next(sections);
						});
					} else {
						return next(sections);
					}
				},
				configuration: async (params, _token, _next): Promise<any[]> => {
					if (params.items === undefined) {
						return [];
					}
					const result: (ConfigurationSettings | null)[] = [];
					for (const item of params.items) {
						if (item.section || !item.scopeUri) {
							result.push(null);
							continue;
						}
						const resource = client.protocol2CodeConverter.asUri(item.scopeUri);
						const config = Workspace.getConfiguration('eslint', resource);
						const workspaceFolder = resource.scheme === 'untitled'
							? Workspace.workspaceFolders !== undefined ? Workspace.workspaceFolders[0] : undefined
							: Workspace.getWorkspaceFolder(resource);
						await migrationSemaphore.lock(async () => {
							const globalMigration = Workspace.getConfiguration('eslint').get('migration.2_x', 'on');
							if (notNow === false && globalMigration === 'on') {
								try {
									migration = new Migration(resource);
									migration.record();
									interface Item extends MessageItem {
										id: 'yes' | 'no' | 'readme' | 'global' | 'local';
									}
									if (migration.needsUpdate()) {
										const folder = workspaceFolder?.name;
										const file = path.basename(resource.fsPath);
										const selected = await Window.showInformationMessage<Item>(
											[
												`The ESLint 'autoFixOnSave' setting needs to be migrated to the new 'editor.codeActionsOnSave' setting`,
												folder !== undefined ? `for the workspace folder: ${folder}.` : `for the file: ${file}.`,
												`For compatibility reasons the 'autoFixOnSave' remains and needs to be removed manually.`,
												`Do you want to migrate the setting?`
											].join(' '),
											{ modal: true},
											{ id: 'yes', title: 'Yes'},
											{ id: 'global', title: 'Never migrate Settings' },
											{ id: 'readme', title: 'Open Readme' },
											{ id: 'no', title: 'Not now', isCloseAffordance: true }
										);
										if (selected !== undefined) {
											if (selected.id === 'yes') {
												try {
													await migration.update();
												} catch (error) {
													migrationFailed(error);
												}
											} else if (selected.id === 'no') {
												notNow = true;
											} else if (selected.id === 'global') {
												await config.update('migration.2_x', 'off', ConfigurationTarget.Global);
											} else if (selected.id === 'readme') {
												notNow = true;
												void Env.openExternal(Uri.parse('https://github.com/microsoft/vscode-eslint#settings-migration'));
											}
										}
									}
								} finally {
									migration = undefined;
								}
							}
						});
						const settings: ConfigurationSettings = {
							validate: Validate.off,
							packageManager: config.get('packageManager', 'npm'),
							useESLintClass: config.get('useESLintClass', false),
							codeActionOnSave: {
								enable: false,
								mode: CodeActionsOnSaveMode.all
							},
							format: false,
							quiet: config.get('quiet', false),
							onIgnoredFiles: ESLintSeverity.from(config.get<string>('onIgnoredFiles', ESLintSeverity.off)),
							options: config.get('options', {}),
							rulesCustomizations: parseRulesCustomizations(config.get('rules.customizations')),
							run: config.get('run', 'onType'),
							nodePath: config.get<string | undefined>('nodePath', undefined) ?? null,
							workingDirectory: undefined,
							workspaceFolder: undefined,
							codeAction: {
								disableRuleComment: config.get('codeAction.disableRuleComment', { enable: true, location: 'separateLine' as 'separateLine' }),
								showDocumentation: config.get('codeAction.showDocumentation', { enable: true })
							}
						};
						const document: TextDocument | undefined = syncedDocuments.get(item.scopeUri);
						if (document === undefined) {
							result.push(settings);
							continue;
						}
						if (config.get('enabled', true)) {
							settings.validate = computeValidate(document);
						}
						if (settings.validate !== Validate.off) {
							settings.format = !!config.get('format.enable', false);
							settings.codeActionOnSave.enable = readCodeActionsOnSaveSetting(document);
							settings.codeActionOnSave.mode = CodeActionsOnSaveMode.from(config.get('codeActionsOnSave.mode', CodeActionsOnSaveMode.all));
							settings.codeActionOnSave.rules = CodeActionsOnSaveRules.from(config.get('codeActionsOnSave.rules', null));
						}
						if (workspaceFolder !== undefined) {
							settings.workspaceFolder = {
								name: workspaceFolder.name,
								uri: client.code2ProtocolConverter.asUri(workspaceFolder.uri)
							};
						}
						const workingDirectories = config.get<(string | LegacyDirectoryItem | DirectoryItem | PatternItem | ModeItem)[] | undefined>('workingDirectories', undefined);
						if (Array.isArray(workingDirectories)) {
							let workingDirectory: ModeItem | DirectoryItem | undefined = undefined;
							const workspaceFolderPath = workspaceFolder && workspaceFolder.uri.scheme === 'file' ? workspaceFolder.uri.fsPath : undefined;
							for (const entry of workingDirectories) {
								let directory: string | undefined;
								let pattern: string | undefined;
								let noCWD = false;
								if (Is.string(entry)) {
									directory = entry;
								} else if (LegacyDirectoryItem.is(entry)) {
									directory = entry.directory;
									noCWD = !entry.changeProcessCWD;
								} else if (DirectoryItem.is(entry)) {
									directory = entry.directory;
									if (entry['!cwd'] !== undefined) {
										noCWD = entry['!cwd'];
									}
								} else if (PatternItem.is(entry)) {
									pattern = entry.pattern;
									if (entry['!cwd'] !== undefined) {
										noCWD = entry['!cwd'];
									}
								} else if (ModeItem.is(entry)) {
									workingDirectory = entry;
									continue;
								}

								let itemValue: string | undefined;
								if (directory !== undefined || pattern !== undefined) {
									const filePath = document.uri.scheme === 'file' ? document.uri.fsPath : undefined;
									if (filePath !== undefined) {
										if (directory !== undefined) {
											directory = toOSPath(directory);
											if (!path.isAbsolute(directory) && workspaceFolderPath !== undefined) {
												directory = path.join(workspaceFolderPath, directory);
											}
											if (directory.charAt(directory.length - 1) !== path.sep) {
												directory = directory + path.sep;
											}
											if (filePath.startsWith(directory)) {
												itemValue = directory;
											}
										} else if (pattern !== undefined && pattern.length > 0) {
											if (!path.posix.isAbsolute(pattern) && workspaceFolderPath !== undefined) {
												pattern = path.posix.join(toPosixPath(workspaceFolderPath), pattern);
											}
											if (pattern.charAt(pattern.length - 1) !== path.posix.sep) {
												pattern = pattern + path.posix.sep;
											}
											const regExp: RegExp | undefined = convert2RegExp(pattern);
											if (regExp !== undefined) {
												const match = regExp.exec(filePath);
												if (match !== null && match.length > 0) {
													itemValue = match[0];
												}
											}
										}
									}
								}
								if (itemValue !== undefined) {
									if (workingDirectory === undefined || ModeItem.is(workingDirectory)) {
										workingDirectory = { directory: itemValue, '!cwd': noCWD };
									} else {
										if (workingDirectory.directory.length < itemValue.length) {
											workingDirectory.directory = itemValue;
											workingDirectory['!cwd'] = noCWD;
										}
									}
								}
							}
							settings.workingDirectory = workingDirectory;
						}
						result.push(settings);
					}
					return result;
				}
			}
		}
	};

	let client: LanguageClient;
	try {
		client = new LanguageClient('ESLint', serverOptions, clientOptions);
	} catch (err) {
		void Window.showErrorMessage(`The ESLint extension couldn't be started. See the ESLint output channel for details.`);
		return;
	}
	// Currently we don't need any proposed features.
	// client.registerProposedFeatures();

	Workspace.onDidChangeConfiguration(() => {
		probeFailed.clear();
		for (const textDocument of syncedDocuments.values()) {
			if (computeValidate(textDocument) === Validate.off) {
				try {
					const provider = client.getFeature(DidCloseTextDocumentNotification.method).getProvider(textDocument);
					provider?.send(textDocument);
				} catch (err) {
					// A feature currently throws if no provider can be found. So for now we catch the exception.
				}
			}
		}
		for (const textDocument of Workspace.textDocuments) {
			if (!syncedDocuments.has(textDocument.uri.toString()) && computeValidate(textDocument) !== Validate.off) {
				try {
					const provider = client.getFeature(DidOpenTextDocumentNotification.method).getProvider(textDocument);
					provider?.send(textDocument);
				} catch (err) {
					// A feature currently throws if no provider can be found. So for now we catch the exception.
				}
			}
		}
	});

	defaultErrorHandler = client.createDefaultErrorHandler();
	client.onDidChangeState((event) => {
		if (event.newState === ClientState.Starting) {
			client.info('ESLint server is starting');
			serverRunning = undefined;
		} else if (event.newState === ClientState.Running) {
			client.info(running);
			serverRunning = true;
		} else {
			client.info(stopped);
			serverRunning = false;
		}
		updateStatusBar(undefined);
	});

	const readyHandler = () => {
		client.onNotification(ShowOutputChannel.type, () => {
			client.outputChannel.show();
		});

		client.onNotification(StatusNotification.type, (params) => {
			updateDocumentStatus(params);
		});

		client.onNotification(exitCalled, (params) => {
			serverCalledProcessExit = true;
			client.error(`Server process exited with code ${params[0]}. This usually indicates a misconfigured ESLint setup.`, params[1]);
			void Window.showErrorMessage(`ESLint server shut down itself. See 'ESLint' output channel for details.`, { title: 'Open Output', id: 1}).then((value) => {
				if (value !== undefined && value.id === 1) {
					client.outputChannel.show();
				}
			});
		});

		client.onRequest(NoConfigRequest.type, (params) => {
			const document = Uri.parse(params.document.uri);
			const workspaceFolder = Workspace.getWorkspaceFolder(document);
			const fileLocation = document.fsPath;
			if (workspaceFolder) {
				client.warn([
					'',
					`No ESLint configuration (e.g .eslintrc) found for file: ${fileLocation}`,
					`File will not be validated. Consider running 'eslint --init' in the workspace folder ${workspaceFolder.name}`,
					`Alternatively you can disable ESLint by executing the 'Disable ESLint' command.`
				].join('\n'));
			} else {
				client.warn([
					'',
					`No ESLint configuration (e.g .eslintrc) found for file: ${fileLocation}`,
					`File will not be validated. Alternatively you can disable ESLint by executing the 'Disable ESLint' command.`
				].join('\n'));
			}

			updateDocumentStatus({ uri: params.document.uri, state: Status.error });
			return {};
		});

		client.onRequest(NoESLintLibraryRequest.type, (params) => {
			const key = 'noESLintMessageShown';
			const state = context.globalState.get<NoESLintState>(key, {});

			const uri: Uri = Uri.parse(params.source.uri);
			const workspaceFolder = Workspace.getWorkspaceFolder(uri);
			const packageManager = Workspace.getConfiguration('eslint', uri).get('packageManager', 'npm');
			const localInstall = {
				npm: 'npm install eslint',
				pnpm: 'pnpm install eslint',
				yarn: 'yarn add eslint',
			};
			const globalInstall = {
				npm: 'npm install -g eslint',
				pnpm: 'pnpm install -g eslint',
				yarn: 'yarn global add eslint'
			};
			const isPackageManagerNpm = packageManager === 'npm';
			interface ButtonItem extends MessageItem {
				id: number;
			}
			const outputItem: ButtonItem = {
				title: 'Go to output',
				id: 1
			};
			if (workspaceFolder) {
				client.info([
					'',
					`Failed to load the ESLint library for the document ${uri.fsPath}`,
					'',
					`To use ESLint please install eslint by running ${localInstall[packageManager]} in the workspace folder ${workspaceFolder.name}`,
					`or globally using '${globalInstall[packageManager]}'. You need to reopen the workspace after installing eslint.`,
					'',
					isPackageManagerNpm ? 'If you are using yarn or pnpm instead of npm set the setting `eslint.packageManager` to either `yarn` or `pnpm`' : null,
					`Alternatively you can disable ESLint for the workspace folder ${workspaceFolder.name} by executing the 'Disable ESLint' command.`
				].filter((str => (str !== null))).join('\n'));

				if (state.workspaces === undefined) {
					state.workspaces = {};
				}
				if (!state.workspaces[workspaceFolder.uri.toString()]) {
					state.workspaces[workspaceFolder.uri.toString()] = true;
					void context.globalState.update(key, state);
					void Window.showInformationMessage(`Failed to load the ESLint library for the document ${uri.fsPath}. See the output for more information.`, outputItem).then((item) => {
						if (item && item.id === 1) {
							client.outputChannel.show(true);
						}
					});
				}
			} else {
				client.info([
					`Failed to load the ESLint library for the document ${uri.fsPath}`,
					`To use ESLint for single JavaScript file install eslint globally using '${globalInstall[packageManager]}'.`,
					isPackageManagerNpm ? 'If you are using yarn or pnpm instead of npm set the setting `eslint.packageManager` to either `yarn` or `pnpm`' : null,
					'You need to reopen VS Code after installing eslint.',
				].filter((str => (str !== null))).join('\n'));

				if (!state.global) {
					state.global = true;
					void context.globalState.update(key, state);
					void Window.showInformationMessage(`Failed to load the ESLint library for the document ${uri.fsPath}. See the output for more information.`, outputItem).then((item) => {
						if (item && item.id === 1) {
							client.outputChannel.show(true);
						}
					});
				}
			}
			return {};
		});

		client.onRequest(OpenESLintDocRequest.type, async (params) => {
			await Commands.executeCommand('vscode.open', Uri.parse(params.url));
			return {};
		});

		client.onRequest(ProbeFailedRequest.type, (params) => {
			probeFailed.add(params.textDocument.uri);
			const closeFeature = client.getFeature(DidCloseTextDocumentNotification.method);
			for (const document of Workspace.textDocuments) {
				if (document.uri.toString() === params.textDocument.uri) {
					closeFeature.getProvider(document)?.send(document);
				}
			}
		});
	};

	client.onReady().then(readyHandler).catch((error) => client.error(`On ready failed`, error));

	if (onActivateCommands) {
		onActivateCommands.forEach(command => command.dispose());
		onActivateCommands = undefined;
	}

	context.subscriptions.push(
		client.start(),
		Window.onDidChangeActiveTextEditor(() => {
			updateStatusBar(undefined);
		}),
		Workspace.onDidCloseTextDocument((document) => {
			const uri = document.uri.toString();
			documentStatus.delete(uri);
			updateStatusBar(undefined);
		}),
		Commands.registerCommand('eslint.executeAutofix', async () => {
			const textEditor = Window.activeTextEditor;
			if (!textEditor) {
				return;
			}
			const textDocument: VersionedTextDocumentIdentifier = {
				uri: textEditor.document.uri.toString(),
				version: textEditor.document.version
			};
			const params: ExecuteCommandParams = {
				command: 'eslint.applyAllFixes',
				arguments: [textDocument]
			};
			await client.onReady();
			client.sendRequest(ExecuteCommandRequest.type, params).then(undefined, () => {
				void Window.showErrorMessage('Failed to apply ESLint fixes to the document. Please consider opening an issue with steps to reproduce.');
			});
		}),
		Commands.registerCommand('eslint.showOutputChannel', async () => {
			client.outputChannel.show();
		}),
		Commands.registerCommand('eslint.migrateSettings', () => {
			void migrateSettings();
		}),
		Commands.registerCommand('eslint.restart', async () => {
			await client.stop();
			// Wait a little to free debugger port. Can not happen in production
			// So we should add a dev flag.
			const start = () => {
				client.start();
				client.onReady().then(readyHandler).catch((error) => client.error(`On ready failed`, error));
			};
			if (isInDebugMode()) {
				setTimeout(start, 1000);
			} else {
				start();
			}
		})
	);
}