From 0a96394f3b3125332eeaaa6c7a5beeffb3c3a27f Mon Sep 17 00:00:00 2001 From: Trevor Linton Date: Thu, 14 Feb 2019 20:19:30 -0700 Subject: [PATCH] fix: support options/sub-commands in zsh completion --- completion.zsh.hbs | 2 +- lib/completion.js | 7 ++++--- test/completion.js | 19 ++++++++++++++++++- 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/completion.zsh.hbs b/completion.zsh.hbs index ac6180586..2a819e249 100644 --- a/completion.zsh.hbs +++ b/completion.zsh.hbs @@ -9,7 +9,7 @@ _{{app_name}}_yargs_completions() { local reply local si=$IFS - IFS=$'\n' reply=($(COMP_CWORD="$((CURRENT-1))" COMP_LINE="$BUFFER" COMP_POINT="$CURSOR" {{app_path}} --get-yargs-completions "$\{words[@]\}")) + IFS=$'\n' reply=($(COMP_CWORD="$((CURRENT-1))" COMP_LINE="$BUFFER" COMP_POINT="$CURSOR" {{app_path}} --get-yargs-completions "${words[@]}")) IFS=$si _describe 'values' reply } diff --git a/lib/completion.js b/lib/completion.js index ef0986fb4..a8de5b04e 100644 --- a/lib/completion.js +++ b/lib/completion.js @@ -17,6 +17,7 @@ module.exports = function completion (yargs, usage, command) { const current = args.length ? args[args.length - 1] : '' const argv = yargs.parse(args, true) const aliases = yargs.parsed.aliases + const parentCommands = yargs.getContext().commands // a custom completion function can be provided // to completion(). @@ -55,7 +56,7 @@ module.exports = function completion (yargs, usage, command) { } } - if (!current.match(/^-/)) { + if (!current.match(/^-/) && parentCommands[parentCommands.length - 1] !== current) { usage.getCommands().forEach((usageCommand) => { const commandName = command.parseCommand(usageCommand[0]).cmd if (args.indexOf(commandName) === -1) { @@ -69,7 +70,7 @@ module.exports = function completion (yargs, usage, command) { }) } - if (current.match(/^-/)) { + if (current.match(/^-/) || (current === '' && completions.length === 0)) { const descs = usage.getDescriptions() Object.keys(yargs.getOptions().key).forEach((key) => { // If the key and its aliases aren't in 'args', add the key to 'completions' @@ -80,7 +81,7 @@ module.exports = function completion (yargs, usage, command) { completions.push(`--${key}`) } else { const desc = descs[key] || '' - completions.push(`--${key.replace(/:/g, '\\:')}:${desc}`) + completions.push(`--${key.replace(/:/g, '\\:')}:${desc.replace('__yargsString__:', '')}`) } } }) diff --git a/test/completion.js b/test/completion.js index 9860fc5f6..604e4c678 100644 --- a/test/completion.js +++ b/test/completion.js @@ -181,7 +181,7 @@ describe('Completion', () => { r.logs.should.have.length(2) r.logs.should.include('--bar:bar option') - r.logs.should.include('--help:__yargsString__:Show help') + r.logs.should.include('--help:Show help') }) it('completes options for the correct command', () => { @@ -460,4 +460,21 @@ describe('Completion', () => { r.errors.length.should.equal(0) r.logs.should.include('--foo:bar') }) + it('when using subcommands ensure early bailout if full command is typed (zsh)', () => { + process.env.SHELL = '/bin/zsh' + const r = checkUsage(() => { + try { + return yargs(['./completion', '--get-yargs-completions', 'dream']) + .commandDir('./fixtures/cmddir', { 'recurse': true }) + .demand(1) + .strict() + .completion() + .argv + } catch (e) { + console.log(e.message) + } + }) + r.errors.length.should.equal(0) + r.logs.should.include('of-memory:Dream about a specific memory') + }) })