diff --git a/NodeApp/src/helpers/AutoCompletionHelper.ts b/NodeApp/src/helpers/AutoCompletionHelper.ts index e3f25347dc05fdd9727513c1e856d53f2e9bfdab..fb3349190cf65480275a8dcdd3371fea1edc2663 100644 --- a/NodeApp/src/helpers/AutoCompletionHelper.ts +++ b/NodeApp/src/helpers/AutoCompletionHelper.ts @@ -79,84 +79,62 @@ import { writeFileSync } from 'fs'; // return 0 // } -interface CmdNode { - readonly name: string; - readonly children: Array<CmdNode>; - readonly parent?: string; +function isLeaf(cmd: Command): boolean { + return cmd.commands.length == 0 } -function createCmdNode(name: string, children: Array<CmdNode>, parent?: string): CmdNode { - return { - name, - children, - parent - }; -} - -function isLeaf(tree: CmdNode): boolean { - return tree.children === undefined || tree.children.length == 0 -} - -function search(tree: CmdNode, cmdName: string): Array<CmdNode> { - if (isLeaf(tree)) { - if (tree.name != cmdName) { +function search(cmd: Command, cmdName: string): Array<Command> { + if (isLeaf(cmd)) { + if (cmd.name() != cmdName) { return [] } else { - return [tree] + return [cmd] } - } else if (tree.name == cmdName) { - return tree.children.flatMap(st => search(st, cmdName)).concat(tree) + } else if (cmd.name() == cmdName) { + return cmd.commands.flatMap(st => search(st, cmdName)).concat(cmd) } else { - return tree.children.flatMap(st => search(st, cmdName)) + return cmd.commands.flatMap(st => search(st, cmdName)) } } -function flatten(tree: CmdNode): Array<CmdNode> { - if (isLeaf(tree)) { - return [tree] +function flatten(cmd: Command): Array<Command> { + if (isLeaf(cmd)) { + return [cmd] } else { - return tree.children + return cmd.commands .map(child => flatten(child)) - .reduce((acc, cmd) => acc.concat(cmd), [tree]) + .reduce((acc, cmd) => acc.concat(cmd), [cmd]) } } -function addWordsGrandParents(cmd: CmdNode): string { +function addWordsGrandParents(cmd: Command): string { let parentWords = "" let ident = 3 - if (cmd.parent !== undefined) { + if (cmd.parent !== null) { parentWords += openCase(ident, 'grand_parent') ident += 1 - parentWords += addLine(ident, `${cmd.parent})`) + parentWords += addLine(ident, `${cmd.parent.name()})`) ident += 1 } - parentWords += addLine(ident, `words="${cmd.children.map(c => c.name).join(" ")} --help -h"`) + parentWords += addLine(ident, `words="${commandsAndOptionsToString(cmd)}"`) ident -= 1 parentWords += addLine(ident, ';;') - if (cmd.parent !== undefined) { + if (cmd.parent !== null) { ident -= 1 parentWords += `${closeCase(ident)}` } return parentWords } -function getOptions(cmd: Command): Array<CmdNode> { +function getOptions(cmd: Command): string { // we remove <args>, [command], and , from option lines return cmd.options.filter(opt => !opt.hidden).map(opt => - createCmdNode(opt.flags.replace(/<.*?>/, '').replace(/\[.*?\]/, '').replace(',', '').trimEnd(), [], cmd.name()) - ) + opt.flags.replace(/<.*?>/, '').replace(/\[.*?\]/, '').replace(',', '').trimEnd() + ).join(" ") } -function getSubCmdNode(cmd: Command, parent: Command): CmdNode { - if (cmd.commands.length > 0) { - return createCmdNode(cmd.name(), cmd.commands.map(subCmd => getSubCmdNode(subCmd, cmd)).concat(getOptions(cmd)), parent.name()) - } else { - return createCmdNode(cmd.name(), getOptions(cmd), parent.name()) - } -} - -function buildCmdNode(root: Command): CmdNode { - return createCmdNode(root.name(), root.commands.map(subCmd => getSubCmdNode(subCmd, root)).concat(getOptions(root))) +function commandsAndOptionsToString(cmd: Command): string { + return cmd.commands.map(c => c.name()).join(" ").concat(' ' + getOptions(cmd)).trim().concat(' --help -h').trim() } function openCase(identLevel: number, pattern: string): string { @@ -174,20 +152,19 @@ function addLine(identLevel: number, pattern: string): string { } export function getBashCompletion(root: Command, filename: string) { - const tree = buildCmdNode(root) - let data = `${addLine(0, '#/usr/bin/env bash\nfunction _dojo_completions()')}` + `${addLine(0, '{')}${addLine(1, 'latest="${COMP_WORDS[$COMP_CWORD]}"')}` + `${addLine(1, 'parent="${COMP_WORDS[$COMP_CWORD - 1]}"')}` + `${addLine(1, 'grand_parent="${COMP_WORDS[$COMP_CWORD - 2]}"')}` - + `${addLine(1, 'words=""')}${openCase(1, "parent")}` - const commands = Array.from(new Set(flatten(tree).filter(cmd => !isLeaf(cmd)).map(cmd => cmd.name))).map(name => search(tree, name)) + + `${addLine(1, 'words=""')}` + + `${openCase(1, "parent")}` + const commands = Array.from(new Set(flatten(root).map(cmd => cmd.name()))).map(name => search(root, name)) for (const cmdNode of commands) { const cmd = cmdNode[0] - data += addLine(2, `${cmd.name})`) + data += addLine(2, `${cmd.name()})`) if (cmd !== undefined && cmdNode.length == 1) { - data += addLine(3, `words="${cmd.children.map(c => c.name).join(" ")} --help -h"`) + data += addLine(3, `words="${commandsAndOptionsToString(cmd)}"`) } else if (cmd !== undefined && cmdNode.length > 1) { cmdNode.forEach(n => data += addWordsGrandParents(n)) }