diff --git a/language-server/out/eslintServer.js b/language-server/out/eslintServer.js index 4818842..93cca54 100644 --- a/language-server/out/eslintServer.js +++ b/language-server/out/eslintServer.js @@ -43,6 +43,9 @@ var Status; Status[Status["ok"] = 1] = "ok"; Status[Status["warn"] = 2] = "warn"; Status[Status["error"] = 3] = "error"; + Status[Status["confirmationPending"] = 4] = "confirmationPending"; + Status[Status["confirmationCanceled"] = 5] = "confirmationCanceled"; + Status[Status["executionDenied"] = 6] = "executionDenied"; })(Status || (Status = {})); var StatusNotification; (function (StatusNotification) { @@ -64,6 +67,36 @@ var ProbeFailedRequest; (function (ProbeFailedRequest) { ProbeFailedRequest.type = new node_1.RequestType('eslint/probeFailed'); })(ProbeFailedRequest || (ProbeFailedRequest = {})); +var ConfirmExecutionResult; +(function (ConfirmExecutionResult) { + ConfirmExecutionResult[ConfirmExecutionResult["deny"] = 1] = "deny"; + ConfirmExecutionResult[ConfirmExecutionResult["confirmationPending"] = 2] = "confirmationPending"; + ConfirmExecutionResult[ConfirmExecutionResult["confirmationCanceled"] = 3] = "confirmationCanceled"; + ConfirmExecutionResult[ConfirmExecutionResult["approved"] = 4] = "approved"; +})(ConfirmExecutionResult || (ConfirmExecutionResult = {})); +(function (ConfirmExecutionResult) { + function toStatus(value) { + switch (value) { + case ConfirmExecutionResult.deny: + return Status.executionDenied; + case ConfirmExecutionResult.confirmationPending: + return Status.confirmationPending; + case ConfirmExecutionResult.confirmationCanceled: + return Status.confirmationCanceled; + case ConfirmExecutionResult.approved: + return Status.ok; + } + } + ConfirmExecutionResult.toStatus = toStatus; +})(ConfirmExecutionResult || (ConfirmExecutionResult = {})); +var ConfirmExecution; +(function (ConfirmExecution) { + ConfirmExecution.type = new node_1.RequestType('eslint/confirmESLintExecution'); +})(ConfirmExecution || (ConfirmExecution = {})); +var ShowOutputChannel; +(function (ShowOutputChannel) { + ShowOutputChannel.type = new node_1.NotificationType0('eslint/showOutputChannel'); +})(ShowOutputChannel || (ShowOutputChannel = {})); var ModeEnum; (function (ModeEnum) { ModeEnum["auto"] = "auto"; @@ -156,14 +189,14 @@ function makeDiagnostic(problem) { }; if (problem.ruleId) { const url = ruleDocData.urls.get(problem.ruleId); + result.code = problem.ruleId; if (url !== undefined) { - result.code = { - value: problem.ruleId, - target: url + result.codeDescription = { + href: url }; } - else { - result.code = problem.ruleId; + if (problem.ruleId === 'no-unused-vars') { + result.tags = [node_1.DiagnosticTag.Unnecessary]; } } return result; @@ -208,7 +241,15 @@ function recordCodeAction(document, diagnostic, problem) { edits = new Map(); codeActions.set(uri, edits); } - edits.set(computeKey(diagnostic), { label: `Fix this ${problem.ruleId} problem`, documentVersion: document.version, ruleId: problem.ruleId, edit: problem.fix, suggestions: problem.suggestions, line: problem.line }); + edits.set(computeKey(diagnostic), { + label: `Fix this ${problem.ruleId} problem`, + documentVersion: document.version, + ruleId: problem.ruleId, + line: problem.line, + diagnostic: diagnostic, + edit: problem.fix, + suggestions: problem.suggestions + }); } function convertSeverity(severity) { switch (severity) { @@ -371,14 +412,16 @@ const languageId2DefaultExt = new Map([ const languageId2ParserRegExp = function createLanguageId2ParserRegExp() { const result = new Map(); const typescript = /\/@typescript-eslint\/parser\//; - result.set('typescript', [typescript]); - result.set('typescriptreact', [typescript]); + const babelESLint = /\/babel-eslint\/lib\/index.js$/; + result.set('typescript', [typescript, babelESLint]); + result.set('typescriptreact', [typescript, babelESLint]); return result; }(); const languageId2ParserOptions = function createLanguageId2ParserOptionsRegExp() { const result = new Map(); const vue = /vue-eslint-parser\/.*\.js$/; - result.set('typescript', { regExps: [vue], parsers: new Set(['@typescript-eslint/parser']) }); + const typescriptEslintParser = /@typescript-eslint\/parser\/.*\.js$/; + result.set('typescript', { regExps: [vue], parsers: new Set(['@typescript-eslint/parser']), parserRegExps: [typescriptEslintParser] }); return result; }(); const languageId2PluginName = new Map([ @@ -391,6 +434,7 @@ const defaultLanguageIds = new Set([ ]); const path2Library = new Map(); const document2Settings = new Map(); +const executionConfirmations = new Map(); const projectFolderIndicators = [ ['package.json', true], ['.eslintignore', true], @@ -497,95 +541,142 @@ function resolveSettings(document) { } settings.silent = settings.validate === Validate.probe; return promise.then((libraryPath) => { - var _a; - let library = path2Library.get(libraryPath); - if (library === undefined) { - library = loadNodeModule(libraryPath); - if (library === undefined) { + const scope = settings.resolvedGlobalPackageManagerPath !== undefined && libraryPath.startsWith(settings.resolvedGlobalPackageManagerPath) + ? 'global' + : 'local'; + const cachedExecutionConfirmation = executionConfirmations.get(libraryPath); + const confirmationPromise = cachedExecutionConfirmation === undefined + ? connection.sendRequest(ConfirmExecution.type, { scope: scope, uri: uri, libraryPath }) + : Promise.resolve(cachedExecutionConfirmation); + return confirmationPromise.then((confirmed) => { + var _a; + // Only cache if the execution got confirm to give the UI the change + // to update on un confirmed execution. + if (confirmed !== ConfirmExecutionResult.approved) { settings.validate = Validate.off; - if (!settings.silent) { - connection.console.error(`Failed to load eslint library from ${libraryPath}. See output panel for more information.`); - } - } - else if (library.CLIEngine === undefined) { - settings.validate = Validate.off; - connection.console.error(`The eslint library loaded from ${libraryPath} doesn\'t export a CLIEngine. You need at least eslint@1.0.0`); + connection.sendDiagnostics({ uri: uri, diagnostics: [] }); + connection.sendNotification(StatusNotification.type, { uri: uri, state: ConfirmExecutionResult.toStatus(confirmed) }); + return settings; } else { - connection.console.info(`ESLint library loaded from: ${libraryPath}`); - settings.library = library; - path2Library.set(libraryPath, library); + executionConfirmations.set(libraryPath, confirmed); } - } - else { - settings.library = library; - } - if (settings.validate === Validate.probe && TextDocumentSettings.hasLibrary(settings)) { - settings.validate = Validate.off; - const uri = vscode_uri_1.URI.parse(document.uri); - let filePath = getFilePath(document); - if (filePath === undefined && uri.scheme === 'untitled' && settings.workspaceFolder !== undefined) { - const ext = languageId2DefaultExt.get(document.languageId); - const workspacePath = getFilePath(settings.workspaceFolder.uri); - if (workspacePath !== undefined && ext !== undefined) { - filePath = path.join(workspacePath, `test${ext}`); + let library = path2Library.get(libraryPath); + if (library === undefined) { + library = loadNodeModule(libraryPath); + if (library === undefined) { + settings.validate = Validate.off; + if (!settings.silent) { + connection.console.error(`Failed to load eslint library from ${libraryPath}. See output panel for more information.`); + } + } + else if (library.CLIEngine === undefined) { + settings.validate = Validate.off; + connection.console.error(`The eslint library loaded from ${libraryPath} doesn\'t export a CLIEngine. You need at least eslint@1.0.0`); } + else { + connection.console.info(`ESLint library loaded from: ${libraryPath}`); + settings.library = library; + path2Library.set(libraryPath, library); + } + } + else { + settings.library = library; } - if (filePath !== undefined) { - const parserRegExps = languageId2ParserRegExp.get(document.languageId); - const pluginName = languageId2PluginName.get(document.languageId); - const parserOptions = languageId2ParserOptions.get(document.languageId); - if (defaultLanguageIds.has(document.languageId)) { - settings.validate = Validate.on; + if (settings.validate === Validate.probe && TextDocumentSettings.hasLibrary(settings)) { + settings.validate = Validate.off; + const uri = vscode_uri_1.URI.parse(document.uri); + let filePath = getFilePath(document); + if (filePath === undefined && uri.scheme === 'untitled' && settings.workspaceFolder !== undefined) { + const ext = languageId2DefaultExt.get(document.languageId); + const workspacePath = getFilePath(settings.workspaceFolder.uri); + if (workspacePath !== undefined && ext !== undefined) { + filePath = path.join(workspacePath, `test${ext}`); + } } - else if (parserRegExps !== undefined || pluginName !== undefined || parserOptions !== undefined) { - const eslintConfig = withCLIEngine((cli) => { - if (typeof cli.getConfigForFile === 'function') { - return cli.getConfigForFile(filePath); - } - else { - return undefined; - } - }, settings); - if (eslintConfig !== undefined) { - const parser = eslintConfig.parser !== null - ? (process.platform === 'win32' ? eslintConfig.parser.replace(/\\/g, '/') : eslintConfig.parser) - : undefined; - if (parser !== undefined) { - if (parserRegExps !== undefined) { - for (const regExp of parserRegExps) { - if (regExp.test(parser)) { - settings.validate = Validate.on; - break; + if (filePath !== undefined) { + const parserRegExps = languageId2ParserRegExp.get(document.languageId); + const pluginName = languageId2PluginName.get(document.languageId); + const parserOptions = languageId2ParserOptions.get(document.languageId); + if (defaultLanguageIds.has(document.languageId)) { + settings.validate = Validate.on; + } + else if (parserRegExps !== undefined || pluginName !== undefined || parserOptions !== undefined) { + const eslintConfig = withCLIEngine((cli) => { + try { + if (typeof cli.getConfigForFile === 'function') { + return cli.getConfigForFile(filePath); + } + else { + return undefined; + } + } + catch (err) { + return undefined; + } + }, settings); + if (eslintConfig !== undefined) { + const parser = eslintConfig.parser !== null + ? (process.platform === 'win32' ? eslintConfig.parser.replace(/\\/g, '/') : eslintConfig.parser) + : undefined; + if (parser !== undefined) { + if (parserRegExps !== undefined) { + for (const regExp of parserRegExps) { + if (regExp.test(parser)) { + settings.validate = Validate.on; + break; + } + } + } + if (settings.validate !== Validate.on && parserOptions !== undefined && typeof ((_a = eslintConfig.parserOptions) === null || _a === void 0 ? void 0 : _a.parser) === 'string') { + for (const regExp of parserOptions.regExps) { + if (regExp.test(parser) && (parserOptions.parsers.has(eslintConfig.parserOptions.parser) || + parserOptions.parserRegExps !== undefined && parserOptions.parserRegExps.some(parserRegExp => parserRegExp.test(eslintConfig.parserOptions.parser)))) { + settings.validate = Validate.on; + break; + } } } } - if (settings.validate !== Validate.on && parserOptions !== undefined && typeof ((_a = eslintConfig.parserOptions) === null || _a === void 0 ? void 0 : _a.parser) === 'string') { - for (const regExp of parserOptions.regExps) { - if (regExp.test(parser) && parserOptions.parsers.has(eslintConfig.parserOptions.parser)) { + if (settings.validate !== Validate.on && Array.isArray(eslintConfig.plugins) && eslintConfig.plugins.length > 0 && pluginName !== undefined) { + for (const name of eslintConfig.plugins) { + if (name === pluginName) { settings.validate = Validate.on; break; } } } } - if (settings.validate !== Validate.on && Array.isArray(eslintConfig.plugins) && eslintConfig.plugins.length > 0 && pluginName !== undefined) { - for (const name of eslintConfig.plugins) { - if (name === pluginName) { - settings.validate = Validate.on; - break; - } - } - } } } + if (settings.validate === Validate.off) { + const params = { textDocument: { uri: document.uri } }; + connection.sendRequest(ProbeFailedRequest.type, params); + } } - if (settings.validate === Validate.off) { - const params = { textDocument: { uri: document.uri } }; - connection.sendRequest(ProbeFailedRequest.type, params); + if (settings.format && settings.validate === Validate.on && TextDocumentSettings.hasLibrary(settings)) { + const Uri = vscode_uri_1.URI.parse(uri); + const isFile = Uri.scheme === 'file'; + let pattern = isFile + ? Uri.fsPath.replace(/\\/g, '/') + : Uri.fsPath; + pattern = pattern.replace(/[\[\]\{\}]/g, '?'); + const filter = { scheme: Uri.scheme, pattern: pattern }; + const options = { documentSelector: [filter] }; + if (!isFile) { + formatterRegistrations.set(uri, connection.client.register(node_1.DocumentFormattingRequest.type, options)); + } + else { + const filePath = getFilePath(uri); + withCLIEngine((cli) => { + if (!cli.isPathIgnored(filePath)) { + formatterRegistrations.set(uri, connection.client.register(node_1.DocumentFormattingRequest.type, options)); + } + }, settings); + } } - } - return settings; + return settings; + }); }, () => { settings.validate = Validate.off; if (!settings.silent) { @@ -676,7 +767,7 @@ class BufferedMessageQueue { if (Request.is(message)) { const requestMessage = message; if (requestMessage.token.isCancellationRequested) { - requestMessage.reject(new node_1.ResponseError(node_1.ErrorCodes.RequestCancelled, 'Request got cancelled')); + requestMessage.reject(new node_1.ResponseError(node_1.LSPErrorCodes.RequestCancelled, 'Request got cancelled')); return; } const elem = this.requestHandlers.get(requestMessage.method); @@ -684,7 +775,7 @@ class BufferedMessageQueue { throw new Error(`No handler registered`); } if (elem.versionProvider && requestMessage.documentVersion !== undefined && requestMessage.documentVersion !== elem.versionProvider(requestMessage.params)) { - requestMessage.reject(new node_1.ResponseError(node_1.ErrorCodes.RequestCancelled, 'Request got cancelled')); + requestMessage.reject(new node_1.ResponseError(node_1.LSPErrorCodes.RequestCancelled, 'Request got cancelled')); return; } const result = elem.handler(requestMessage.params, requestMessage.token); @@ -732,30 +823,6 @@ function setupDocumentsListeners() { if (settings.validate !== Validate.on || !TextDocumentSettings.hasLibrary(settings)) { return; } - if (settings.format) { - const uri = vscode_uri_1.URI.parse(event.document.uri); - const isFile = uri.scheme === 'file'; - let pattern = isFile - ? uri.path.replace(/\\/g, '/') - : uri.path; - pattern = pattern.replace('[', '\\['); - pattern = pattern.replace(']', '\\]'); - pattern = pattern.replace('{', '\\{'); - pattern = pattern.replace('}', '\\}'); - const filter = { scheme: uri.scheme, pattern: pattern }; - const options = { documentSelector: [filter] }; - if (!isFile) { - formatterRegistrations.set(event.document.uri, connection.client.register(node_1.DocumentFormattingRequest.type, options)); - } - else { - const filePath = getFilePath(uri); - withCLIEngine((cli) => { - if (!cli.isPathIgnored(filePath)) { - formatterRegistrations.set(event.document.uri, connection.client.register(node_1.DocumentFormattingRequest.type, options)); - } - }, settings); - } - } if (settings.run === 'onSave') { messageQueue.addNotificationMessage(ValidateNotification.type, event.document, event.document.version); } @@ -763,6 +830,8 @@ function setupDocumentsListeners() { }); // A text document has changed. Validate the document according the run setting. documents.onDidChangeContent((event) => { + const uri = event.document.uri; + codeActions.delete(uri); resolveSettings(event.document).then((settings) => { if (settings.validate !== Validate.on || settings.run !== 'onType') { return; @@ -797,9 +866,14 @@ function setupDocumentsListeners() { } function environmentChanged() { document2Settings.clear(); + executionConfirmations.clear(); for (let document of documents.all()) { messageQueue.addNotificationMessage(ValidateNotification.type, document, document.version); } + for (const unregistration of formatterRegistrations.values()) { + unregistration.then(disposable => disposable.dispose()); + } + formatterRegistrations.clear(); } function trace(message, verbose) { connection.tracer.log(message, verbose); @@ -868,9 +942,12 @@ function validateSingle(document, publishDiagnostics = true) { } try { validate(document, settings, publishDiagnostics); - connection.sendNotification(StatusNotification.type, { state: Status.ok }); + connection.sendNotification(StatusNotification.type, { uri: document.uri, state: Status.ok }); } catch (err) { + // if an exception has occurred while validating clear all errors to ensure + // we are not showing any stale once + connection.sendDiagnostics({ uri: document.uri, diagnostics: [] }); if (!settings.silent) { let status = undefined; for (let handler of singleErrorHandlers) { @@ -880,11 +957,11 @@ function validateSingle(document, publishDiagnostics = true) { } } status = status || Status.error; - connection.sendNotification(StatusNotification.type, { state: status }); + connection.sendNotification(StatusNotification.type, { uri: document.uri, state: status }); } else { connection.console.info(getMessage(err, document)); - connection.sendNotification(StatusNotification.type, { state: Status.ok }); + connection.sendNotification(StatusNotification.type, { uri: document.uri, state: Status.ok }); } } }); @@ -1080,7 +1157,11 @@ function tryHandleMissingModule(error, document, library) { return undefined; } function showErrorMessage(error, document) { - connection.window.showErrorMessage(`ESLint: ${getMessage(error, document)}. Please see the 'ESLint' output channel for details.`); + connection.window.showErrorMessage(`ESLint: ${getMessage(error, document)}. Please see the 'ESLint' output channel for details.`, { title: 'Open Output', id: 1 }).then((value) => { + if (value !== undefined && value.id === 1) { + connection.sendNotification(ShowOutputChannel.type); + } + }); if (Is.string(error.stack)) { connection.console.error('ESLint stack trace:'); connection.console.error(error.stack); @@ -1282,9 +1363,12 @@ messageQueue.registerRequest(node_1.CodeActionRequest.type, (params) => { changes.clear(textDocument); return result.all(); } - function createCodeAction(title, kind, commandId, arg) { + function createCodeAction(title, kind, commandId, arg, diagnostic) { const command = node_1.Command.create(title, commandId, arg); const action = node_1.CodeAction.create(title, command, kind); + if (diagnostic !== undefined) { + action.diagnostics = [diagnostic]; + } return action; } function createDisableLineTextEdit(editInfo, indentationText) { @@ -1294,7 +1378,10 @@ messageQueue.registerRequest(node_1.CodeActionRequest.type, (params) => { return node_1.TextEdit.insert(node_1.Position.create(editInfo.line - 1, Number.MAX_VALUE), ` // eslint-disable-line ${editInfo.ruleId}`); } function createDisableFileTextEdit(editInfo) { - return node_1.TextEdit.insert(node_1.Position.create(0, 0), `/* eslint-disable ${editInfo.ruleId} */${os_1.EOL}`); + // If firts line contains a shebang, insert on the next line instead. + const shebang = textDocument === null || textDocument === void 0 ? void 0 : textDocument.getText(node_1.Range.create(node_1.Position.create(0, 0), node_1.Position.create(0, 2))); + const line = shebang === '#!' ? 1 : 0; + return node_1.TextEdit.insert(node_1.Position.create(line, 0), `/* eslint-disable ${editInfo.ruleId} */${os_1.EOL}`); } function getLastEdit(array) { const length = array.length; @@ -1343,7 +1430,7 @@ messageQueue.registerRequest(node_1.CodeActionRequest.type, (params) => { const workspaceChange = new node_1.WorkspaceChange(); workspaceChange.getTextEditChange({ uri, version: documentVersion }).add(FixableProblem.createTextEdit(textDocument, editInfo)); changes.set(`${CommandIds.applySingleFix}:${ruleId}`, workspaceChange); - const action = createCodeAction(editInfo.label, kind, CommandIds.applySingleFix, CommandParams.create(textDocument, ruleId)); + const action = createCodeAction(editInfo.label, kind, CommandIds.applySingleFix, CommandParams.create(textDocument, ruleId), editInfo.diagnostic); action.isPreferred = true; result.get(ruleId).fixes.push(action); } @@ -1352,7 +1439,7 @@ messageQueue.registerRequest(node_1.CodeActionRequest.type, (params) => { const workspaceChange = new node_1.WorkspaceChange(); workspaceChange.getTextEditChange({ uri, version: documentVersion }).add(SuggestionsProblem.createTextEdit(textDocument, suggestion)); changes.set(`${CommandIds.applySuggestion}:${ruleId}:${suggestionSequence}`, workspaceChange); - const action = createCodeAction(`${suggestion.desc} (${editInfo.ruleId})`, node_1.CodeActionKind.QuickFix, CommandIds.applySuggestion, CommandParams.create(textDocument, ruleId, suggestionSequence)); + const action = createCodeAction(`${suggestion.desc} (${editInfo.ruleId})`, node_1.CodeActionKind.QuickFix, CommandIds.applySuggestion, CommandParams.create(textDocument, ruleId, suggestionSequence), editInfo.diagnostic); result.get(ruleId).suggestions.push(action); }); } diff --git a/language-server/package-lock.json b/language-server/package-lock.json index 7a52968..f256492 100644 --- a/language-server/package-lock.json +++ b/language-server/package-lock.json @@ -1,41 +1,41 @@ { "name": "eslint-server", - "version": "2.1.5", + "version": "2.1.14", "lockfileVersion": 1, "requires": true, "dependencies": { "@types/node": { - "version": "14.0.13", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.0.13.tgz", - "integrity": "sha512-rouEWBImiRaSJsVA+ITTFM6ZxibuAlTuNOCyxVbwreu6k6+ujs7DfnU9o+PShFhET78pMBl3eH+AGSI5eOTkPA==", + "version": "14.14.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.6.tgz", + "integrity": "sha512-6QlRuqsQ/Ox/aJEQWBEJG7A9+u7oSYl3mem/K8IzxXG/kAGbV1YPD9Bg9Zw3vyxC/YP+zONKwy8hGkSt1jxFMw==", "dev": true }, "typescript": { - "version": "3.9.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.5.tgz", - "integrity": "sha512-hSAifV3k+i6lEoCJ2k6R2Z/rp/H3+8sdmcn5NrS3/3kE7+RyZXm9aqvxWqjEXHAd8b0pShatpcdMTvEdvAJltQ==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.0.5.tgz", + "integrity": "sha512-ywmr/VrTVCmNTJ6iV2LwIrfG1P+lv6luD8sUJs+2eI9NLGigaN+nUQc13iHqisq7bra9lnmUSYqbJvegraBOPQ==", "dev": true }, "vscode-jsonrpc": { - "version": "6.0.0-next.3", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-6.0.0-next.3.tgz", - "integrity": "sha512-bkAtRMXbTwU1pAXnlbkAMnrqXZX3q2/zttkcnPZOsDqgoycO2L7GK2aN3K5qCMZmhItwBU185T78Q9YH0v5jEA==" + "version": "6.0.0-next.7", + "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-6.0.0-next.7.tgz", + "integrity": "sha512-1nG+6cuTtpzmXe7yYfO9GCkYlyV6Ai+jDnwidHiT2T7zhc+bJM+VTtc0T/CdTlDyTNTqIcCj0V1nD4TcVjJ7Ug==" }, "vscode-languageserver": { - "version": "7.0.0-next.4", - "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-7.0.0-next.4.tgz", - "integrity": "sha512-yyFMuKLNkSKYb//6dQHCo0wlDYWkgRPEXoV+/aYXHp9ziIBqQxKJJFrf/rnXYReCz1TroxYMcFGdO5UrBsLAaA==", + "version": "7.0.0-next.10", + "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-7.0.0-next.10.tgz", + "integrity": "sha512-49Ud6FtO//AeACkZc208s7hx8trkJgJ+JsfBsUxbcLp4ScZk+mFbl3zNFv8/mllxRZF2le+vCgOmhLzTyemJHw==", "requires": { - "vscode-languageserver-protocol": "3.16.0-next.5" + "vscode-languageserver-protocol": "3.16.0-next.10" } }, "vscode-languageserver-protocol": { - "version": "3.16.0-next.5", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.16.0-next.5.tgz", - "integrity": "sha512-MVuLT4d5tdDo/14laViyZY+p1HT7wYDwJdvGmo8mCfkgON5c10AABhtqjD+LccidBcwdbKy+4dwwUUxiNg/8PA==", + "version": "3.16.0-next.10", + "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.16.0-next.10.tgz", + "integrity": "sha512-YRTctHUZvts0Z1xXKNYU0ha0o+Tlgtwr+6O8OmDquM086N8exiSKBMwMC+Ra1QtIE+1mfW43Wxsme2FnMkAS9A==", "requires": { - "vscode-jsonrpc": "6.0.0-next.3", - "vscode-languageserver-types": "3.16.0-next.2" + "vscode-jsonrpc": "6.0.0-next.7", + "vscode-languageserver-types": "3.16.0-next.4" } }, "vscode-languageserver-textdocument": { @@ -44,9 +44,9 @@ "integrity": "sha512-UIcJDjX7IFkck7cSkNNyzIz5FyvpQfY7sdzVy+wkKN/BLaD4DQ0ppXQrKePomCxTS7RrolK1I0pey0bG9eh8dA==" }, "vscode-languageserver-types": { - "version": "3.16.0-next.2", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.16.0-next.2.tgz", - "integrity": "sha512-QjXB7CKIfFzKbiCJC4OWC8xUncLsxo19FzGVp/ADFvvi87PlmBSCAtZI5xwGjF5qE0xkLf0jjKUn3DzmpDP52Q==" + "version": "3.16.0-next.4", + "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.16.0-next.4.tgz", + "integrity": "sha512-NlKJyGcET/ZBCCLBYIPaGo2c37R03bPYeWXozUtnjyye7+9dhlbMSODyoG2INcQf8zFmB4qhm2UOJjgYEgPCNA==" }, "vscode-uri": { "version": "2.1.1", diff --git a/language-server/package.json b/language-server/package.json index 3920caf..923bef3 100644 --- a/language-server/package.json +++ b/language-server/package.json @@ -1,6 +1,6 @@ { "name": "eslint-server", - "version": "2.1.5", + "version": "2.1.14", "private": true, "author": "Microsoft Corporation", "license": "MIT", @@ -16,12 +16,12 @@ }, "dependencies": { "vscode-uri": "^2.1.1", - "vscode-languageserver": "7.0.0-next.4", + "vscode-languageserver": "7.0.0-next.10", "vscode-languageserver-textdocument": "1.0.1" }, "scripts": {}, "devDependencies": { - "@types/node": "^14.0.13", - "typescript": "^3.9.5" + "@types/node": "^14.14.6", + "typescript": "^4.0.5" } } diff --git a/language-server/update-info.log b/language-server/update-info.log index c45ca2d..d8f36d9 100644 --- a/language-server/update-info.log +++ b/language-server/update-info.log @@ -1,2 +1,2 @@ Archive: src-master.zip -998a5e58642fa390a1df9d128a8581a906a58666 +8c4e0924063224245ddb4d7e059a5ab573fec17f diff --git a/plugin.py b/plugin.py index 9980325..dc332fe 100644 --- a/plugin.py +++ b/plugin.py @@ -31,12 +31,23 @@ def __init__(self, *args: Any, **kwargs: Any) -> None: def on_ready(self, api) -> None: api.on_notification('eslint/status', self.handle_status) + api.on_notification('eslint/exitCalled', self.handle_exit_called) + api.on_notification('eslint/showOutputChannel', self.handle_show_output_channel) api.on_request('eslint/openDoc', self.handle_open_doc) api.on_request('eslint/probeFailed', self.handle_probe_failed) + api.on_request('eslint/noConfig', self.handle_no_config) + api.on_request('eslint/noLibrary', self.handle_no_library) + api.on_request('eslint/confirmESLintExecution', self.handle_confirm_execution) def handle_status(self, params) -> None: pass + def handle_exit_called(self, params) -> None: + pass + + def handle_show_output_channel(self, params) -> None: + sublime.active_window().run_command('lsp_toggle_server_panel') + def handle_open_doc(self, params, respond) -> None: webbrowser.open(params['url']) respond({}) @@ -45,6 +56,20 @@ def handle_probe_failed(self, params, respond) -> None: self._probe_failed.add(params['textDocument']['uri']) respond(None) + def handle_no_config(self, params, respond) -> None: + # TODO: Show better notification that no eslint configuration was found. + print('LSP-eslint: Could not find eslint configuration ({}) for {}'.format( + params['message'], params['document']['uri'])) + respond(None) + + def handle_no_library(self, params, respond) -> None: + # TODO: Show better notification that no eslint library was found. + print('LSP-eslint: Failed resolving eslint library for {}'.format(params['source']['uri'])) + respond(None) + + def handle_confirm_execution(self, params, respond) -> None: + respond(4) # ConfirmExecutionResult.approved + def on_workspace_configuration(self, params, configuration) -> None: session = self.weaksession() if session: