UNPKG

fish-lsp

Version:

LSP implementation for fish/fish-shell

127 lines (126 loc) 4.83 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.handleHover = handleHover; exports.getHoverForFlag = getHoverForFlag; exports.collectCommandString = collectCommandString; const vscode_languageserver_1 = require("vscode-languageserver"); const documentation_1 = require("./documentation"); const exec_1 = require("./utils/exec"); const node_types_1 = require("./utils/node-types"); const tree_sitter_1 = require("./utils/tree-sitter"); const translation_1 = require("./utils/translation"); async function handleHover(analyzer, document, position, current, cache, logger) { if ((0, node_types_1.isOption)(current)) { return await getHoverForFlag(current); } const local = analyzer.getDefinition(document, position); if (local) { return { contents: { kind: vscode_languageserver_1.MarkupKind.Markdown, value: local.detail, }, range: local.selectionRange, }; } const { kindType, kindString } = (0, translation_1.symbolKindsFromNode)(current); const symbolType = ['function', 'class', 'variable'].includes(kindString) ? kindType : undefined; logger?.log({ './src/hover.ts:37': kindType }); if (cache.find(current.text) !== undefined) { await cache.resolve(current.text, document.uri, symbolType); const item = symbolType ? cache.find(current.text, symbolType) : cache.getItem(current.text); logger?.logAsJson('call: [./src/hover.ts:42]'); if (item && item?.docs) { return { contents: { kind: vscode_languageserver_1.MarkupKind.Markdown, value: item.docs.toString(), }, }; } } const commandString = await collectCommandString(current); const result = await (0, documentation_1.documentationHoverProvider)(commandString); logger?.log({ commandString, result }); return result; } async function getHoverForFlag(current) { const commandNode = (0, tree_sitter_1.findFirstParent)(current, n => (0, node_types_1.isCommand)(n) || (0, node_types_1.isFunctionDefinition)(n)); if (!commandNode) { return null; } let commandStr = [commandNode.child(0)?.text || '']; const flags = []; let hasFlags = false; for (const child of commandNode?.children || []) { if (!hasFlags && !child.text.startsWith('-')) { commandStr = await appendToCommand(commandStr, child.text); } else if (child.text.startsWith('-')) { flags.push(child.text); hasFlags = true; } } const flagCompletions = await (0, exec_1.execCompletions)(...commandStr, '-'); const shouldSplitShortFlags = hasOldUnixStyleFlags(flagCompletions); const fixedFlags = spiltShortFlags(flags, !shouldSplitShortFlags); const found = flagCompletions .map(line => line.split('\t')) .filter(line => fixedFlags.includes(line[0])) .map(line => line.join('\t')); return { contents: (0, documentation_1.enrichCommandWithFlags)(commandStr.join('-'), found), }; } function hasOldUnixStyleFlags(allFlags) { for (const line of allFlags.map(line => line.split('\t'))) { const flag = line[0]; if (flag.startsWith('-') && !flag.startsWith('--')) { if (flag.length > 2) { return true; } } } return false; } function spiltShortFlags(flags, shouldSplit) { const newFlags = []; for (let flag of flags) { flag = flag.split('=')[0]; if (flag.startsWith('-') && !flag.startsWith('--')) { if (flag.length > 2 && shouldSplit) { newFlags.push(...flag.split('').map(f => '-' + f)); continue; } } newFlags.push(flag); } return newFlags; } async function appendToCommand(commands, subCommand) { const completions = await (0, exec_1.execSubCommandCompletions)(...commands, ' '); // HERE if (completions.includes(subCommand)) { commands.push(subCommand); return commands; } else { return commands; } } async function collectCommandString(current) { const commandNode = (0, tree_sitter_1.findFirstParent)(current, n => (0, node_types_1.isCommand)(n)); if (!commandNode) { return ''; } const commandNodeText = commandNode.child(0)?.text; const subCommandName = commandNode.child(1)?.text; if (subCommandName?.startsWith('-')) { return commandNodeText || ''; } const commandText = [commandNodeText, subCommandName].join('-'); const docs = await (0, exec_1.execCommandDocs)(commandText); if (docs) { return commandText; } return commandNodeText || ''; }