UNPKG

fish-lsp

Version:

LSP implementation for fish/fish-shell

158 lines (157 loc) 7.83 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.createCodeActionHandler = createCodeActionHandler; 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) { /** * small helper for now, used to add code actions that are not `preferred` * quickfixes to the list of results, when a quickfix is requested. */ async function getSelectionCodeActions(document, range) { const rootNode = analyzer.getRootNode(document); 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).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.isIfStatement)(n)) { const convertIfAction = (0, refactors_1.convertIfToCombiners)(document, n, false); if (convertIfAction) results.push(convertIfAction); } }); } 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; } /** * Helper to add quick fixes to the list that are mostly of the type `preferred` * * These quick fixes include things like `disable` actions, and general fixes to silence diagnostics */ 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; } /** * Process refactors for the given document and range */ async function processRefactors(document, range) { const results = []; const rootNode = analyzer.getRootNode(document); if (!rootNode) return results; // Get node at the selected range const selectedNode = (0, tree_sitter_1.getNodeAtRange)(rootNode, range); if (!selectedNode) return results; // try refactoring aliases first 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; } // Try each refactoring action 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 []; const results = []; // Check what kinds of actions are requested 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', params.context.diagnostics.map(d => d.message)); // Add disable actions if (params.context.diagnostics.length > 0 && !onlyRefactoring) { results.push(...(0, disable_actions_1.getDisableDiagnosticActions)(document, params.context.diagnostics)); } // Add quick fixes if requested if (onlyQuickFix) { logger_1.logger.log('Processing onlyQuickFixes'); results.push(...await processQuickFixes(document, params.context.diagnostics, analyzer)); results.push(...await getSelectionCodeActions(document, params.range)); logger_1.logger.log('CodeAction results', results.map(r => r.title)); return results; } // add the refactors 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, params.context.diagnostics, analyzer)); results.push(...await getSelectionCodeActions(document, params.range)); logger_1.logger.log('CodeAction results', results.map(r => r.title)); return results; }; }