diff --git a/client/package-lock.json b/client/package-lock.json index 812e7fc..5b5034a 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -9,10 +9,12 @@ "version": "1.0.0", "license": "MIT", "dependencies": { - "vscode-languageclient": "^8.0.2" + "vscode-languageclient": "^8.0.2", + "which": "^3.0.0" }, "devDependencies": { - "@types/vscode": "^1.68.0" + "@types/vscode": "^1.68.0", + "@types/which": "^2.0.1" }, "engines": { "vscode": "^1.68.0" @@ -24,6 +26,12 @@ "integrity": "sha512-WvHluhUo+lQvE3I4wUagRpnkHuysB4qSyOQUyIAS9n9PYMJjepzTUD8Jyks0YeXoPD0UGctjqp2u84/b3v6Ydw==", "dev": true }, + "node_modules/@types/which": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/which/-/which-2.0.1.tgz", + "integrity": "sha512-Jjakcv8Roqtio6w1gr0D7y6twbhx6gGgFGF5BLwajPpnOIOxFkakFhCq+LmyyeAz7BX6ULrjBOxdKaCDy+4+dQ==", + "dev": true + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -43,6 +51,11 @@ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + }, "node_modules/lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", @@ -114,6 +127,20 @@ "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.2.tgz", "integrity": "sha512-zHhCWatviizPIq9B7Vh9uvrH6x3sK8itC84HkamnBWoDFJtzBf7SWlpLCZUit72b3os45h6RWQNC9xHRDF8dRA==" }, + "node_modules/which": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-3.0.0.tgz", + "integrity": "sha512-nla//68K9NU6yRiwDY/Q8aU6siKlSs64aEC7+IV56QoAuyQT2ovsJcgGYGyqMOmI/CGN1BOR6mM5EN0FBO+zyQ==", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, "node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", @@ -127,6 +154,12 @@ "integrity": "sha512-WvHluhUo+lQvE3I4wUagRpnkHuysB4qSyOQUyIAS9n9PYMJjepzTUD8Jyks0YeXoPD0UGctjqp2u84/b3v6Ydw==", "dev": true }, + "@types/which": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/which/-/which-2.0.1.tgz", + "integrity": "sha512-Jjakcv8Roqtio6w1gr0D7y6twbhx6gGgFGF5BLwajPpnOIOxFkakFhCq+LmyyeAz7BX6ULrjBOxdKaCDy+4+dQ==", + "dev": true + }, "balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -146,6 +179,11 @@ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + }, "lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", @@ -199,6 +237,14 @@ "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.2.tgz", "integrity": "sha512-zHhCWatviizPIq9B7Vh9uvrH6x3sK8itC84HkamnBWoDFJtzBf7SWlpLCZUit72b3os45h6RWQNC9xHRDF8dRA==" }, + "which": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-3.0.0.tgz", + "integrity": "sha512-nla//68K9NU6yRiwDY/Q8aU6siKlSs64aEC7+IV56QoAuyQT2ovsJcgGYGyqMOmI/CGN1BOR6mM5EN0FBO+zyQ==", + "requires": { + "isexe": "^2.0.0" + } + }, "yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", diff --git a/client/package.json b/client/package.json index 0d06411..1185b01 100644 --- a/client/package.json +++ b/client/package.json @@ -13,9 +13,11 @@ "url": "https://gitee.com/openkylin/cmake-intellisence" }, "dependencies": { - "vscode-languageclient": "^8.0.2" + "vscode-languageclient": "^8.0.2", + "which": "^3.0.0" }, "devDependencies": { - "@types/vscode": "^1.68.0" + "@types/vscode": "^1.68.0", + "@types/which": "^2.0.1" } } diff --git a/client/src/extension.ts b/client/src/extension.ts index f27da30..f3de448 100644 --- a/client/src/extension.ts +++ b/client/src/extension.ts @@ -8,8 +8,8 @@ import { TransportKind } from 'vscode-languageclient/node'; import { existsSync } from 'fs'; -import { isAbsolute } from 'path'; -import { which } from './utils'; +import { stat } from 'node:fs/promises'; +import * as which from 'which'; export const SERVER_ID = 'cmakeIntelliSence'; @@ -17,41 +17,59 @@ export const SERVER_NAME = 'CMake Language Server'; let client: LanguageClient; -async function checkCMakePath(cmakePath: string) { - if (!existsSync(cmakePath)) { - if (which(cmakePath) === null) { - let select = await window.showErrorMessage(`Can not find cmakePath: ${cmakePath}`, - 'Open Settings', 'Ignore'); - if (select === 'Open Settings') { - commands.executeCommand('workbench.action.openSettings', 'cmakeIntelliSence.cmakePath'); - } +async function checkCMakeExecutable(cmakePath: string) : Promise { + try { + await stat(cmakePath); + } catch (error) { + try { + await which(cmakePath); + } catch (error) { + return false; } } + return true; } export async function activate(context: ExtensionContext) { const config = workspace.getConfiguration(SERVER_ID); const logger = new Logger(); logger.setLogLevel(getConfigLogLevel(config)); - checkCMakePath(config.cmakePath); - context.subscriptions.push(workspace.onDidChangeConfiguration((e) => { + const serverModule = context.asAbsolutePath( + path.join('dist', 'server.js') + ); + + async function checkAndStart(cmakePath: string) { + if (await checkCMakeExecutable(cmakePath)) { + startLanguageServer(serverModule, logger); + } else { + let select = await window.showErrorMessage(`Can not find cmake: ${cmakePath}, please set cmakePath, otherwise only syntax highlight is enabled`, + 'Open Settings', 'Ignore'); + if (select === 'Open Settings') { + commands.executeCommand('workbench.action.openSettings', 'cmakeIntelliSence.cmakePath'); + } + } + } + + checkAndStart(config.cmakePath); + + context.subscriptions.push(workspace.onDidChangeConfiguration(async (e) => { if (e.affectsConfiguration(`${SERVER_ID}.loggingLevel`)) { logger.setLogLevel(getConfigLogLevel(config)); } if (e.affectsConfiguration(`${SERVER_ID}.cmakePath`)) { const cmakePath = workspace.getConfiguration(SERVER_ID).get('cmakePath'); - checkCMakePath(cmakePath); + if (! client?.isRunning()) { + checkAndStart(cmakePath); + } } })); +} - const serverModule = context.asAbsolutePath( - path.join('dist', 'server.js') - ); - +function startLanguageServer(serverModule: string, logger: Logger) { // The debug options for the server - // --inspect=6009: runs the server in Node's Inspector mode so VS Code can attach to the server for debugging + // --inspect=6009: runs the server in Node's Inspector mode so VS Code can attach to the server for debugging const debugOptions = { execArgv: ['--nolazy', '--inspect=6009'] }; // If the extension is lanched in debug mode then the debug server options are used @@ -77,7 +95,7 @@ export async function activate(context: ExtensionContext) { outputChannel: logger.getOutputChannel() }; - + client = new LanguageClient(SERVER_ID, SERVER_NAME, serverOptions, clientOptions); // start the client. This will also launch the server