UNPKG

fish-lsp

Version:

LSP implementation for fish/fish-shell

125 lines (124 loc) 5.7 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.handleDisableSingleLine = handleDisableSingleLine; exports.handleDisableBlock = handleDisableBlock; exports.groupDiagnostics = groupDiagnostics; exports.handleDisableEntireFile = handleDisableEntireFile; exports.getDisableDiagnosticActions = getDisableDiagnosticActions; const vscode_languageserver_1 = require("vscode-languageserver"); const error_codes_1 = require("../diagnostics/error-codes"); const action_kinds_1 = require("./action-kinds"); const logger_1 = require("../logger"); function createDisableAction(title, document, edits, diagnostics, isPreferred = false) { return { title, kind: action_kinds_1.SupportedCodeActionKinds.Disable, edit: { changes: { [document.uri]: edits, }, }, diagnostics, isPreferred, }; } function handleDisableSingleLine(document, diagnostic) { const indent = document.getIndentAtLine(diagnostic.range.start.line); const edit = vscode_languageserver_1.TextEdit.insert({ line: diagnostic.range.start.line, character: 0 }, `${indent}# @fish-lsp-disable-next-line ${diagnostic.code}\n`); const severity = error_codes_1.ErrorCodes.getSeverityString(diagnostic.severity); return createDisableAction(`Disable ${severity} diagnostic ${diagnostic.code} for line ${diagnostic.range.start.line + 1}`, document, [edit], [diagnostic]); } function handleDisableBlock(document, group) { const numbers = Array.from(new Set(group.diagnostics.map(diagnostic => diagnostic.code)).values()).join(' '); const startIndent = document.getIndentAtLine(group.startLine); const endIndent = document.getIndentAtLine(group.endLine); const edits = [ vscode_languageserver_1.TextEdit.insert({ line: group.startLine, character: 0 }, `${startIndent}# @fish-lsp-disable ${numbers}\n`), vscode_languageserver_1.TextEdit.insert({ line: group.endLine + 1, character: 0 }, `${endIndent}# @fish-lsp-enable ${numbers}\n`), ]; return { ...createDisableAction(`Disable diagnostics ${numbers} in block (lines ${group.startLine + 1}-${group.endLine + 1})`, document, edits, group.diagnostics), }; } function groupDiagnostics(diagnostics, maxGap = 1) { if (diagnostics.length === 0) return []; const sorted = [...diagnostics].sort((a, b) => a.range.start.line - b.range.start.line); const groups = []; let currentGroup = { startLine: sorted[0].range.start.line, endLine: sorted[0].range.end.line, diagnostics: [sorted[0]], }; for (let i = 1; i < sorted.length; i++) { const current = sorted[i]; const gap = current.range.start.line - currentGroup.endLine; if (gap <= maxGap) { currentGroup.endLine = Math.max(currentGroup.endLine, current.range.end.line); currentGroup.diagnostics.push(current); } else { groups.push(currentGroup); currentGroup = { startLine: current.range.start.line, endLine: current.range.end.line, diagnostics: [current], }; } } groups.push(currentGroup); return groups; } function handleDisableEntireFile(document, diagnostics) { const results = []; const diagnosticsCounts = new Map(); diagnostics.forEach(diagnostic => { const code = diagnostic.code; diagnosticsCounts.set(code, (diagnosticsCounts.get(code) || 0) + 1); }); const matchingDiagnostics = []; diagnosticsCounts.forEach((count, code) => { if (count >= 5) { logger_1.logger.log(`CODEACTION: Disabling ${count} ${code.toString()} diagnostics in file`); } matchingDiagnostics.push(code); }); if (matchingDiagnostics.length === 0) return results; let tokenLine = 0; let firstLine = document.getLine(tokenLine); if (firstLine.startsWith('#!/')) { tokenLine++; } firstLine = document.getLine(tokenLine); const allNumbersStr = matchingDiagnostics.join(' ').trim(); if (!firstLine.startsWith('# @fish-lsp-disable')) { const edits = [ vscode_languageserver_1.TextEdit.insert({ line: tokenLine, character: 0 }, `# @fish-lsp-disable ${allNumbersStr}\n`), ]; results.push(createDisableAction(`Disable all diagnostics in file (${allNumbersStr.split(' ').join(', ')})`, document, edits, diagnostics)); matchingDiagnostics.forEach(match => { const severity = error_codes_1.ErrorCodes.getSeverityString(error_codes_1.ErrorCodes.getDiagnostic(match).severity); results.push(createDisableAction(`Disable ${severity} ${match.toString()} diagnostics for entire file`, document, [ vscode_languageserver_1.TextEdit.insert({ line: tokenLine, character: 0 }, `# @fish-lsp-disable ${match.toString()}\n`), ], diagnostics)); }); } return results; } function getDisableDiagnosticActions(document, diagnostics) { const actions = []; diagnostics .filter(diagnostic => diagnostic.severity === vscode_languageserver_1.DiagnosticSeverity.Warning || diagnostic.code === error_codes_1.ErrorCodes.sourceFileDoesNotExist).forEach(diagnostic => { actions.push(handleDisableSingleLine(document, diagnostic)); }); const groups = groupDiagnostics(diagnostics); groups.forEach(group => { if (group.diagnostics.length > 1) { actions.push(handleDisableBlock(document, group)); } }); actions.push(...handleDisableEntireFile(document, diagnostics)); return actions; }