fish-lsp
Version:
LSP implementation for fish/fish-shell
127 lines (126 loc) • 6.1 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.SetModifiers = exports.SetOptions = void 0;
exports.isSetDefinition = isSetDefinition;
exports.isSetQueryDefinition = isSetQueryDefinition;
exports.isSetVariableDefinitionName = isSetVariableDefinitionName;
exports.findSetChildren = findSetChildren;
exports.setModifierDetailDescriptor = setModifierDetailDescriptor;
exports.processSetCommand = processSetCommand;
const node_types_1 = require("../utils/node-types");
const options_1 = require("./options");
const symbol_1 = require("./symbol");
const definition_scope_1 = require("../utils/definition-scope");
exports.SetOptions = [
options_1.Option.create('-U', '--universal'),
options_1.Option.create('-g', '--global'),
options_1.Option.create('-f', '--function'),
options_1.Option.create('-l', '--local'),
options_1.Option.create('-x', '--export'),
options_1.Option.create('-u', '--unexport'),
options_1.Option.long('--path'),
options_1.Option.long('--unpath'),
options_1.Option.create('-a', '--append'),
options_1.Option.create('-p', '--prepend'),
options_1.Option.create('-e', '--erase'),
options_1.Option.create('-q', '--query'),
options_1.Option.create('-n', '--names'),
options_1.Option.create('-S', '--show'),
options_1.Option.long('--no-event'),
options_1.Option.create('-L', '--long'),
options_1.Option.create('-h', '--help'),
];
exports.SetModifiers = [
options_1.Option.create('-U', '--universal'),
options_1.Option.create('-g', '--global'),
options_1.Option.create('-f', '--function'),
options_1.Option.create('-l', '--local'),
];
function isSetDefinition(node) {
return (0, node_types_1.isCommandWithName)(node, 'set') && !node.children.some(child => (0, options_1.isMatchingOption)(child, options_1.Option.create('-q', '--query')));
}
function isSetQueryDefinition(node) {
return (0, node_types_1.isCommandWithName)(node, 'set') && node.children.some(child => (0, options_1.isMatchingOption)(child, options_1.Option.create('-q', '--query')));
}
function isSetVariableDefinitionName(node, excludeQuery = true) {
if (!node.parent)
return false;
if (excludeQuery && isSetQueryDefinition(node.parent))
return false;
const searchNodes = findSetChildren(node.parent);
const definitionNode = searchNodes.find(n => !(0, node_types_1.isOption)(n));
return !!definitionNode && definitionNode.equals(node);
}
function getFallbackModifierScope(document, node) {
const autoloadType = document.getAutoloadType();
switch (autoloadType) {
case 'conf.d':
case 'config':
case 'functions':
return (0, node_types_1.isTopLevelDefinition)(node) ? 'global' : (0, node_types_1.hasParentFunction)(node) ? 'function' : 'inherit';
case 'completions':
return (0, node_types_1.isTopLevelDefinition)(node) ? 'local' : (0, node_types_1.hasParentFunction)(node) ? 'function' : 'local';
case '':
return 'local';
default:
return 'inherit';
}
}
function findSetChildren(node) {
const children = node.childrenForFieldName('argument');
const firstNonOption = children.findIndex(child => !(0, node_types_1.isOption)(child));
return children.slice(0, firstNonOption + 1);
}
function setModifierDetailDescriptor(node) {
const options = (0, options_1.findOptions)(node.childrenForFieldName('argument'), exports.SetModifiers);
const exportedOption = options.found.find(o => o.option.equalsRawOption('-x', '--export') || o.option.equalsRawOption('-u', '--unexport'));
const exportedStr = exportedOption ? exportedOption.option.isOption('-x', '--export') ? 'exported' : 'unexported' : '';
const modifier = options.found.find(o => o.option.equalsRawOption('-U', '-g', '-f', '-l'));
if (modifier) {
switch (true) {
case modifier.option.isOption('-U', '--universal'):
return ['universally scoped', exportedStr].filter(Boolean).join('; ');
case modifier.option.isOption('-g', '--global'):
return ['globally scoped', exportedStr].filter(Boolean).join('; ');
case modifier.option.isOption('-f', '--function'):
return ['function scoped', exportedStr].filter(Boolean).join('; ');
case modifier.option.isOption('-l', '--local'):
return ['locally scoped', exportedStr].filter(Boolean).join('; ');
default:
return ['', exportedStr].filter(Boolean).join('; ');
}
}
return ['', exportedStr].filter(Boolean).join('; ');
}
function processSetCommand(document, node, children = []) {
if (!isSetDefinition(node))
return [];
const searchNodes = findSetChildren(node);
const definitionNode = searchNodes.find(n => !(0, node_types_1.isOption)(n));
const skipText = ['-', '$', '('];
if (!definitionNode
|| definitionNode.type === 'concatenation'
|| skipText.some(t => definitionNode.text.startsWith(t)))
return [];
const modifierOption = (0, options_1.findOptionsSet)(searchNodes, exports.SetModifiers).pop();
let modifier = 'local';
if (modifierOption) {
modifier = (0, symbol_1.SetModifierToScopeTag)(modifierOption.option);
}
else {
modifier = getFallbackModifierScope(document, node);
}
let parentNode = (0, node_types_1.findParentCommand)(node.parent || node) || node.parent || node;
if (parentNode && (0, node_types_1.isConditionalCommand)(parentNode)) {
while (parentNode && (0, node_types_1.isConditionalCommand)(parentNode)) {
if (parentNode.type === 'function_definition')
break;
if (!parentNode.parent)
break;
parentNode = parentNode.parent;
}
}
return [
symbol_1.FishSymbol.create(definitionNode.text.toString(), node, definitionNode, 'SET', document, document.uri, node.text.toString(), definition_scope_1.DefinitionScope.create(parentNode, modifier), children),
];
}