UNPKG

fish-lsp

Version:

LSP implementation for fish/fish-shell

173 lines (172 loc) 8.42 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.createCodeActionHandler = createCodeActionHandler; exports.equalDiagnostics = equalDiagnostics; exports.createOnCodeActionResolveHandler = createOnCodeActionResolveHandler; exports.codeActionHandlers = codeActionHandlers; const disable_actions_1 = require("./disable-actions"); const quick_fixes_1 = require("./quick-fixes"); const translation_1 = require("../utils/translation"); const logger_1 = require("../logger"); const tree_sitter_1 = require("../utils/tree-sitter"); const refactors_1 = require("./refactors"); const argparse_completions_1 = require("./argparse-completions"); const node_types_1 = require("../utils/node-types"); const alias_wrapper_1 = require("./alias-wrapper"); function createCodeActionHandler(docs, analyzer) { async function getSelectionCodeActions(document, range) { const rootNode = analyzer.getRootNode(document.uri); if (!rootNode) return []; const selectedNode = (0, tree_sitter_1.getNodeAtRange)(rootNode, range); if (!selectedNode) return []; const results = []; if ((0, node_types_1.isProgram)(selectedNode)) { analyzer.getNodes(document.uri).forEach(n => { if ((0, node_types_1.isCommandWithName)(n, 'argparse')) { const argparseAction = (0, argparse_completions_1.createArgparseCompletionsCodeAction)(n, document); if (argparseAction) results.push(argparseAction); } }); } if (!(0, node_types_1.isProgram)(selectedNode)) { const commandToFunctionAction = (0, refactors_1.extractCommandToFunction)(document, selectedNode); if (commandToFunctionAction) results.push(commandToFunctionAction); } if ((0, node_types_1.isCommandWithName)(selectedNode, 'alias')) { const aliasInlineFunction = await (0, alias_wrapper_1.createAliasInlineAction)(document, selectedNode); const aliasNewFile = await (0, alias_wrapper_1.createAliasSaveActionNewFile)(document, selectedNode); if (aliasInlineFunction) results.push(aliasInlineFunction); if (aliasNewFile) results.push(aliasNewFile); } return results; } async function processQuickFixes(document, diagnostics, analyzer) { const results = []; for (const diagnostic of diagnostics) { logger_1.logger.log('Processing diagnostic', diagnostic.code, diagnostic.message); const quickFixs = await (0, quick_fixes_1.getQuickFixes)(document, diagnostic, analyzer); for (const fix of quickFixs) { logger_1.logger.log('QuickFix', fix?.title); } if (quickFixs) results.push(...quickFixs); } return results; } async function processRefactors(document, range) { const results = []; const rootNode = analyzer.getRootNode(document.uri); if (!rootNode) return results; const selectedNode = (0, tree_sitter_1.getNodeAtRange)(rootNode, range); if (!selectedNode) return results; let aliasCommand = selectedNode; if (selectedNode.text === 'alias') aliasCommand = selectedNode.parent; if (aliasCommand && (0, node_types_1.isCommandWithName)(aliasCommand, 'alias')) { logger_1.logger.log('isCommandWithName(alias)', aliasCommand.text); const aliasInlineFunction = await (0, alias_wrapper_1.createAliasInlineAction)(document, aliasCommand); const aliasNewFile = await (0, alias_wrapper_1.createAliasSaveActionNewFile)(document, aliasCommand); if (aliasInlineFunction) results.push(aliasInlineFunction); if (aliasNewFile) results.push(aliasNewFile); return results; } const extractFunction = (0, refactors_1.extractToFunction)(document, range); if (extractFunction) results.push(extractFunction); const extractCommandFunction = (0, refactors_1.extractCommandToFunction)(document, selectedNode); if (extractCommandFunction) results.push(extractCommandFunction); const extractVar = (0, refactors_1.extractToVariable)(document, range, selectedNode); if (extractVar) results.push(extractVar); const extractFuncToFile = (0, refactors_1.extractFunctionToFile)(document, range, selectedNode); if (extractFuncToFile) results.push(extractFuncToFile); const extractCompletionToFile = (0, refactors_1.extractFunctionWithArgparseToCompletionsFile)(document, range, selectedNode); if (extractCompletionToFile) results.push(extractCompletionToFile); const convertIf = (0, refactors_1.convertIfToCombiners)(document, selectedNode); if (convertIf) results.push(convertIf); return results; } return async function handleCodeAction(params) { logger_1.logger.log('onCodeAction', params); const uri = (0, translation_1.uriToPath)(params.textDocument.uri); const document = docs.get(uri); if (!document || !uri) return []; logger_1.logger.log('onCodeAction', { uri }); const results = []; const diagnostics = params.context.diagnostics.filter(d => d.source === 'fish-lsp'); const onlyRefactoring = params.context.only?.some(kind => kind.startsWith('refactor')); const onlyQuickFix = params.context.only?.some(kind => kind.startsWith('quickfix')); logger_1.logger.log('Requested actions', { onlyRefactoring, onlyQuickFix }); logger_1.logger.log('Diagnostics', diagnostics.map(d => d.message)); if (diagnostics.length > 0 && !onlyRefactoring) { results.push(...(0, disable_actions_1.getDisableDiagnosticActions)(document, diagnostics)); } if (onlyQuickFix) { logger_1.logger.log('Processing onlyQuickFixes'); results.push(...await processQuickFixes(document, diagnostics, analyzer)); results.push(...await getSelectionCodeActions(document, params.range)); const allAction = (0, quick_fixes_1.createFixAllAction)(document, results); if (allAction) results.push(allAction); logger_1.logger.log('CodeAction results', results.map(r => r.title)); return results; } if (onlyRefactoring) { logger_1.logger.log('Processing onlyRefactors'); results.push(...await processRefactors(document, params.range)); logger_1.logger.log('CodeAction results', results.map(r => r.title)); return results; } logger_1.logger.log('Processing all actions'); results.push(...await processQuickFixes(document, diagnostics, analyzer)); results.push(...await getSelectionCodeActions(document, params.range)); const allAction = (0, quick_fixes_1.createFixAllAction)(document, results); if (allAction) { logger_1.logger.log({ name: 'allAction', title: allAction.title, kind: allAction.kind, diagnostics: diagnostics?.map(d => d.message), edit: allAction.edit, }); results.push(allAction); } logger_1.logger.log('CodeAction results', results.map(r => r.title)); return results; }; } function equalDiagnostics(d1, d2) { return d1.code === d2.code && d1.message === d2.message && d1.range.start.line === d2.range.start.line && d1.range.start.character === d2.range.start.character && d1.range.end.line === d2.range.end.line && d1.range.end.character === d2.range.end.character && d1.data.node?.text === d2.data.node?.text; } function createOnCodeActionResolveHandler(_docs, _analyzer) { return async function codeActionResolover(codeAction) { return codeAction; }; } function codeActionHandlers(docs, analyzer) { return { onCodeAction: createCodeActionHandler(docs, analyzer), onCodeActionResolve: createOnCodeActionResolveHandler(docs, analyzer), }; }