UNPKG

fish-lsp

Version:

LSP implementation for fish/fish-shell

122 lines (121 loc) 4.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.CompletionItemMap = void 0; exports.splitLine = splitLine; const types_1 = require("./types"); const exec_1 = require("../exec"); const static_items_1 = require("./static-items"); const startup_config_1 = require("./startup-config"); const markdown_builder_1 = require("../markdown-builder"); class CompletionItemMap { _items; constructor(_items = {}) { this._items = _items; } static async initialize() { const result = {}; const cmdOutputs = new Map(); const topLevelLabels = new Set(); await Promise.all(startup_config_1.SetupItemsFromCommandConfig.map(async (item) => { const stdout = await (0, exec_1.execCmd)(item.command); cmdOutputs.set(item.fishKind, stdout); })); startup_config_1.SetupItemsFromCommandConfig.forEach((item) => { const items = []; const stdout = cmdOutputs.get(item.fishKind); stdout.forEach((line) => { if (line.trim().length === 0) { return; } const { label, value } = splitLine(line); if (item.topLevel) { if (topLevelLabels.has(label)) { return; } topLevelLabels.add(label); } const detail = getCommandsDetail(value || item.detail); items.push(types_1.FishCompletionItem.create(label, item.fishKind, detail, line)); }); result[item.fishKind] = items; }); Object.entries(static_items_1.StaticItems).forEach(([key, value]) => { const kind = key; if (!result[kind]) { result[kind] = value.map((item) => types_1.FishCompletionItem.create(item.label, kind, item.detail, item.documentation.toString(), item.examples)); } if (kind === types_1.FishCompletionItemKind.FUNCTION || kind === types_1.FishCompletionItemKind.VARIABLE) { const toAdd = value .filter((item) => !result[kind].find((i) => i.label === item.label)) .map((item) => types_1.FishCompletionItem.create(item.label, kind, item.detail, [ `(${markdown_builder_1.md.italic(kind)}) ${markdown_builder_1.md.bold(item.label)}`, markdown_builder_1.md.separator(), item.documentation.toString(), ].join('\n'), item.examples).setUseDocAsDetail()); result[kind].push(...toAdd); } }); return new CompletionItemMap(result); } get(kind) { return this._items[kind] || []; } get allKinds() { return Object.keys(this._items); } allOfKinds(...kinds) { return kinds.reduce((acc, kind) => acc.concat(this.get(kind)), []); } entries() { return Object.entries(this._items); } forEach(callbackfn) { this.entries().forEach(([key, value]) => callbackfn(key, value)); } allCompletionsWithoutCommand() { return this.allOfKinds(types_1.FishCompletionItemKind.ABBR, types_1.FishCompletionItemKind.ALIAS, types_1.FishCompletionItemKind.BUILTIN, types_1.FishCompletionItemKind.FUNCTION, types_1.FishCompletionItemKind.COMMAND); } findLabel(label, ...searchKinds) { const kinds = searchKinds?.length > 0 ? searchKinds : this.allKinds; for (const kind of kinds) { const item = this.get(kind).find((item) => item.label === label); if (item) { return item; } } return undefined; } get blockedCommands() { return [ 'end', 'else', 'continue', 'break', ]; } } exports.CompletionItemMap = CompletionItemMap; function splitLine(line) { const index = line.search(/\s/); if (index === -1) { return { label: line }; } const label = line.slice(0, index); const value = line.slice(index).trimStart(); return { label, value }; } function getCommandsDetail(value) { if (value.trim().length === 0) { return 'command'; } if (value.startsWith('alias')) { return 'alias'; } if (value === 'command link') { return 'command'; } if (value === 'command') { return 'command'; } return value; }