@oclif/plugin-autocomplete
Advanced tools
Comparing version 2.3.10 to 2.3.11-dev.0
@@ -1,3 +0,1 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const script = `#!/usr/bin/env bash | ||
@@ -81,2 +79,2 @@ | ||
`; | ||
exports.default = script; | ||
export default script; |
@@ -1,3 +0,1 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const script = `#!/usr/bin/env bash | ||
@@ -37,2 +35,2 @@ | ||
`; | ||
exports.default = script; | ||
export default script; |
import { Config } from '@oclif/core'; | ||
export default class PowerShellComp { | ||
protected config: Config; | ||
private topics; | ||
private _coTopics?; | ||
private commands; | ||
private topics; | ||
constructor(config: Config); | ||
generate(): string; | ||
private get coTopics(); | ||
private genCmdHashtable; | ||
private genHashtable; | ||
private getCommands; | ||
private getTopics; | ||
private sanitizeSummary; | ||
generate(): string; | ||
private getTopics; | ||
private getCommands; | ||
} |
@@ -1,8 +0,9 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const tslib_1 = require("tslib"); | ||
const util = tslib_1.__importStar(require("util")); | ||
const os_1 = require("os"); | ||
const ejs = tslib_1.__importStar(require("ejs")); | ||
class PowerShellComp { | ||
import * as ejs from 'ejs'; | ||
import { EOL } from 'node:os'; | ||
import * as util from 'node:util'; | ||
export default class PowerShellComp { | ||
config; | ||
_coTopics; | ||
commands; | ||
topics; | ||
constructor(config) { | ||
@@ -13,107 +14,2 @@ this.config = config; | ||
} | ||
get coTopics() { | ||
if (this._coTopics) | ||
return this._coTopics; | ||
const coTopics = []; | ||
for (const topic of this.topics) { | ||
for (const cmd of this.commands) { | ||
if (topic.name === cmd.id) { | ||
coTopics.push(topic.name); | ||
} | ||
} | ||
} | ||
this._coTopics = coTopics; | ||
return this._coTopics; | ||
} | ||
genCmdHashtable(cmd) { | ||
const flaghHashtables = []; | ||
const flagNames = Object.keys(cmd.flags); | ||
// Add comp for the global `--help` flag. | ||
if (!flagNames.includes('help')) { | ||
flaghHashtables.push(' "help" = @{ "summary" = "Show help for command" }'); | ||
} | ||
if (flagNames.length > 0) { | ||
for (const flagName of flagNames) { | ||
const f = cmd.flags[flagName]; | ||
// skip hidden flags | ||
if (f.hidden) | ||
continue; | ||
const flagSummary = this.sanitizeSummary(f.summary || f.description); | ||
if (f.type === 'option' && f.multiple) { | ||
flaghHashtables.push(` "${f.name}" = @{ | ||
"summary" = "${flagSummary}" | ||
"multiple" = $true | ||
}`); | ||
} | ||
else { | ||
flaghHashtables.push(` "${f.name}" = @{ "summary" = "${flagSummary}" }`); | ||
} | ||
} | ||
} | ||
const cmdHashtable = `@{ | ||
"summary" = "${cmd.summary}" | ||
"flags" = @{ | ||
${flaghHashtables.join('\n')} | ||
} | ||
}`; | ||
return cmdHashtable; | ||
} | ||
genHashtable(key, node, leafTpl) { | ||
if (!leafTpl) { | ||
leafTpl = `"${key}" = @{ | ||
%s | ||
} | ||
`; | ||
} | ||
const nodeKeys = Object.keys(node[key]); | ||
// this is a topic | ||
if (nodeKeys.includes('_summary')) { | ||
let childTpl = `"_summary" = "${node[key]._summary}"\n%s`; | ||
const newKeys = nodeKeys.filter(k => k !== '_summary'); | ||
if (newKeys.length > 0) { | ||
const childNodes = []; | ||
for (const newKey of newKeys) { | ||
childNodes.push(this.genHashtable(newKey, node[key])); | ||
} | ||
childTpl = util.format(childTpl, childNodes.join('\n')); | ||
return util.format(leafTpl, childTpl); | ||
} | ||
// last node | ||
return util.format(leafTpl, childTpl); | ||
} | ||
const childNodes = []; | ||
for (const k of nodeKeys) { | ||
if (k === '_command') { | ||
const cmd = this.commands.find(c => c.id === node[key][k]); | ||
if (!cmd) | ||
throw new Error('no command'); | ||
childNodes.push(util.format('"_command" = %s', this.genCmdHashtable(cmd))); | ||
} | ||
else if (node[key][k]._command) { | ||
const cmd = this.commands.find(c => c.id === node[key][k]._command); | ||
if (!cmd) | ||
throw new Error('no command'); | ||
childNodes.push(util.format(`"${k}" = @{\n"_command" = %s\n}`, this.genCmdHashtable(cmd))); | ||
} | ||
else { | ||
const childTpl = `"summary" = "${node[key][k]._summary}"\n"${k}" = @{ \n %s\n }`; | ||
childNodes.push(this.genHashtable(k, node[key], childTpl)); | ||
} | ||
} | ||
if (childNodes.length >= 1) { | ||
return util.format(leafTpl, childNodes.join('\n')); | ||
} | ||
return leafTpl; | ||
} | ||
sanitizeSummary(summary) { | ||
if (summary === undefined) { | ||
// PowerShell: | ||
// [System.Management.Automation.CompletionResult] will error out if will error out if you pass in an empty string for the summary. | ||
return ' '; | ||
} | ||
return ejs.render(summary, { config: this.config }) | ||
.replace(/"/g, '""') // escape double quotes. | ||
.replace(/`/g, '``') // escape backticks. | ||
.split(os_1.EOL)[0]; // only use the first line | ||
} | ||
generate() { | ||
@@ -126,16 +22,12 @@ const genNode = (partialId) => { | ||
const topicNameSplit = t.name.split(':'); | ||
if (t.name.startsWith(partialId + ':') && | ||
topicNameSplit.length === depth + 1) { | ||
if (t.name.startsWith(partialId + ':') && topicNameSplit.length === depth + 1) { | ||
nextArgs.push(topicNameSplit[depth]); | ||
if (this.coTopics.includes(t.name)) { | ||
node[topicNameSplit[depth]] = { | ||
node[topicNameSplit[depth]] = this.coTopics.includes(t.name) | ||
? { | ||
...genNode(`${partialId}:${topicNameSplit[depth]}`), | ||
}; | ||
} | ||
else { | ||
node[topicNameSplit[depth]] = { | ||
} | ||
: { | ||
_summary: t.description, | ||
...genNode(`${partialId}:${topicNameSplit[depth]}`), | ||
}; | ||
} | ||
} | ||
@@ -161,20 +53,17 @@ } | ||
// Collect top-level topics and generate a cmd tree node for each one of them. | ||
this.topics.forEach(t => { | ||
for (const t of this.topics) { | ||
if (!t.name.includes(':')) { | ||
if (this.coTopics.includes(t.name)) { | ||
commandTree[t.name] = { | ||
commandTree[t.name] = this.coTopics.includes(t.name) | ||
? { | ||
...genNode(t.name), | ||
}; | ||
} | ||
else { | ||
commandTree[t.name] = { | ||
} | ||
: { | ||
_summary: t.description, | ||
...genNode(t.name), | ||
}; | ||
} | ||
topLevelArgs.push(t.name); | ||
} | ||
}); | ||
} | ||
// Collect top-level commands and add a cmd tree node with the command ID. | ||
this.commands.forEach(c => { | ||
for (const c of this.commands) { | ||
if (!c.id.includes(':') && !this.coTopics.includes(c.id)) { | ||
@@ -186,3 +75,3 @@ commandTree[c.id] = { | ||
} | ||
}); | ||
} | ||
const hashtables = []; | ||
@@ -319,51 +208,120 @@ for (const topLevelArg of topLevelArgs) { | ||
} | ||
Register-ArgumentCompleter -Native -CommandName ${this.config.binAliases ? `@(${[...this.config.binAliases, this.config.bin].map(alias => `"${alias}"`).join(',')})` : this.config.bin} -ScriptBlock $scriptblock | ||
Register-ArgumentCompleter -Native -CommandName ${this.config.binAliases | ||
? `@(${[...this.config.binAliases, this.config.bin].map((alias) => `"${alias}"`).join(',')})` | ||
: this.config.bin} -ScriptBlock $scriptblock | ||
`; | ||
return compRegister; | ||
} | ||
getTopics() { | ||
const topics = this.config.topics | ||
.filter((topic) => { | ||
// it is assumed a topic has a child if it has children | ||
const hasChild = this.config.topics.some(subTopic => subTopic.name.includes(`${topic.name}:`)); | ||
return hasChild; | ||
}) | ||
.sort((a, b) => { | ||
if (a.name < b.name) { | ||
return -1; | ||
get coTopics() { | ||
if (this._coTopics) | ||
return this._coTopics; | ||
const coTopics = []; | ||
for (const topic of this.topics) { | ||
for (const cmd of this.commands) { | ||
if (topic.name === cmd.id) { | ||
coTopics.push(topic.name); | ||
} | ||
} | ||
if (a.name > b.name) { | ||
return 1; | ||
} | ||
this._coTopics = coTopics; | ||
return this._coTopics; | ||
} | ||
genCmdHashtable(cmd) { | ||
const flaghHashtables = []; | ||
const flagNames = Object.keys(cmd.flags); | ||
// Add comp for the global `--help` flag. | ||
if (!flagNames.includes('help')) { | ||
flaghHashtables.push(' "help" = @{ "summary" = "Show help for command" }'); | ||
} | ||
if (flagNames.length > 0) { | ||
for (const flagName of flagNames) { | ||
const f = cmd.flags[flagName]; | ||
// skip hidden flags | ||
if (f.hidden) | ||
continue; | ||
const flagSummary = this.sanitizeSummary(f.summary ?? f.description); | ||
if (f.type === 'option' && f.multiple) { | ||
flaghHashtables.push(` "${f.name}" = @{ | ||
"summary" = "${flagSummary}" | ||
"multiple" = $true | ||
}`); | ||
} | ||
else { | ||
flaghHashtables.push(` "${f.name}" = @{ "summary" = "${flagSummary}" }`); | ||
} | ||
} | ||
return 0; | ||
}) | ||
.map(t => { | ||
const description = t.description ? | ||
this.sanitizeSummary(t.description) : | ||
`${t.name.replace(/:/g, ' ')} commands`; | ||
return { | ||
name: t.name, | ||
description, | ||
}; | ||
}); | ||
return topics; | ||
} | ||
const cmdHashtable = `@{ | ||
"summary" = "${cmd.summary}" | ||
"flags" = @{ | ||
${flaghHashtables.join('\n')} | ||
} | ||
}`; | ||
return cmdHashtable; | ||
} | ||
genHashtable(key, node, leafTpl) { | ||
if (!leafTpl) { | ||
leafTpl = `"${key}" = @{ | ||
%s | ||
} | ||
`; | ||
} | ||
const nodeKeys = Object.keys(node[key]); | ||
// this is a topic | ||
if (nodeKeys.includes('_summary')) { | ||
let childTpl = `"_summary" = "${node[key]._summary}"\n%s`; | ||
const newKeys = nodeKeys.filter((k) => k !== '_summary'); | ||
if (newKeys.length > 0) { | ||
const childNodes = []; | ||
for (const newKey of newKeys) { | ||
childNodes.push(this.genHashtable(newKey, node[key])); | ||
} | ||
childTpl = util.format(childTpl, childNodes.join('\n')); | ||
return util.format(leafTpl, childTpl); | ||
} | ||
// last node | ||
return util.format(leafTpl, childTpl); | ||
} | ||
const childNodes = []; | ||
for (const k of nodeKeys) { | ||
if (k === '_command') { | ||
const cmd = this.commands.find((c) => c.id === node[key][k]); | ||
if (!cmd) | ||
throw new Error('no command'); | ||
childNodes.push(util.format('"_command" = %s', this.genCmdHashtable(cmd))); | ||
} | ||
else if (node[key][k]._command) { | ||
const cmd = this.commands.find((c) => c.id === node[key][k]._command); | ||
if (!cmd) | ||
throw new Error('no command'); | ||
childNodes.push(util.format(`"${k}" = @{\n"_command" = %s\n}`, this.genCmdHashtable(cmd))); | ||
} | ||
else { | ||
const childTpl = `"summary" = "${node[key][k]._summary}"\n"${k}" = @{ \n %s\n }`; | ||
childNodes.push(this.genHashtable(k, node[key], childTpl)); | ||
} | ||
} | ||
if (childNodes.length > 0) { | ||
return util.format(leafTpl, childNodes.join('\n')); | ||
} | ||
return leafTpl; | ||
} | ||
getCommands() { | ||
const cmds = []; | ||
this.config.plugins.forEach(p => { | ||
p.commands.forEach(c => { | ||
for (const p of this.config.getPluginsList()) { | ||
for (const c of p.commands) { | ||
if (c.hidden) | ||
return; | ||
continue; | ||
const summary = this.sanitizeSummary(c.summary || c.description); | ||
const flags = c.flags; | ||
const { flags } = c; | ||
cmds.push({ | ||
flags, | ||
id: c.id, | ||
summary, | ||
flags, | ||
}); | ||
c.aliases.forEach(a => { | ||
for (const a of c.aliases) { | ||
cmds.push({ | ||
flags, | ||
id: a, | ||
summary, | ||
flags, | ||
}); | ||
@@ -378,6 +336,6 @@ const split = a.split(':'); | ||
for (let i = 0; i < split.length - 1; i++) { | ||
if (!this.topics.find(t => t.name === topic)) { | ||
if (!this.topics.some((t) => t.name === topic)) { | ||
this.topics.push({ | ||
description: `${topic.replaceAll(':', ' ')} commands`, | ||
name: topic, | ||
description: `${topic.replace(/:/g, ' ')} commands`, | ||
}); | ||
@@ -387,8 +345,46 @@ } | ||
} | ||
}); | ||
}); | ||
}); | ||
} | ||
} | ||
} | ||
return cmds; | ||
} | ||
getTopics() { | ||
const topics = this.config.topics | ||
.filter((topic) => { | ||
// it is assumed a topic has a child if it has children | ||
const hasChild = this.config.topics.some((subTopic) => subTopic.name.includes(`${topic.name}:`)); | ||
return hasChild; | ||
}) | ||
.sort((a, b) => { | ||
if (a.name < b.name) { | ||
return -1; | ||
} | ||
if (a.name > b.name) { | ||
return 1; | ||
} | ||
return 0; | ||
}) | ||
.map((t) => { | ||
const description = t.description | ||
? this.sanitizeSummary(t.description) | ||
: `${t.name.replaceAll(':', ' ')} commands`; | ||
return { | ||
description, | ||
name: t.name, | ||
}; | ||
}); | ||
return topics; | ||
} | ||
sanitizeSummary(summary) { | ||
if (summary === undefined) { | ||
// PowerShell: | ||
// [System.Management.Automation.CompletionResult] will error out if will error out if you pass in an empty string for the summary. | ||
return ' '; | ||
} | ||
return ejs | ||
.render(summary, { config: this.config }) | ||
.replaceAll('"', '""') // escape double quotes. | ||
.replaceAll('`', '``') // escape backticks. | ||
.split(EOL)[0]; // only use the first line | ||
} | ||
} | ||
exports.default = PowerShellComp; |
import { Config } from '@oclif/core'; | ||
export default class ZshCompWithSpaces { | ||
protected config: Config; | ||
private _coTopics?; | ||
private commands; | ||
private topics; | ||
private commands; | ||
private _coTopics?; | ||
constructor(config: Config); | ||
private sanitizeSummary; | ||
generate(): string; | ||
private get coTopics(); | ||
private genZshFlagArgumentsBlock; | ||
private genZshTopicCompFun; | ||
private genZshValuesBlock; | ||
private genZshTopicCompFun; | ||
private get coTopics(); | ||
private getCommands; | ||
private getTopics; | ||
private getCommands; | ||
private sanitizeSummary; | ||
} |
@@ -1,8 +0,9 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const tslib_1 = require("tslib"); | ||
const util = tslib_1.__importStar(require("util")); | ||
const ejs = tslib_1.__importStar(require("ejs")); | ||
import * as ejs from 'ejs'; | ||
import * as util from 'node:util'; | ||
const argTemplate = ' "%s")\n %s\n ;;\n'; | ||
class ZshCompWithSpaces { | ||
export default class ZshCompWithSpaces { | ||
config; | ||
_coTopics; | ||
commands; | ||
topics; | ||
constructor(config) { | ||
@@ -13,16 +14,5 @@ this.config = config; | ||
} | ||
sanitizeSummary(summary) { | ||
if (summary === undefined) { | ||
return ''; | ||
} | ||
return ejs.render(summary, { config: this.config }) | ||
.replace(/([`"])/g, '\\\\\\$1') // backticks and double-quotes require triple-backslashes | ||
// eslint-disable-next-line no-useless-escape | ||
.replace(/([\[\]])/g, '\\\\$1') // square brackets require double-backslashes | ||
.split('\n')[0]; // only use the first line | ||
} | ||
generate() { | ||
var _a, _b; | ||
const firstArgs = []; | ||
this.topics.forEach(t => { | ||
for (const t of this.topics) { | ||
if (!t.name.includes(':')) | ||
@@ -33,5 +23,5 @@ firstArgs.push({ | ||
}); | ||
}); | ||
this.commands.forEach(c => { | ||
if (!firstArgs.find(a => a.id === c.id) && !c.id.includes(':')) | ||
} | ||
for (const c of this.commands) { | ||
if (!firstArgs.some((a) => a.id === c.id) && !c.id.includes(':')) | ||
firstArgs.push({ | ||
@@ -41,3 +31,3 @@ id: c.id, | ||
}); | ||
}); | ||
} | ||
const mainArgsCaseBlock = () => { | ||
@@ -51,3 +41,3 @@ let caseBlock = 'case $line[1] in\n'; | ||
else { | ||
const cmd = this.commands.find(c => c.id === arg.id); | ||
const cmd = this.commands.find((c) => c.id === arg.id); | ||
if (cmd) { | ||
@@ -70,5 +60,5 @@ // if it's a command and has flags, inline flag completion statement. | ||
return `#compdef ${this.config.bin} | ||
${(_b = (_a = this.config.binAliases) === null || _a === void 0 ? void 0 : _a.map(a => `compdef ${a}=${this.config.bin}`).join('\n')) !== null && _b !== void 0 ? _b : ''} | ||
${this.config.binAliases?.map((a) => `compdef ${a}=${this.config.bin}`).join('\n') ?? ''} | ||
${this.topics.map(t => this.genZshTopicCompFun(t.name)).join('\n')} | ||
${this.topics.map((t) => this.genZshTopicCompFun(t.name)).join('\n')} | ||
@@ -94,4 +84,17 @@ _${this.config.bin}() { | ||
} | ||
get coTopics() { | ||
if (this._coTopics) | ||
return this._coTopics; | ||
const coTopics = []; | ||
for (const topic of this.topics) { | ||
for (const cmd of this.commands) { | ||
if (topic.name === cmd.id) { | ||
coTopics.push(topic.name); | ||
} | ||
} | ||
} | ||
this._coTopics = coTopics; | ||
return this._coTopics; | ||
} | ||
genZshFlagArgumentsBlock(flags) { | ||
var _a; | ||
// if a command doesn't have flags make it only complete files | ||
@@ -116,2 +119,3 @@ // also add comp for the global `--help` flag. | ||
if (f.char) { | ||
// eslint-disable-next-line unicorn/prefer-ternary | ||
if (f.multiple) { | ||
@@ -125,8 +129,3 @@ // this flag can be present multiple times on the line | ||
flagSpec += `"[${flagSummary}]`; | ||
if (f.options) { | ||
flagSpec += `:${f.name} options:(${(_a = f.options) === null || _a === void 0 ? void 0 : _a.join(' ')})"`; | ||
} | ||
else { | ||
flagSpec += ':file:_files"'; | ||
} | ||
flagSpec += f.options ? `:${f.name} options:(${f.options?.join(' ')})"` : ':file:_files"'; | ||
} | ||
@@ -139,8 +138,3 @@ else { | ||
flagSpec += `--${f.name}"[${flagSummary}]:`; | ||
if (f.options) { | ||
flagSpec += `${f.name} options:(${f.options.join(' ')})"`; | ||
} | ||
else { | ||
flagSpec += 'file:_files"'; | ||
} | ||
flagSpec += f.options ? `${f.name} options:(${f.options.join(' ')})"` : 'file:_files"'; | ||
} | ||
@@ -165,11 +159,3 @@ } | ||
} | ||
genZshValuesBlock(subArgs) { | ||
let valuesBlock = '_values "completions" \\\n'; | ||
subArgs.forEach(subArg => { | ||
valuesBlock += `"${subArg.id}[${subArg.summary}]" \\\n`; | ||
}); | ||
return valuesBlock; | ||
} | ||
genZshTopicCompFun(id) { | ||
var _a; | ||
const coTopics = []; | ||
@@ -184,3 +170,3 @@ for (const topic of this.topics) { | ||
const flagArgsTemplate = ' "%s")\n %s\n ;;\n'; | ||
const underscoreSepId = id.replace(/:/g, '_'); | ||
const underscoreSepId = id.replaceAll(':', '_'); | ||
const depth = id.split(':').length; | ||
@@ -195,3 +181,3 @@ const isCotopic = coTopics.includes(id); | ||
${this.genZshFlagArgumentsBlock((_a = this.commands.find(c => c.id === id)) === null || _a === void 0 ? void 0 : _a.flags)} | ||
${this.genZshFlagArgumentsBlock(this.commands.find((c) => c.id === id)?.flags)} | ||
} | ||
@@ -225,5 +211,3 @@ | ||
let argsBlock = ''; | ||
this.topics | ||
.filter(t => t.name.startsWith(id + ':') && t.name.split(':').length === depth + 1) | ||
.forEach(t => { | ||
for (const t of this.topics.filter((t) => t.name.startsWith(id + ':') && t.name.split(':').length === depth + 1)) { | ||
const subArg = t.name.split(':')[depth]; | ||
@@ -235,8 +219,6 @@ subArgs.push({ | ||
argsBlock += util.format(argTemplate, subArg, `_${this.config.bin}_${underscoreSepId}_${subArg}`); | ||
}); | ||
this.commands | ||
.filter(c => c.id.startsWith(id + ':') && c.id.split(':').length === depth + 1) | ||
.forEach(c => { | ||
} | ||
for (const c of this.commands.filter((c) => c.id.startsWith(id + ':') && c.id.split(':').length === depth + 1)) { | ||
if (coTopics.includes(c.id)) | ||
return; | ||
continue; | ||
const subArg = c.id.split(':')[depth]; | ||
@@ -248,3 +230,3 @@ subArgs.push({ | ||
argsBlock += util.format(flagArgsTemplate, subArg, this.genZshFlagArgumentsBlock(c.flags)); | ||
}); | ||
} | ||
return util.format(coTopicCompFunc, this.genZshValuesBlock(subArgs), argsBlock); | ||
@@ -254,5 +236,3 @@ } | ||
const subArgs = []; | ||
this.topics | ||
.filter(t => t.name.startsWith(id + ':') && t.name.split(':').length === depth + 1) | ||
.forEach(t => { | ||
for (const t of this.topics.filter((t) => t.name.startsWith(id + ':') && t.name.split(':').length === depth + 1)) { | ||
const subArg = t.name.split(':')[depth]; | ||
@@ -264,8 +244,6 @@ subArgs.push({ | ||
argsBlock += util.format(argTemplate, subArg, `_${this.config.bin}_${underscoreSepId}_${subArg}`); | ||
}); | ||
this.commands | ||
.filter(c => c.id.startsWith(id + ':') && c.id.split(':').length === depth + 1) | ||
.forEach(c => { | ||
} | ||
for (const c of this.commands.filter((c) => c.id.startsWith(id + ':') && c.id.split(':').length === depth + 1)) { | ||
if (coTopics.includes(c.id)) | ||
return; | ||
continue; | ||
const subArg = c.id.split(':')[depth]; | ||
@@ -277,3 +255,3 @@ subArgs.push({ | ||
argsBlock += util.format(flagArgsTemplate, subArg, this.genZshFlagArgumentsBlock(c.flags)); | ||
}); | ||
} | ||
const topicCompFunc = `_${this.config.bin}_${underscoreSepId}() { | ||
@@ -299,58 +277,27 @@ local context state state_descr line | ||
} | ||
get coTopics() { | ||
if (this._coTopics) | ||
return this._coTopics; | ||
const coTopics = []; | ||
for (const topic of this.topics) { | ||
for (const cmd of this.commands) { | ||
if (topic.name === cmd.id) { | ||
coTopics.push(topic.name); | ||
} | ||
} | ||
genZshValuesBlock(subArgs) { | ||
let valuesBlock = '_values "completions" \\\n'; | ||
for (const subArg of subArgs) { | ||
valuesBlock += `"${subArg.id}[${subArg.summary}]" \\\n`; | ||
} | ||
this._coTopics = coTopics; | ||
return this._coTopics; | ||
return valuesBlock; | ||
} | ||
getTopics() { | ||
const topics = this.config.topics.filter((topic) => { | ||
// it is assumed a topic has a child if it has children | ||
const hasChild = this.config.topics.some(subTopic => subTopic.name.includes(`${topic.name}:`)); | ||
return hasChild; | ||
}) | ||
.sort((a, b) => { | ||
if (a.name < b.name) { | ||
return -1; | ||
} | ||
if (a.name > b.name) { | ||
return 1; | ||
} | ||
return 0; | ||
}) | ||
.map(t => { | ||
const description = t.description ? this.sanitizeSummary(t.description) : `${t.name.replace(/:/g, ' ')} commands`; | ||
return { | ||
name: t.name, | ||
description, | ||
}; | ||
}); | ||
return topics; | ||
} | ||
getCommands() { | ||
const cmds = []; | ||
this.config.plugins.forEach(p => { | ||
p.commands.forEach(c => { | ||
for (const p of this.config.getPluginsList()) { | ||
for (const c of p.commands) { | ||
if (c.hidden) | ||
return; | ||
continue; | ||
const summary = this.sanitizeSummary(c.summary || c.description); | ||
const flags = c.flags; | ||
const { flags } = c; | ||
cmds.push({ | ||
flags, | ||
id: c.id, | ||
summary, | ||
flags, | ||
}); | ||
c.aliases.forEach(a => { | ||
for (const a of c.aliases) { | ||
cmds.push({ | ||
flags, | ||
id: a, | ||
summary, | ||
flags, | ||
}); | ||
@@ -365,6 +312,6 @@ const split = a.split(':'); | ||
for (let i = 0; i < split.length - 1; i++) { | ||
if (!this.topics.find(t => t.name === topic)) { | ||
if (!this.topics.some((t) => t.name === topic)) { | ||
this.topics.push({ | ||
description: `${topic.replaceAll(':', ' ')} commands`, | ||
name: topic, | ||
description: `${topic.replace(/:/g, ' ')} commands`, | ||
}); | ||
@@ -374,8 +321,44 @@ } | ||
} | ||
}); | ||
}); | ||
}); | ||
} | ||
} | ||
} | ||
return cmds; | ||
} | ||
getTopics() { | ||
const topics = this.config.topics | ||
.filter((topic) => { | ||
// it is assumed a topic has a child if it has children | ||
const hasChild = this.config.topics.some((subTopic) => subTopic.name.includes(`${topic.name}:`)); | ||
return hasChild; | ||
}) | ||
.sort((a, b) => { | ||
if (a.name < b.name) { | ||
return -1; | ||
} | ||
if (a.name > b.name) { | ||
return 1; | ||
} | ||
return 0; | ||
}) | ||
.map((t) => { | ||
const description = t.description | ||
? this.sanitizeSummary(t.description) | ||
: `${t.name.replaceAll(':', ' ')} commands`; | ||
return { | ||
description, | ||
name: t.name, | ||
}; | ||
}); | ||
return topics; | ||
} | ||
sanitizeSummary(summary) { | ||
if (summary === undefined) { | ||
return ''; | ||
} | ||
return ejs | ||
.render(summary, { config: this.config }) | ||
.replaceAll(/(["`])/g, '\\\\\\$1') // backticks and double-quotes require triple-backslashes | ||
.replaceAll(/([[\]])/g, '\\\\$1') // square brackets require double-backslashes | ||
.split('\n')[0]; // only use the first line | ||
} | ||
} | ||
exports.default = ZshCompWithSpaces; |
import { Command } from '@oclif/core'; | ||
export declare abstract class AutocompleteBase extends Command { | ||
get acLogfilePath(): string; | ||
get autocompleteCacheDir(): string; | ||
get cliBin(): string; | ||
get cliBinEnvVar(): string; | ||
determineShell(shell: string): string; | ||
get autocompleteCacheDir(): string; | ||
get acLogfilePath(): string; | ||
writeLogFile(msg: string): void; | ||
private isBashOnWindows; | ||
} |
@@ -1,9 +0,11 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.AutocompleteBase = void 0; | ||
const tslib_1 = require("tslib"); | ||
const core_1 = require("@oclif/core"); | ||
const fs_1 = require("fs"); | ||
const path = tslib_1.__importStar(require("path")); | ||
class AutocompleteBase extends core_1.Command { | ||
import { Command } from '@oclif/core'; | ||
import { mkdirSync, openSync, writeSync } from 'node:fs'; | ||
import * as path from 'node:path'; | ||
export class AutocompleteBase extends Command { | ||
get acLogfilePath() { | ||
return path.join(this.config.cacheDir, 'autocomplete.log'); | ||
} | ||
get autocompleteCacheDir() { | ||
return path.join(this.config.cacheDir, 'autocomplete'); | ||
} | ||
get cliBin() { | ||
@@ -13,3 +15,3 @@ return this.config.bin; | ||
get cliBinEnvVar() { | ||
return this.config.bin.toUpperCase().replace(/-/g, '_'); | ||
return this.config.bin.toUpperCase().replaceAll('-', '_'); | ||
} | ||
@@ -27,13 +29,7 @@ determineShell(shell) { | ||
} | ||
get autocompleteCacheDir() { | ||
return path.join(this.config.cacheDir, 'autocomplete'); | ||
} | ||
get acLogfilePath() { | ||
return path.join(this.config.cacheDir, 'autocomplete.log'); | ||
} | ||
writeLogFile(msg) { | ||
(0, fs_1.mkdirSync)(this.config.cacheDir, { recursive: true }); | ||
const entry = `[${(new Date()).toISOString()}] ${msg}\n`; | ||
const fd = (0, fs_1.openSync)(this.acLogfilePath, 'a'); | ||
(0, fs_1.writeSync)(fd, entry); | ||
mkdirSync(this.config.cacheDir, { recursive: true }); | ||
const entry = `[${new Date().toISOString()}] ${msg}\n`; | ||
const fd = openSync(this.acLogfilePath, 'a'); | ||
writeSync(fd, entry); | ||
} | ||
@@ -44,2 +40,1 @@ isBashOnWindows(shell) { | ||
} | ||
exports.AutocompleteBase = AutocompleteBase; |
@@ -1,27 +0,27 @@ | ||
import { AutocompleteBase } from '../../base'; | ||
import { AutocompleteBase } from '../../base.js'; | ||
export default class Create extends AutocompleteBase { | ||
static description: string; | ||
static hidden: boolean; | ||
static description: string; | ||
private _commands?; | ||
run(): Promise<void>; | ||
private ensureDirs; | ||
private createFiles; | ||
private get bashSetupScriptPath(); | ||
private get zshSetupScriptPath(); | ||
private get pwshFunctionsDir(); | ||
private get bashCommandsWithFlagsList(); | ||
private get bashCompletionFunction(); | ||
private get bashCompletionFunctionPath(); | ||
private get bashFunctionsDir(); | ||
private get zshFunctionsDir(); | ||
private get pwshCompletionFunctionPath(); | ||
private get bashCompletionFunctionPath(); | ||
private get zshCompletionFunctionPath(); | ||
private get bashSetupScript(); | ||
private get zshSetupScript(); | ||
private get bashSetupScriptPath(); | ||
private get commands(); | ||
private genZshFlagSpecs; | ||
private createFiles; | ||
private ensureDirs; | ||
private get genAllCommandsMetaString(); | ||
private get genCaseStatementForFlagsMetaString(); | ||
private genCmdPublicFlags; | ||
private get bashCommandsWithFlagsList(); | ||
private get bashCompletionFunction(); | ||
private genZshFlagSpecs; | ||
private get pwshCompletionFunctionPath(); | ||
private get pwshFunctionsDir(); | ||
private get zshCompletionFunction(); | ||
private get zshCompletionFunctionPath(); | ||
private get zshFunctionsDir(); | ||
private get zshSetupScript(); | ||
private get zshSetupScriptPath(); | ||
} |
@@ -1,12 +0,10 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const tslib_1 = require("tslib"); | ||
const path = tslib_1.__importStar(require("path")); | ||
const promises_1 = require("fs/promises"); | ||
const bash_1 = tslib_1.__importDefault(require("../../autocomplete/bash")); | ||
const zsh_1 = tslib_1.__importDefault(require("../../autocomplete/zsh")); | ||
const powershell_1 = tslib_1.__importDefault(require("../../autocomplete/powershell")); | ||
const bash_spaces_1 = tslib_1.__importDefault(require("../../autocomplete/bash-spaces")); | ||
const base_1 = require("../../base"); | ||
const debug = require('debug')('autocomplete:create'); | ||
import makeDebug from 'debug'; | ||
import { mkdir, writeFile } from 'node:fs/promises'; | ||
import * as path from 'node:path'; | ||
import bashAutocomplete from '../../autocomplete/bash.js'; | ||
import bashAutocompleteWithSpaces from '../../autocomplete/bash-spaces.js'; | ||
import PowerShellComp from '../../autocomplete/powershell.js'; | ||
import ZshCompWithSpaces from '../../autocomplete/zsh.js'; | ||
import { AutocompleteBase } from '../../base.js'; | ||
const debug = makeDebug('autocomplete:create'); | ||
function sanitizeDescription(description) { | ||
@@ -17,8 +15,10 @@ if (description === undefined) { | ||
return description | ||
.replace(/([`"])/g, '\\\\\\$1') // backticks and double-quotes require triple-backslashes | ||
// eslint-disable-next-line no-useless-escape | ||
.replace(/([\[\]])/g, '\\\\$1') // square brackets require double-backslashes | ||
.replaceAll(/(["`])/g, '\\\\\\$1') // backticks and double-quotes require triple-backslashes | ||
.replaceAll(/([[\]])/g, '\\\\$1') // square brackets require double-backslashes | ||
.split('\n')[0]; // only use the first line | ||
} | ||
class Create extends base_1.AutocompleteBase { | ||
export default class Create extends AutocompleteBase { | ||
static description = 'create autocomplete setup scripts and completion functions'; | ||
static hidden = true; | ||
_commands; | ||
async run() { | ||
@@ -30,37 +30,26 @@ // 1. ensure needed dirs | ||
} | ||
async ensureDirs() { | ||
// ensure autocomplete cache dir before doing the children | ||
await (0, promises_1.mkdir)(this.autocompleteCacheDir, { recursive: true }); | ||
await Promise.all([ | ||
(0, promises_1.mkdir)(this.bashFunctionsDir, { recursive: true }), | ||
(0, promises_1.mkdir)(this.zshFunctionsDir, { recursive: true }), | ||
(0, promises_1.mkdir)(this.pwshFunctionsDir, { recursive: true }), | ||
]); | ||
get bashCommandsWithFlagsList() { | ||
return this.commands | ||
.map((c) => { | ||
const publicFlags = this.genCmdPublicFlags(c).trim(); | ||
return `${c.id} ${publicFlags}`; | ||
}) | ||
.join('\n'); | ||
} | ||
async createFiles() { | ||
// zsh | ||
get bashCompletionFunction() { | ||
const { cliBin } = this; | ||
const supportSpaces = this.config.topicSeparator === ' '; | ||
await Promise.all([ | ||
(0, promises_1.writeFile)(this.bashSetupScriptPath, this.bashSetupScript), | ||
(0, promises_1.writeFile)(this.bashCompletionFunctionPath, this.bashCompletionFunction), | ||
(0, promises_1.writeFile)(this.zshSetupScriptPath, this.zshSetupScript), | ||
].concat(process.env.OCLIF_AUTOCOMPLETE_TOPIC_SEPARATOR === 'colon' || !supportSpaces ? [ | ||
(0, promises_1.writeFile)(this.zshCompletionFunctionPath, this.zshCompletionFunction), | ||
] : [ | ||
(0, promises_1.writeFile)(this.zshCompletionFunctionPath, new zsh_1.default(this.config).generate()), | ||
(0, promises_1.writeFile)(this.pwshCompletionFunctionPath, new powershell_1.default(this.config).generate()), | ||
])); | ||
const bashScript = process.env.OCLIF_AUTOCOMPLETE_TOPIC_SEPARATOR === 'colon' || !supportSpaces | ||
? bashAutocomplete | ||
: bashAutocompleteWithSpaces; | ||
return (bashScript | ||
// eslint-disable-next-line unicorn/prefer-spread | ||
.concat(...(this.config.binAliases?.map((alias) => `complete -F _<CLI_BIN>_autocomplete ${alias}`).join('\n') ?? [])) | ||
.replaceAll('<CLI_BIN>', cliBin) | ||
.replaceAll('<BASH_COMMANDS_WITH_FLAGS_LIST>', this.bashCommandsWithFlagsList)); | ||
} | ||
get bashSetupScriptPath() { | ||
// <cachedir>/autocomplete/bash_setup | ||
return path.join(this.autocompleteCacheDir, 'bash_setup'); | ||
get bashCompletionFunctionPath() { | ||
// <cachedir>/autocomplete/functions/bash/<bin>.bash | ||
return path.join(this.bashFunctionsDir, `${this.cliBin}.bash`); | ||
} | ||
get zshSetupScriptPath() { | ||
// <cachedir>/autocomplete/zsh_setup | ||
return path.join(this.autocompleteCacheDir, 'zsh_setup'); | ||
} | ||
get pwshFunctionsDir() { | ||
// <cachedir>/autocomplete/functions/powershell | ||
return path.join(this.autocompleteCacheDir, 'functions', 'powershell'); | ||
} | ||
get bashFunctionsDir() { | ||
@@ -70,18 +59,2 @@ // <cachedir>/autocomplete/functions/bash | ||
} | ||
get zshFunctionsDir() { | ||
// <cachedir>/autocomplete/functions/zsh | ||
return path.join(this.autocompleteCacheDir, 'functions', 'zsh'); | ||
} | ||
get pwshCompletionFunctionPath() { | ||
// <cachedir>/autocomplete/functions/powershell/<bin>.ps1 | ||
return path.join(this.pwshFunctionsDir, `${this.cliBin}.ps1`); | ||
} | ||
get bashCompletionFunctionPath() { | ||
// <cachedir>/autocomplete/functions/bash/<bin>.bash | ||
return path.join(this.bashFunctionsDir, `${this.cliBin}.bash`); | ||
} | ||
get zshCompletionFunctionPath() { | ||
// <cachedir>/autocomplete/functions/zsh/_<bin> | ||
return path.join(this.zshFunctionsDir, `_${this.cliBin}`); | ||
} | ||
get bashSetupScript() { | ||
@@ -94,10 +67,5 @@ const setup = path.join(this.bashFunctionsDir, `${this.cliBin}.bash`); | ||
} | ||
get zshSetupScript() { | ||
return ` | ||
fpath=( | ||
${this.zshFunctionsDir} | ||
$fpath | ||
); | ||
autoload -Uz compinit; | ||
compinit;\n`; | ||
get bashSetupScriptPath() { | ||
// <cachedir>/autocomplete/bash_setup | ||
return path.join(this.autocompleteCacheDir, 'bash_setup'); | ||
} | ||
@@ -107,23 +75,22 @@ get commands() { | ||
return this._commands; | ||
const plugins = this.config.plugins; | ||
const cmds = []; | ||
plugins.forEach(p => { | ||
p.commands.forEach(c => { | ||
for (const p of this.config.getPluginsList()) { | ||
for (const c of p.commands) { | ||
try { | ||
if (c.hidden) | ||
return; | ||
continue; | ||
const description = sanitizeDescription(c.summary || c.description || ''); | ||
const flags = c.flags; | ||
const { flags } = c; | ||
cmds.push({ | ||
id: c.id, | ||
description, | ||
flags, | ||
id: c.id, | ||
}); | ||
c.aliases.forEach(a => { | ||
for (const a of c.aliases) { | ||
cmds.push({ | ||
id: a, | ||
description, | ||
flags, | ||
id: a, | ||
}); | ||
}); | ||
} | ||
} | ||
@@ -135,29 +102,35 @@ catch (error) { | ||
} | ||
}); | ||
}); | ||
} | ||
} | ||
this._commands = cmds; | ||
return this._commands; | ||
} | ||
genZshFlagSpecs(Klass) { | ||
return Object.keys(Klass.flags || {}) | ||
.filter(flag => Klass.flags && !Klass.flags[flag].hidden) | ||
.map(flag => { | ||
const f = (Klass.flags && Klass.flags[flag]) || { description: '' }; | ||
const isBoolean = f.type === 'boolean'; | ||
const isOption = f.type === 'option'; | ||
const name = isBoolean ? flag : `${flag}=-`; | ||
const multiple = isOption && f.multiple ? '*' : ''; | ||
const valueCmpl = isBoolean ? '' : ':'; | ||
const completion = `${multiple}--${name}[${sanitizeDescription(f.summary || f.description)}]${valueCmpl}`; | ||
return `"${completion}"`; | ||
}) | ||
.join('\n'); | ||
async createFiles() { | ||
// zsh | ||
const supportSpaces = this.config.topicSeparator === ' '; | ||
await Promise.all([ | ||
writeFile(this.bashSetupScriptPath, this.bashSetupScript), | ||
writeFile(this.bashCompletionFunctionPath, this.bashCompletionFunction), | ||
writeFile(this.zshSetupScriptPath, this.zshSetupScript), | ||
// eslint-disable-next-line unicorn/prefer-spread | ||
].concat(process.env.OCLIF_AUTOCOMPLETE_TOPIC_SEPARATOR === 'colon' || !supportSpaces | ||
? [writeFile(this.zshCompletionFunctionPath, this.zshCompletionFunction)] | ||
: [ | ||
writeFile(this.zshCompletionFunctionPath, new ZshCompWithSpaces(this.config).generate()), | ||
writeFile(this.pwshCompletionFunctionPath, new PowerShellComp(this.config).generate()), | ||
])); | ||
} | ||
async ensureDirs() { | ||
// ensure autocomplete cache dir before doing the children | ||
await mkdir(this.autocompleteCacheDir, { recursive: true }); | ||
await Promise.all([ | ||
mkdir(this.bashFunctionsDir, { recursive: true }), | ||
mkdir(this.zshFunctionsDir, { recursive: true }), | ||
mkdir(this.pwshFunctionsDir, { recursive: true }), | ||
]); | ||
} | ||
/* eslint-disable no-useless-escape */ | ||
get genAllCommandsMetaString() { | ||
return this.commands.map(c => { | ||
return `\"${c.id.replace(/:/g, '\\:')}:${c.description}\"`; | ||
}).join('\n'); | ||
return this.commands.map((c) => `\"${c.id.replaceAll(':', '\\:')}:${c.description}\"`).join('\n'); | ||
} | ||
/* eslint-enable no-useless-escape */ | ||
get genCaseStatementForFlagsMetaString() { | ||
@@ -170,9 +143,9 @@ // command) | ||
// ;; | ||
return this.commands.map(c => { | ||
return `${c.id}) | ||
return this.commands | ||
.map((c) => `${c.id}) | ||
_command_flags=( | ||
${this.genZshFlagSpecs(c)} | ||
) | ||
;;\n`; | ||
}).join('\n'); | ||
;;\n`) | ||
.join('\n'); | ||
} | ||
@@ -182,24 +155,32 @@ genCmdPublicFlags(Command) { | ||
return Object.keys(Flags) | ||
.filter(flag => !Flags[flag].hidden) | ||
.map(flag => `--${flag}`) | ||
.filter((flag) => !Flags[flag].hidden) | ||
.map((flag) => `--${flag}`) | ||
.join(' '); | ||
} | ||
get bashCommandsWithFlagsList() { | ||
return this.commands.map(c => { | ||
const publicFlags = this.genCmdPublicFlags(c).trim(); | ||
return `${c.id} ${publicFlags}`; | ||
}).join('\n'); | ||
genZshFlagSpecs(Klass) { | ||
return Object.keys(Klass.flags || {}) | ||
.filter((flag) => Klass.flags && !Klass.flags[flag].hidden) | ||
.map((flag) => { | ||
const f = (Klass.flags && Klass.flags[flag]) || { description: '' }; | ||
const isBoolean = f.type === 'boolean'; | ||
const isOption = f.type === 'option'; | ||
const name = isBoolean ? flag : `${flag}=-`; | ||
const multiple = isOption && f.multiple ? '*' : ''; | ||
const valueCmpl = isBoolean ? '' : ':'; | ||
const completion = `${multiple}--${name}[${sanitizeDescription(f.summary || f.description)}]${valueCmpl}`; | ||
return `"${completion}"`; | ||
}) | ||
.join('\n'); | ||
} | ||
get bashCompletionFunction() { | ||
var _a, _b; | ||
const cliBin = this.cliBin; | ||
const supportSpaces = this.config.topicSeparator === ' '; | ||
const bashScript = (process.env.OCLIF_AUTOCOMPLETE_TOPIC_SEPARATOR === 'colon' || !supportSpaces) ? bash_1.default : bash_spaces_1.default; | ||
return bashScript | ||
.concat(...((_b = (_a = this.config.binAliases) === null || _a === void 0 ? void 0 : _a.map(alias => `complete -F _<CLI_BIN>_autocomplete ${alias}`).join('\n')) !== null && _b !== void 0 ? _b : [])) | ||
.replace(/<CLI_BIN>/g, cliBin) | ||
.replace(/<BASH_COMMANDS_WITH_FLAGS_LIST>/g, this.bashCommandsWithFlagsList); | ||
get pwshCompletionFunctionPath() { | ||
// <cachedir>/autocomplete/functions/powershell/<bin>.ps1 | ||
return path.join(this.pwshFunctionsDir, `${this.cliBin}.ps1`); | ||
} | ||
get pwshFunctionsDir() { | ||
// <cachedir>/autocomplete/functions/powershell | ||
return path.join(this.autocompleteCacheDir, 'functions', 'powershell'); | ||
} | ||
/* eslint-enable no-useless-escape */ | ||
get zshCompletionFunction() { | ||
const cliBin = this.cliBin; | ||
const { cliBin } = this; | ||
const allCommandsMeta = this.genAllCommandsMetaString; | ||
@@ -246,5 +227,23 @@ const caseStatementForFlagsMeta = this.genCaseStatementForFlagsMetaString; | ||
} | ||
get zshCompletionFunctionPath() { | ||
// <cachedir>/autocomplete/functions/zsh/_<bin> | ||
return path.join(this.zshFunctionsDir, `_${this.cliBin}`); | ||
} | ||
get zshFunctionsDir() { | ||
// <cachedir>/autocomplete/functions/zsh | ||
return path.join(this.autocompleteCacheDir, 'functions', 'zsh'); | ||
} | ||
get zshSetupScript() { | ||
return ` | ||
fpath=( | ||
${this.zshFunctionsDir} | ||
$fpath | ||
); | ||
autoload -Uz compinit; | ||
compinit;\n`; | ||
} | ||
get zshSetupScriptPath() { | ||
// <cachedir>/autocomplete/zsh_setup | ||
return path.join(this.autocompleteCacheDir, 'zsh_setup'); | ||
} | ||
} | ||
exports.default = Create; | ||
Create.hidden = true; | ||
Create.description = 'create autocomplete setup scripts and completion functions'; |
@@ -1,12 +0,12 @@ | ||
import { AutocompleteBase } from '../../base'; | ||
import { AutocompleteBase } from '../../base.js'; | ||
export default class Index extends AutocompleteBase { | ||
static description: string; | ||
static args: { | ||
shell: import("@oclif/core/lib/interfaces/parser").Arg<string | undefined, Record<string, unknown>>; | ||
shell: import("@oclif/core/lib/interfaces/parser.js").Arg<string | undefined, Record<string, unknown>>; | ||
}; | ||
static description: string; | ||
static examples: string[]; | ||
static flags: { | ||
'refresh-cache': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>; | ||
'refresh-cache': import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>; | ||
}; | ||
static examples: string[]; | ||
run(): Promise<void>; | ||
} |
@@ -1,52 +0,70 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const tslib_1 = require("tslib"); | ||
const core_1 = require("@oclif/core"); | ||
const os_1 = require("os"); | ||
const chalk_1 = tslib_1.__importDefault(require("chalk")); | ||
const base_1 = require("../../base"); | ||
const create_1 = tslib_1.__importDefault(require("./create")); | ||
import { Args, Flags, ux } from '@oclif/core'; | ||
import chalk from 'chalk'; | ||
import { EOL } from 'node:os'; | ||
import { AutocompleteBase } from '../../base.js'; | ||
import Create from './create.js'; | ||
const noteFromShell = (shell) => { | ||
switch (shell) { | ||
case 'zsh': | ||
return `After sourcing, you can run \`${chalk_1.default.cyan('$ compaudit -D')}\` to ensure no permissions conflicts are present`; | ||
case 'bash': | ||
case 'zsh': { | ||
return `After sourcing, you can run \`${chalk.cyan('$ compaudit -D')}\` to ensure no permissions conflicts are present`; | ||
} | ||
case 'bash': { | ||
return 'If your terminal starts as a login shell you may need to print the init script into ~/.bash_profile or ~/.profile.'; | ||
case 'powershell': | ||
return `Use the \`MenuComplete\` mode to get matching completions printed below the command line:\n${chalk_1.default.cyan('Set-PSReadlineKeyHandler -Key Tab -Function MenuComplete')}`; | ||
default: | ||
} | ||
case 'powershell': { | ||
return `Use the \`MenuComplete\` mode to get matching completions printed below the command line:\n${chalk.cyan('Set-PSReadlineKeyHandler -Key Tab -Function MenuComplete')}`; | ||
} | ||
default: { | ||
return ''; | ||
} | ||
} | ||
}; | ||
class Index extends base_1.AutocompleteBase { | ||
export default class Index extends AutocompleteBase { | ||
static args = { | ||
shell: Args.string({ | ||
description: 'Shell type', | ||
options: ['zsh', 'bash', 'powershell'], | ||
required: false, | ||
}), | ||
}; | ||
static description = 'Display autocomplete installation instructions.'; | ||
static examples = [ | ||
'$ <%= config.bin %> autocomplete', | ||
'$ <%= config.bin %> autocomplete bash', | ||
'$ <%= config.bin %> autocomplete zsh', | ||
'$ <%= config.bin %> autocomplete powershell', | ||
'$ <%= config.bin %> autocomplete --refresh-cache', | ||
]; | ||
static flags = { | ||
'refresh-cache': Flags.boolean({ char: 'r', description: 'Refresh cache (ignores displaying instructions)' }), | ||
}; | ||
async run() { | ||
var _a; | ||
const { args, flags } = await this.parse(Index); | ||
const shell = args.shell || this.determineShell(this.config.shell); | ||
if (shell === 'powershell' && ((_a = this.config) === null || _a === void 0 ? void 0 : _a.topicSeparator) === ':') { | ||
this.error(`PowerShell completion is not supported in CLIs using colon as the topic separator.${os_1.EOL}See: https://oclif.io/docs/topic_separator`); | ||
if (shell === 'powershell' && this.config?.topicSeparator === ':') { | ||
this.error(`PowerShell completion is not supported in CLIs using colon as the topic separator.${EOL}See: https://oclif.io/docs/topic_separator`); | ||
} | ||
core_1.ux.action.start(`${chalk_1.default.bold('Building the autocomplete cache')}`); | ||
await create_1.default.run([], this.config); | ||
core_1.ux.action.stop(); | ||
ux.action.start(`${chalk.bold('Building the autocomplete cache')}`); | ||
await Create.run([], this.config); | ||
ux.action.stop(); | ||
if (!flags['refresh-cache']) { | ||
const bin = this.config.bin; | ||
const { bin } = this.config; | ||
const tabStr = shell === 'bash' ? '<TAB><TAB>' : '<TAB>'; | ||
const instructions = shell === 'powershell' ? | ||
`New-Item -Type Directory -Path (Split-Path -Parent $PROFILE) -ErrorAction SilentlyContinue | ||
Add-Content -Path $PROFILE -Value (Invoke-Expression -Command "${bin} autocomplete${this.config.topicSeparator}script ${shell}"); .$PROFILE` : | ||
`$ printf "eval $(${bin} autocomplete${this.config.topicSeparator}script ${shell})" >> ~/.${shell}rc; source ~/.${shell}rc`; | ||
const instructions = shell === 'powershell' | ||
? `New-Item -Type Directory -Path (Split-Path -Parent $PROFILE) -ErrorAction SilentlyContinue | ||
Add-Content -Path $PROFILE -Value (Invoke-Expression -Command "${bin} autocomplete${this.config.topicSeparator}script ${shell}"); .$PROFILE` | ||
: `$ printf "eval $(${bin} autocomplete${this.config.topicSeparator}script ${shell})" >> ~/.${shell}rc; source ~/.${shell}rc`; | ||
const note = noteFromShell(shell); | ||
this.log(` | ||
${chalk_1.default.bold(`Setup Instructions for ${bin.toUpperCase()} CLI Autocomplete ---`)} | ||
${chalk.bold(`Setup Instructions for ${bin.toUpperCase()} CLI Autocomplete ---`)} | ||
1) Add the autocomplete ${shell === 'powershell' ? 'file' : 'env var'} to your ${shell} profile and source it | ||
${chalk_1.default.cyan(instructions)} | ||
${chalk.cyan(instructions)} | ||
${chalk_1.default.bold('NOTE')}: ${note} | ||
${chalk.bold('NOTE')}: ${note} | ||
2) Test it out, e.g.: | ||
${chalk_1.default.cyan(`$ ${bin} ${tabStr}`)} # Command completion | ||
${chalk_1.default.cyan(`$ ${bin} command --${tabStr}`)} # Flag completion | ||
${chalk.cyan(`$ ${bin} ${tabStr}`)} # Command completion | ||
${chalk.cyan(`$ ${bin} command --${tabStr}`)} # Flag completion | ||
@@ -58,20 +76,1 @@ Enjoy! | ||
} | ||
exports.default = Index; | ||
Index.description = 'display autocomplete installation instructions'; | ||
Index.args = { | ||
shell: core_1.Args.string({ | ||
description: 'Shell type', | ||
options: ['zsh', 'bash', 'powershell'], | ||
required: false, | ||
}), | ||
}; | ||
Index.flags = { | ||
'refresh-cache': core_1.Flags.boolean({ description: 'Refresh cache (ignores displaying instructions)', char: 'r' }), | ||
}; | ||
Index.examples = [ | ||
'$ <%= config.bin %> autocomplete', | ||
'$ <%= config.bin %> autocomplete bash', | ||
'$ <%= config.bin %> autocomplete zsh', | ||
'$ <%= config.bin %> autocomplete powershell', | ||
'$ <%= config.bin %> autocomplete --refresh-cache', | ||
]; |
@@ -1,8 +0,8 @@ | ||
import { AutocompleteBase } from '../../base'; | ||
import { AutocompleteBase } from '../../base.js'; | ||
export default class Script extends AutocompleteBase { | ||
static args: { | ||
shell: import("@oclif/core/lib/interfaces/parser.js").Arg<string | undefined, Record<string, unknown>>; | ||
}; | ||
static description: string; | ||
static hidden: boolean; | ||
static args: { | ||
shell: import("@oclif/core/lib/interfaces/parser").Arg<string | undefined, Record<string, unknown>>; | ||
}; | ||
run(): Promise<void>; | ||
@@ -9,0 +9,0 @@ private get prefix(); |
@@ -1,8 +0,14 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const tslib_1 = require("tslib"); | ||
const core_1 = require("@oclif/core"); | ||
const path = tslib_1.__importStar(require("path")); | ||
const base_1 = require("../../base"); | ||
class Script extends base_1.AutocompleteBase { | ||
import { Args } from '@oclif/core'; | ||
import * as path from 'node:path'; | ||
import { AutocompleteBase } from '../../base.js'; | ||
export default class Script extends AutocompleteBase { | ||
static args = { | ||
shell: Args.string({ | ||
description: 'Shell type', | ||
options: ['zsh', 'bash', 'powershell'], | ||
required: false, | ||
}), | ||
}; | ||
static description = 'outputs autocomplete config script for shells'; | ||
static hidden = true; | ||
async run() { | ||
@@ -28,11 +34,1 @@ const { args } = await this.parse(Script); | ||
} | ||
exports.default = Script; | ||
Script.description = 'outputs autocomplete config script for shells'; | ||
Script.hidden = true; | ||
Script.args = { | ||
shell: core_1.Args.string({ | ||
description: 'Shell type', | ||
options: ['zsh', 'bash', 'powershell'], | ||
required: false, | ||
}), | ||
}; |
@@ -1,3 +0,1 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.default = {}; | ||
export default {}; |
{ | ||
"version": "2.3.10", | ||
"commands": { | ||
"autocomplete:create": { | ||
"aliases": [], | ||
"args": {}, | ||
"description": "create autocomplete setup scripts and completion functions", | ||
"flags": {}, | ||
"hasDynamicHelp": false, | ||
"hidden": true, | ||
"hiddenAliases": [], | ||
"id": "autocomplete:create", | ||
"description": "create autocomplete setup scripts and completion functions", | ||
"strict": true, | ||
"pluginAlias": "@oclif/plugin-autocomplete", | ||
"pluginName": "@oclif/plugin-autocomplete", | ||
"pluginAlias": "@oclif/plugin-autocomplete", | ||
"pluginType": "core", | ||
"hidden": true, | ||
"aliases": [], | ||
"flags": {}, | ||
"args": {} | ||
"strict": true, | ||
"isESM": true, | ||
"relativePath": [ | ||
"lib", | ||
"commands", | ||
"autocomplete", | ||
"create.js" | ||
], | ||
"aliasPermutations": [], | ||
"permutations": [ | ||
"autocomplete:create", | ||
"create:autocomplete" | ||
] | ||
}, | ||
"autocomplete": { | ||
"id": "autocomplete", | ||
"description": "display autocomplete installation instructions", | ||
"strict": true, | ||
"pluginName": "@oclif/plugin-autocomplete", | ||
"pluginAlias": "@oclif/plugin-autocomplete", | ||
"pluginType": "core", | ||
"aliases": [], | ||
"args": { | ||
"shell": { | ||
"description": "Shell type", | ||
"name": "shell", | ||
"options": [ | ||
"zsh", | ||
"bash", | ||
"powershell" | ||
], | ||
"required": false | ||
} | ||
}, | ||
"description": "Display autocomplete installation instructions.", | ||
"examples": [ | ||
@@ -33,14 +53,34 @@ "$ <%= config.bin %> autocomplete", | ||
"refresh-cache": { | ||
"name": "refresh-cache", | ||
"type": "boolean", | ||
"char": "r", | ||
"description": "Refresh cache (ignores displaying instructions)", | ||
"allowNo": false | ||
"name": "refresh-cache", | ||
"allowNo": false, | ||
"type": "boolean" | ||
} | ||
}, | ||
"hasDynamicHelp": false, | ||
"hiddenAliases": [], | ||
"id": "autocomplete", | ||
"pluginAlias": "@oclif/plugin-autocomplete", | ||
"pluginName": "@oclif/plugin-autocomplete", | ||
"pluginType": "core", | ||
"strict": true, | ||
"isESM": true, | ||
"relativePath": [ | ||
"lib", | ||
"commands", | ||
"autocomplete", | ||
"index.js" | ||
], | ||
"aliasPermutations": [], | ||
"permutations": [ | ||
"autocomplete" | ||
] | ||
}, | ||
"autocomplete:script": { | ||
"aliases": [], | ||
"args": { | ||
"shell": { | ||
"description": "Shell type", | ||
"name": "shell", | ||
"description": "Shell type", | ||
"required": false, | ||
"options": [ | ||
@@ -50,30 +90,31 @@ "zsh", | ||
"powershell" | ||
] | ||
], | ||
"required": false | ||
} | ||
} | ||
}, | ||
"autocomplete:script": { | ||
}, | ||
"description": "outputs autocomplete config script for shells", | ||
"flags": {}, | ||
"hasDynamicHelp": false, | ||
"hidden": true, | ||
"hiddenAliases": [], | ||
"id": "autocomplete:script", | ||
"description": "outputs autocomplete config script for shells", | ||
"strict": true, | ||
"pluginAlias": "@oclif/plugin-autocomplete", | ||
"pluginName": "@oclif/plugin-autocomplete", | ||
"pluginAlias": "@oclif/plugin-autocomplete", | ||
"pluginType": "core", | ||
"hidden": true, | ||
"aliases": [], | ||
"flags": {}, | ||
"args": { | ||
"shell": { | ||
"name": "shell", | ||
"description": "Shell type", | ||
"required": false, | ||
"options": [ | ||
"zsh", | ||
"bash", | ||
"powershell" | ||
] | ||
} | ||
} | ||
"strict": true, | ||
"isESM": true, | ||
"relativePath": [ | ||
"lib", | ||
"commands", | ||
"autocomplete", | ||
"script.js" | ||
], | ||
"aliasPermutations": [], | ||
"permutations": [ | ||
"autocomplete:script", | ||
"script:autocomplete" | ||
] | ||
} | ||
} | ||
}, | ||
"version": "2.3.11-dev.0" | ||
} |
{ | ||
"name": "@oclif/plugin-autocomplete", | ||
"description": "autocomplete plugin for oclif", | ||
"version": "2.3.10", | ||
"version": "2.3.11-dev.0", | ||
"author": "Salesforce", | ||
"bugs": "https://github.com/oclif/plugin-autocomplete/issues", | ||
"dependencies": { | ||
"@oclif/core": "^2.15.0", | ||
"chalk": "^4.1.0", | ||
"debug": "^4.3.4" | ||
"@oclif/core": "^3.5.0", | ||
"chalk": "^5.3.0", | ||
"debug": "^4.3.4", | ||
"ejs": "^3.1.9" | ||
}, | ||
"devDependencies": { | ||
"@oclif/plugin-help": "^5", | ||
"@oclif/test": "^2.5.6", | ||
"@commitlint/config-conventional": "^18.0.0", | ||
"@oclif/plugin-help": "^6", | ||
"@oclif/prettier-config": "^0.2.1", | ||
"@oclif/test": "^3.0.2", | ||
"@types/chai": "^4", | ||
"@types/chalk": "^2.2.0", | ||
"@types/ejs": "^3.1.3", | ||
"@types/mocha": "^8", | ||
"@types/debug": "^4.1.10", | ||
"@types/ejs": "^3.1.4", | ||
"@types/mocha": "^10.0.3", | ||
"@types/nock": "^11.1.0", | ||
"@types/node": "^15.14.9", | ||
"@types/node": "^18", | ||
"chai": "^4", | ||
"eslint": "^7.3.1", | ||
"eslint-config-oclif": "^3.1.0", | ||
"eslint-config-oclif-typescript": "^0.2.0", | ||
"commitlint": "^18.0.0", | ||
"eslint": "^8.52.0", | ||
"eslint-config-oclif": "^5.0.0", | ||
"eslint-config-oclif-typescript": "^3.0.8", | ||
"eslint-config-prettier": "^9.0.0", | ||
"globby": "^11", | ||
"mocha": "^8.2.1", | ||
"nock": "^13.3.4", | ||
"husky": "^8.0.3", | ||
"lint-staged": "^15.0.2", | ||
"mocha": "^10.2.0", | ||
"nock": "^13.3.6", | ||
"nyc": "^15.1.0", | ||
"oclif": "^3.17.2", | ||
"oclif": "^4.0.3", | ||
"prettier": "^3.0.3", | ||
"shx": "^0.3.3", | ||
"ts-node": "^9.0.0", | ||
"tslib": "^2.6.2", | ||
"typescript": "4.6.3" | ||
"ts-node": "^10.9.1", | ||
"typescript": "^5.2.2" | ||
}, | ||
"engines": { | ||
"node": ">=12.0.0" | ||
"node": ">=18.0.0" | ||
}, | ||
"exports": "./lib/index.js", | ||
"files": [ | ||
"/lib", | ||
"/oclif.manifest.json" | ||
"/oclif.manifest.json", | ||
"/oclif.lock" | ||
], | ||
@@ -52,15 +62,18 @@ "homepage": "https://github.com/oclif/plugin-autocomplete", | ||
"@oclif/plugin-help" | ||
] | ||
], | ||
"flexibleTaxonomy": true | ||
}, | ||
"repository": "oclif/plugin-autocomplete", | ||
"scripts": { | ||
"lint": "eslint . --ext .ts --config .eslintrc", | ||
"build": "shx rm -rf lib && tsc", | ||
"lint": "eslint . --ext .ts", | ||
"postpack": "shx rm -f oclif.manifest.json oclif.lock", | ||
"posttest": "yarn lint", | ||
"prepack": "shx rm -rf lib && tsc && oclif lock && oclif manifest . && oclif readme", | ||
"prepare": "husky install", | ||
"pretest": "yarn build && tsc -p test", | ||
"test": "mocha --forbid-only \"test/**/*.test.ts\"", | ||
"posttest": "yarn lint", | ||
"prepack": "shx rm -rf lib && tsc && oclif manifest . && oclif readme", | ||
"postpack": "shx rm -f oclif.manifest.json", | ||
"version": "oclif readme && git add README.md", | ||
"build": "shx rm -rf lib && tsc" | ||
} | ||
} | ||
"version": "oclif readme && git add README.md" | ||
}, | ||
"type": "module" | ||
} |
@@ -1,3 +0,2 @@ | ||
@oclif/plugin-autocomplete | ||
========================== | ||
# @oclif/plugin-autocomplete | ||
@@ -11,5 +10,7 @@ autocomplete plugin for oclif (bash, zsh and powershell) | ||
<!-- toc --> | ||
* [@oclif/plugin-autocomplete](#oclifplugin-autocomplete) | ||
* [Usage](#usage) | ||
* [Commands](#commands) | ||
<!-- tocstop --> | ||
# Usage | ||
@@ -20,2 +21,3 @@ | ||
## Topic separator | ||
Since oclif v2 it's possible to use spaces as a topic separator in addition to colons. | ||
@@ -30,2 +32,3 @@ | ||
# Commands | ||
<!-- commands --> | ||
@@ -36,3 +39,3 @@ * [`oclif-example autocomplete [SHELL]`](#oclif-example-autocomplete-shell) | ||
display autocomplete installation instructions | ||
Display autocomplete installation instructions. | ||
@@ -50,3 +53,3 @@ ``` | ||
DESCRIPTION | ||
display autocomplete installation instructions | ||
Display autocomplete installation instructions. | ||
@@ -65,3 +68,3 @@ EXAMPLES | ||
_See code: [src/commands/autocomplete/index.ts](https://github.com/oclif/plugin-autocomplete/blob/v2.3.10/src/commands/autocomplete/index.ts)_ | ||
_See code: [src/commands/autocomplete/index.ts](https://github.com/oclif/plugin-autocomplete/blob/v2.3.11-dev.0/src/commands/autocomplete/index.ts)_ | ||
<!-- commandsstop --> |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 2 instances in 1 package
370364
23
1390
65
3
Yes
4
28
1
2
0
+ Addedejs@^3.1.9
+ Added@oclif/core@3.27.0(transitive)
+ Addedchalk@5.3.0(transitive)
+ Addedcolor@4.2.3(transitive)
+ Addedcolor-string@1.9.1(transitive)
+ Addedis-arrayish@0.3.2(transitive)
+ Addedminimatch@9.0.5(transitive)
+ Addedsimple-swizzle@0.2.2(transitive)
- Removed@cspotcode/source-map-support@0.8.1(transitive)
- Removed@jridgewell/resolve-uri@3.1.2(transitive)
- Removed@jridgewell/sourcemap-codec@1.5.0(transitive)
- Removed@jridgewell/trace-mapping@0.3.9(transitive)
- Removed@oclif/core@2.16.0(transitive)
- Removed@tsconfig/node10@1.0.11(transitive)
- Removed@tsconfig/node12@1.0.11(transitive)
- Removed@tsconfig/node14@1.0.3(transitive)
- Removed@tsconfig/node16@1.0.4(transitive)
- Removedacorn@8.14.0(transitive)
- Removedacorn-walk@8.3.4(transitive)
- Removedarg@4.1.3(transitive)
- Removedcreate-require@1.1.1(transitive)
- Removeddiff@4.0.2(transitive)
- Removedmake-error@1.3.6(transitive)
- Removedts-node@10.9.2(transitive)
- Removedtslib@2.8.1(transitive)
- Removedtypescript@5.6.3(transitive)
- Removedv8-compile-cache-lib@3.0.1(transitive)
- Removedyn@3.1.1(transitive)
Updated@oclif/core@^3.5.0
Updatedchalk@^5.3.0