| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128 | import { isCommandBuilderCallback } from './command.js';import { assertNotStrictEqual } from './typings/common-types.js';import * as templates from './completion-templates.js';import { isPromise } from './utils/is-promise.js';import { parseCommand } from './parse-command.js';export function completion(yargs, usage, command, shim) {    const self = {        completionKey: 'get-yargs-completions',    };    let aliases;    self.setParsed = function setParsed(parsed) {        aliases = parsed.aliases;    };    const zshShell = (shim.getEnv('SHELL') && shim.getEnv('SHELL').indexOf('zsh') !== -1) ||        (shim.getEnv('ZSH_NAME') && shim.getEnv('ZSH_NAME').indexOf('zsh') !== -1);    self.getCompletion = function getCompletion(args, done) {        const completions = [];        const current = args.length ? args[args.length - 1] : '';        const argv = yargs.parse(args, true);        const parentCommands = yargs.getContext().commands;        function runCompletionFunction(argv) {            assertNotStrictEqual(completionFunction, null, shim);            if (isSyncCompletionFunction(completionFunction)) {                const result = completionFunction(current, argv);                if (isPromise(result)) {                    return result                        .then(list => {                        shim.process.nextTick(() => {                            done(list);                        });                    })                        .catch(err => {                        shim.process.nextTick(() => {                            throw err;                        });                    });                }                return done(result);            }            else {                return completionFunction(current, argv, completions => {                    done(completions);                });            }        }        if (completionFunction) {            return isPromise(argv)                ? argv.then(runCompletionFunction)                : runCompletionFunction(argv);        }        const handlers = command.getCommandHandlers();        for (let i = 0, ii = args.length; i < ii; ++i) {            if (handlers[args[i]] && handlers[args[i]].builder) {                const builder = handlers[args[i]].builder;                if (isCommandBuilderCallback(builder)) {                    const y = yargs.reset();                    builder(y);                    return y.argv;                }            }        }        if (!current.match(/^-/) &&            parentCommands[parentCommands.length - 1] !== current) {            usage.getCommands().forEach(usageCommand => {                const commandName = parseCommand(usageCommand[0]).cmd;                if (args.indexOf(commandName) === -1) {                    if (!zshShell) {                        completions.push(commandName);                    }                    else {                        const desc = usageCommand[1] || '';                        completions.push(commandName.replace(/:/g, '\\:') + ':' + desc);                    }                }            });        }        if (current.match(/^-/) || (current === '' && completions.length === 0)) {            const descs = usage.getDescriptions();            const options = yargs.getOptions();            Object.keys(options.key).forEach(key => {                const negable = !!options.configuration['boolean-negation'] &&                    options.boolean.includes(key);                let keyAndAliases = [key].concat(aliases[key] || []);                if (negable)                    keyAndAliases = keyAndAliases.concat(keyAndAliases.map(key => `no-${key}`));                function completeOptionKey(key) {                    const notInArgs = keyAndAliases.every(val => args.indexOf(`--${val}`) === -1);                    if (notInArgs) {                        const startsByTwoDashes = (s) => /^--/.test(s);                        const isShortOption = (s) => /^[^0-9]$/.test(s);                        const dashes = !startsByTwoDashes(current) && isShortOption(key) ? '-' : '--';                        if (!zshShell) {                            completions.push(dashes + key);                        }                        else {                            const desc = descs[key] || '';                            completions.push(dashes +                                `${key.replace(/:/g, '\\:')}:${desc.replace('__yargsString__:', '')}`);                        }                    }                }                completeOptionKey(key);                if (negable && !!options.default[key])                    completeOptionKey(`no-${key}`);            });        }        done(completions);    };    self.generateCompletionScript = function generateCompletionScript($0, cmd) {        let script = zshShell            ? templates.completionZshTemplate            : templates.completionShTemplate;        const name = shim.path.basename($0);        if ($0.match(/\.js$/))            $0 = `./${$0}`;        script = script.replace(/{{app_name}}/g, name);        script = script.replace(/{{completion_command}}/g, cmd);        return script.replace(/{{app_path}}/g, $0);    };    let completionFunction = null;    self.registerFunction = fn => {        completionFunction = fn;    };    return self;}function isSyncCompletionFunction(completionFunction) {    return completionFunction.length < 3;}
 |