fish-lsp
Version:
LSP implementation for fish/fish-shell
313 lines (312 loc) • 12.7 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.PrebuiltDocumentationMap = exports.fishLspObjs = exports.EnvVariableJson = exports.ExtendedBaseJson = void 0;
exports.fromCliOutputToString = fromCliOutputToString;
exports.fromCliToMarkdownString = fromCliToMarkdownString;
exports.getPrebuiltDocUrlByName = getPrebuiltDocUrlByName;
exports.getPrebuiltDocUrl = getPrebuiltDocUrl;
const helperCommands_json_1 = __importDefault(require("../snippets/helperCommands.json"));
const syntaxHighlightingVariables_json_1 = __importDefault(require("../snippets/syntaxHighlightingVariables.json"));
const statusNumbers_json_1 = __importDefault(require("../snippets/statusNumbers.json"));
const envVariables_json_1 = __importDefault(require("../snippets/envVariables.json"));
const localeVariables_json_1 = __importDefault(require("../snippets/localeVariables.json"));
const specialFishVariables_json_1 = __importDefault(require("../snippets/specialFishVariables.json"));
const pipesAndRedirects_json_1 = __importDefault(require("../snippets/pipesAndRedirects.json"));
const fishlspEnvVariables_json_1 = __importDefault(require("../snippets/fishlspEnvVariables.json"));
const markdown_builder_1 = require("./markdown-builder");
var ExtendedBaseJson;
(function (ExtendedBaseJson) {
function create(o, type, specialType) {
return {
...o,
type,
specialType,
};
}
ExtendedBaseJson.create = create;
function is(o) {
return o.type !== undefined && o.exactMatchOptions === undefined;
}
ExtendedBaseJson.is = is;
})(ExtendedBaseJson || (exports.ExtendedBaseJson = ExtendedBaseJson = {}));
var EnvVariableJson;
(function (EnvVariableJson) {
function create(o, exactMatchOptions, options) {
return {
...o,
type: 'variable',
specialType: 'fishlsp',
isDeprecated: o.isDeprecated || false,
exactMatchOptions,
options,
};
}
EnvVariableJson.create = create;
function is(o) {
return o.type === 'variable' && o.specialType === 'fishlsp' && o.exactMatchOptions !== undefined;
}
EnvVariableJson.is = is;
const joinValueTypes = (valueType) => {
if (!Array.isArray(valueType)) {
return String.raw `${valueType}`;
}
return valueType.map(v => {
if (Number.isInteger(v)) {
return v;
}
return "'" + String.raw `${v}` + "'";
}).join(', ');
};
const joinDefaultValue = (valueType, defaultValue, optionValue) => {
if (!Array.isArray(defaultValue)) {
if (valueType === 'string' && defaultValue === '') {
return `'${defaultValue}'`;
}
else if (valueType === 'number') {
return `${defaultValue}`;
}
else if (valueType === 'boolean') {
return `'${defaultValue}'`;
}
else if (valueType === 'array') {
return '[\'\']';
}
else {
return '';
}
}
else {
if (valueType === 'array' && defaultValue.length === 0) {
if (Array.isArray(optionValue) && optionValue.some(v => Number.isInteger(v))) {
return '[]';
}
return '[]';
}
else if (valueType === 'array' && defaultValue.length > 0) {
return '[' + joinValueTypes(defaultValue) + ']';
}
return joinValueTypes(defaultValue);
}
};
function asCliObject(o) {
const options = joinValueTypes(o.options);
const defaultValue = joinDefaultValue(o.valueType, o.defaultValue, o.options);
return {
name: o.name,
valueType: o.valueType,
description: o.description,
exactMatchOptions: o.exactMatchOptions,
type: o.type,
options,
defaultValue,
};
}
EnvVariableJson.asCliObject = asCliObject;
function toCliOutput(o, opts = {
includeType: true,
includeOptions: true,
includeDefaultValue: true,
wrap: true,
}) {
const cli = asCliObject(o);
return fromCliOutputToString(cli, opts);
}
EnvVariableJson.toCliOutput = toCliOutput;
function toMarkdownString(o, opts = {
includeType: true,
includeOptions: true,
includeDefaultValue: true,
wrap: true,
}) {
const cli = asCliObject(o);
return fromCliToMarkdownString(cli, opts);
}
EnvVariableJson.toMarkdownString = toMarkdownString;
})(EnvVariableJson || (exports.EnvVariableJson = EnvVariableJson = {}));
function buildBodySection(subtitle, body, shouldWrap = false, asMarkdown = false) {
const hasTitle = () => subtitle.length > 0;
const titleStr = !hasTitle() ? '' : `(${subtitle}: `;
const trailingBrace = !hasTitle() ? '' : ')';
const separator = asMarkdown ? '\n\n' : '\n';
if (!shouldWrap)
return `${titleStr} ${body}${trailingBrace}`;
const maxLineLength = 76;
const output = [];
let currentLine = titleStr;
const leftpadBody = !hasTitle() ? '' : ' '.repeat(titleStr.length);
const splitBody = body.split(' ');
const addComma = (idx) => idx === splitBody.length - 1 ? '' : ',';
const words = asMarkdown
? body.split(' ').map((word, idx) => {
const newWord = word !== "''" && !Number.isInteger(word) ? word.slice(0, -1) : word;
if (Number.isInteger(newWord))
return markdown_builder_1.md.inlineCode(newWord) + addComma(idx);
if (newWord.startsWith("'") && newWord.endsWith("'")) {
return markdown_builder_1.md.inlineCode(newWord) + addComma(idx);
}
return markdown_builder_1.md.inlineCode(word);
})
: body.split(' ');
for (const word of words) {
if (currentLine.length + word.length + 1 > maxLineLength) {
output.push(currentLine);
currentLine = `${leftpadBody}${word} `;
}
else {
currentLine += `${word} `;
}
}
output.push(currentLine);
return output.join(separator).trimEnd() + trailingBrace;
}
function fromCliOutputToString(cli, opts = {
includeType: true,
includeOptions: true,
includeDefaultValue: true,
wrap: true,
}) {
const title = opts?.includeType ? `$${cli.name} <${cli.valueType.toString().toUpperCase()}>` : cli.name;
const body = [];
body.push(...cli.description.split('\n\n'));
if (opts.includeOptions) {
if (cli.exactMatchOptions) {
body.push(buildBodySection('Options', cli.options, opts.wrap));
}
else {
body.push(buildBodySection('Example Options', cli.options, opts.wrap));
}
}
if (opts.includeDefaultValue)
body.push(buildBodySection('Default', cli.defaultValue, opts.wrap));
return [
title,
...body.join('\n').trimEnd().split('\n'),
].map(line => `# ${line}`).join('\n');
}
function fromCliToMarkdownString(cli, opts = {
includeType: true,
includeOptions: true,
includeDefaultValue: true,
wrap: true,
}) {
const body = [];
if (opts.includeOptions) {
if (cli.exactMatchOptions) {
body.push(buildBodySection(markdown_builder_1.md.bold('Options'), cli.options, opts.wrap, true));
}
else {
body.push(buildBodySection(markdown_builder_1.md.bold('Example Options'), cli.options, opts.wrap, true));
}
}
if (opts.includeDefaultValue)
body.push(buildBodySection(markdown_builder_1.md.bold('Default'), cli.defaultValue, opts.wrap, true));
return [
`(${markdown_builder_1.md.bold(cli.type)}) ${markdown_builder_1.md.inlineCode(cli.name)} <${cli.valueType.toString().toUpperCase()}>`,
cli.description,
markdown_builder_1.md.separator(),
...body.join('\n\n').trimEnd().split('\n\n'),
].join('\n\n');
}
exports.fishLspObjs = fishlspEnvVariables_json_1.default.map((item) => EnvVariableJson.create(item, item?.exactMatchOptions, item?.options));
class DocumentationMap {
map = new Map();
typeMap = new Map();
constructor(data) {
data.forEach(item => {
const curr = this.map.get(item.name) || [];
curr.push(item);
this.map.set(item.name, curr);
if (!this.typeMap.has(item.type))
this.typeMap.set(item.type, []);
this.typeMap.get(item.type).push(item);
});
}
getByName(name) {
return name.startsWith('$')
? this.map.get(name.slice(1))?.filter(item => item.type === 'variable') || []
: this.map.get(name) || [];
}
getByType(type, specialType) {
const allOfType = this.typeMap.get(type) || [];
return specialType !== undefined
? allOfType.filter(v => v?.specialType === specialType)
: allOfType;
}
add(item) {
const curr = this.map.get(item.name) || [];
curr?.push(item);
this.map.set(item.name, curr);
if (!this.typeMap.has(item.type))
this.typeMap.set(item.type, []);
this.typeMap.get(item.type).push(item);
}
findMatchingNames(query, ...types) {
const results = [];
this.map.forEach(items => {
if (items.filter(item => item.name.startsWith(query) && (types.length === 0 || types.includes(item.type || item.specialType)))) {
results.push(...items);
}
});
return results;
}
getSpecialVariableAsHoverDoc(name) {
const variables = this.getByType('variable');
const searchStr = name.startsWith('$') ? name.slice(1) : name;
const needle = searchStr === 'fish_lsp_logfile' ? 'fish_lsp_log_file' : searchStr;
const result = variables.find(item => item.name === needle);
if (!result)
return '';
return [
`(${markdown_builder_1.md.italic('variable')}) - ${markdown_builder_1.md.inlineCode('$' + searchStr)}`,
markdown_builder_1.md.separator(),
result.description,
].join('\n');
}
}
const allData = [
...helperCommands_json_1.default.map((item) => ExtendedBaseJson.create(item, 'command')),
...pipesAndRedirects_json_1.default.map((item) => ExtendedBaseJson.create(item, 'pipe')),
...statusNumbers_json_1.default.map((item) => ExtendedBaseJson.create(item, 'status')),
...syntaxHighlightingVariables_json_1.default.map((item) => ExtendedBaseJson.create(item, 'variable', 'theme')),
...fishlspEnvVariables_json_1.default.map((item) => EnvVariableJson.create(item, item?.exactMatchOptions, item?.options)),
...envVariables_json_1.default.map((item) => ExtendedBaseJson.create(item, 'variable', 'env')),
...localeVariables_json_1.default.map((item) => ExtendedBaseJson.create(item, 'variable', 'locale')),
...specialFishVariables_json_1.default.map((item) => ExtendedBaseJson.create(item, 'variable', 'special')),
];
exports.PrebuiltDocumentationMap = new DocumentationMap(allData);
function getPrebuiltDocUrlByName(name) {
const objs = exports.PrebuiltDocumentationMap.getByName(name);
const res = [];
objs.forEach((obj, _index) => {
res.push(` - ${getPrebuiltDocUrl(obj)}`);
});
return res.join('\n').trim();
}
function getPrebuiltDocUrl(obj) {
switch (obj.type) {
case 'command':
return `https://fishshell.com/docs/current/cmds/${obj.name}.html`;
case 'pipe':
return 'https://fishshell.com/docs/current/language.html#input-output-redirection';
case 'status':
return 'https://fishshell.com/docs/current/language.html#variables-status';
case 'variable':
default:
break;
}
switch (obj.specialType) {
case 'env':
return `https://fishshell.com/docs/current/language.html#envvar-${obj.name}`;
case 'locale':
return `https://fishshell.com/docs/current/language.html#locale-variables-${obj.name}`;
case 'theme':
return `https://fishshell.com/docs/current/language.html#envvar-${obj.name}`;
case 'special':
return `https://fishshell.com/docs/current/language.html#envvar-${obj.name}`;
default:
return '';
}
}