UNPKG

fish-lsp

Version:

LSP implementation for fish/fish-shell

240 lines (239 loc) 9.15 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.signatureIndex = void 0; exports.buildSignature = buildSignature; exports.getCurrentNodeType = getCurrentNodeType; exports.lineSignatureBuilder = lineSignatureBuilder; exports.getPipes = getPipes; exports.getAliasedCompletionItemSignature = getAliasedCompletionItemSignature; exports.regexStringSignature = regexStringSignature; exports.getDefaultSignatures = getDefaultSignatures; const snippets_1 = require("./utils/snippets"); const NodeTypes = __importStar(require("./utils/node-types")); const TreeSitter = __importStar(require("./utils/tree-sitter")); function buildSignature(label, value) { return { label: label, documentation: { kind: 'markdown', value: value, }, }; } function getCurrentNodeType(input) { const prebuiltTypes = snippets_1.PrebuiltDocumentationMap.getByName(input); if (!prebuiltTypes || prebuiltTypes.length === 0) { return null; } let longestDocs = prebuiltTypes[0]; for (const prebuilt of prebuiltTypes) { if (prebuilt.description.length > longestDocs.description.length) { longestDocs = prebuilt; } } return longestDocs; } function lineSignatureBuilder(lineRootNode, lineCurrentNode, _completeMmap) { const currentCmd = NodeTypes.findParentCommand(lineCurrentNode) || lineRootNode; const pipes = getPipes(lineRootNode); const varNode = getVariableNode(lineRootNode); const allCmds = getAllCommands(lineRootNode); const regexOption = getRegexOption(lineRootNode); if (pipes.length === 1) return getPipesSignature(pipes); switch (true) { case isStringWithRegex(currentCmd.text, regexOption): return getDefaultSignatures(); case varNode && isSetOrReadWithVarNode(currentCmd?.text || lineRootNode.text, varNode, lineRootNode, allCmds): return getSignatureForVariable(varNode); case currentCmd?.text.startsWith('return') || lineRootNode.text.startsWith('return'): return getReturnStatusSignature(); case allCmds.length === 1: return getCommandSignature(currentCmd); default: return null; } } function getPipes(rootNode) { const pipeNames = snippets_1.PrebuiltDocumentationMap.getByType('pipe'); return TreeSitter.getChildNodes(rootNode).reduce((acc, node) => { const pipe = pipeNames.find(p => p.name === node.text); if (pipe) acc.push(pipe); return acc; }, []); } function getVariableNode(rootNode) { return TreeSitter.getChildNodes(rootNode).find(c => NodeTypes.isVariableDefinition(c)); } function getAllCommands(rootNode) { return TreeSitter.getChildNodes(rootNode).filter(c => NodeTypes.isCommand(c)); } function getRegexOption(rootNode) { return TreeSitter.getChildNodes(rootNode).find(n => NodeTypes.isMatchingOption(n, { shortOption: '-r', longOption: '--regex' })); } function isStringWithRegex(line, regexOption) { return line.startsWith('string') && !!regexOption; } function isSetOrReadWithVarNode(line, varNode, rootNode, allCmds) { return !!varNode && (line.startsWith('set') || line.startsWith('read')) && allCmds.pop()?.text === rootNode.text.trim(); } function getSignatureForVariable(varNode) { const output = getCurrentNodeType(varNode.text); if (!output) return null; return { signatures: [buildSignature(output.name, output.description)], activeSignature: 0, activeParameter: 0, }; } function getReturnStatusSignature() { const output = snippets_1.PrebuiltDocumentationMap.getByType('status').map((o) => `___${o.name}___ - _${o.description}_`).join('\n'); return { signatures: [buildSignature('$status', output)], activeSignature: 0, activeParameter: 0, }; } function getPipesSignature(pipes) { return { signatures: pipes.map((o) => buildSignature(o.name, `${o.name} - _${o.description}_`)), activeSignature: 0, activeParameter: 0, }; } function getCommandSignature(firstCmd) { const output = snippets_1.PrebuiltDocumentationMap.getByType('command').filter(n => n.name === firstCmd.text); return { signatures: [buildSignature(firstCmd.text, output.map((o) => `${o.name} - _${o.description}_`).join('\n'))], activeSignature: 0, activeParameter: 0, }; } function getAliasedCompletionItemSignature(item) { // const output = PrebuiltDocumentationMap.getByType('command').filter(n => n.name === firstCmd.text); return { signatures: [buildSignature(item.label, [ '```fish', `${item.fishKind} ${item.label} ${item.detail}`, '```', ].join('\n'))], activeSignature: 0, activeParameter: 0, }; } function regexStringSignature() { //const regexItems = stringRegexExpressions; //let signatureDoc = ["__String Regex Patterns__", "---"]; //for (const item of regexItems) { // signatureDoc.push(`${item.label} {item.description}`) //} const signatureDoc = { kind: 'markdown', value: [ markdownStringRepetitions, markdownStringCharClasses, markdownStringGroups, ].join('\n---\n'), }; return { label: 'Regex Patterns', documentation: signatureDoc, }; } function regexStringCharacterSets() { return { label: 'Regex Groups', documentation: { kind: 'markdown', value: markdownStringCharacterSets, }, }; } exports.signatureIndex = { stringRegexPatterns: 0, stringRegexCharacterSets: 1, }; function getDefaultSignatures() { return { activeParameter: 0, activeSignature: 0, signatures: [ regexStringSignature(), regexStringCharacterSets(), ], }; } // REGEX STRING LINES const markdownStringRepetitions = [ 'Repetitions', '-----------', '- __*__ refers to 0 or more repetitions of the previous expression', '- __+__ 1 or more', '- __?__ 0 or 1.', '- __{n}__ to exactly n (where n is a number)', '- __{n,m}__ at least n, no more than m.', '- __{n,}__ n or more', ].join('\n'); const markdownStringCharClasses = [ 'Character Classes', '-----------------', '- __.__ any character except newline', '- __\\d__ a decimal digit and __\\D__, not a decimal digit', '- __\\s__ whitespace and __\\S__, not whitespace', '- __\\w__ a “word” character and __\\W__, a “non-word” character', '- __\\b__ a “word” boundary, and __\\B__, not a word boundary', '- __[...]__ (where “…” is some characters) is a character set', '- __[^...]__ is the inverse of the given character set', '- __[x-y]__ is the range of characters from x-y', '- __[[:xxx:]]__ is a named character set', '- __[[:^xxx:]]__ is the inverse of a named character set', ].join('\n'); const markdownStringCharacterSets = [ '__[[:alnum:]]__ : “alphanumeric”', '__[[:alpha:]]__ : “alphabetic”', '__[[:ascii:]]__ : “0-127”', '__[[:blank:]]__ : “space or tab”', '__[[:cntrl:]]__ : “control character”', '__[[:digit:]]__ : “decimal digit”', '__[[:graph:]]__ : “printing, excluding space”', '__[[:lower:]]__ : “lower case letter”', '__[[:print:]]__ : “printing, including space”', '__[[:punct:]]__ : “printing, excluding alphanumeric”', '__[[:space:]]__ : “white space”', '__[[:upper:]]__ : “upper case letter”', '__[[:word:]]__ : “same as w”', '__[[:xdigit:]]__ : “hexadecimal digit”', ].join('\n'); const markdownStringGroups = [ 'Groups', '------', '- __(...)__ is a capturing group', '- __(?:...)__ is a non-capturing group', '- __\\n__ is a backreference (where n is the number of the group, starting with 1)', '- __$n__ is a reference from the replacement expression to a group in the match expression.', ].join('\n');