Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

a couple minor tweaks to the command-specific completion logic in #185 #187

Merged
merged 3 commits into from
Jun 24, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 12 additions & 15 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@ function Argv (processArgs, cwd) {
strict = false
helpOpt = null
versionOpt = null
completionOpt = null
commandHandlers = {}
self.parsed = false

Expand Down Expand Up @@ -352,7 +351,6 @@ function Argv (processArgs, cwd) {
return usage.help()
}

var completionOpt = null
var completionCommand = null
self.completion = function (cmd, desc, fn) {
// a function to execute when generating
Expand All @@ -365,7 +363,6 @@ function Argv (processArgs, cwd) {

// register the completion command.
completionCommand = cmd || 'completion'
completionOpt = completion.completionKey
self.command(completionCommand, desc || 'generate bash completion script')

// a function can be provided
Expand Down Expand Up @@ -420,19 +417,11 @@ function Argv (processArgs, cwd) {
// are two passes through the parser. If completion
// is being performed short-circuit on the first pass.
if (completionCommand &&
(process.argv.join(' ')).indexOf(completionOpt) !== -1 &&
!argv[completionOpt]) {
(process.argv.join(' ')).indexOf(completion.completionKey) !== -1 &&
!argv[completion.completionKey]) {
return argv
}

// generate a completion script for adding to ~/.bashrc.
if (completionCommand && ~argv._.indexOf(completionCommand) && !argv[completionOpt]) {
self.showCompletionScript()
if (exitProcess) {
process.exit(0)
}
}

// if there's a handler associated with a
// command defer processing to it.
var handlerKeys = Object.keys(self.getCommandHandlers())
Expand All @@ -443,9 +432,17 @@ function Argv (processArgs, cwd) {
}
}

// generate a completion script for adding to ~/.bashrc.
if (completionCommand && ~argv._.indexOf(completionCommand) && !argv[completion.completionKey]) {
self.showCompletionScript()
if (exitProcess) {
process.exit(0)
}
}

// we must run completions first, a user might
// want to complete the --help or --version option.
if (completionOpt in argv) {
if (completion.completionKey in argv) {
// we allow for asynchronous completions,
// e.g., loading in a list of commands from an API.
completion.getCompletion(function (completions) {
Expand Down Expand Up @@ -476,7 +473,7 @@ function Argv (processArgs, cwd) {

// if we're executed via bash completion, don't
// bother with validation.
if (!argv[completionOpt]) {
if (!argv[completion.completionKey]) {
validation.nonOptionCount(argv)
validation.missingArgumentValue(argv)
validation.requiredArguments(argv)
Expand Down
7 changes: 7 additions & 0 deletions lib/completion.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,13 @@ module.exports = function (yargs, usage) {
}
}

var handlers = yargs.getCommandHandlers()
for (var i = 0, ii = previous.length; i < ii; ++i) {
if (handlers[previous[i]]) {
return handlers[previous[i]](yargs.reset())
}
}

if (!current.match(/^-/)) {
usage.getCommands().forEach(function (command) {
if (previous.indexOf(command[0]) === -1) {
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
"hashish": "0.0.4",
"mocha": "^2.2.1",
"nyc": "^2.2.1",
"standard": "^4.2.1"
"standard": "^4.3.2"
},
"scripts": {
"test": "standard && nyc mocha --check-leaks && nyc report",
Expand Down
77 changes: 65 additions & 12 deletions test/completion.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
/* global describe, it, beforeEach */

var checkUsage = require('./helpers/utils').checkOutput
var yargs = require('../')

require('chai').should()

describe('Completion', function () {
beforeEach(function () {
yargs.reset()
Expand All @@ -11,15 +12,11 @@ describe('Completion', function () {
describe('default completion behavior', function () {
it('it returns a list of commands as completion suggestions', function () {
var r = checkUsage(function () {
try {
return yargs(['--get-yargs-completions'])
return yargs(['--get-yargs-completions'])
.command('foo', 'bar')
.command('apple', 'banana')
.completion()
.argv
} catch (e) {
console.log(e.message)
}
}, ['./completion', '--get-yargs-completions', ''])

r.logs.should.include('apple')
Expand All @@ -28,21 +25,77 @@ describe('Completion', function () {

it('avoids repeating already included commands', function () {
var r = checkUsage(function () {
try {
return yargs(['--get-yargs-completions'])
return yargs(['--get-yargs-completions'])
.command('foo', 'bar')
.command('apple', 'banana')
.completion()
.argv
} catch (e) {
console.log(e.message)
}
}, ['./completion', '--get-yargs-completions', 'apple'])

r.logs.should.include('foo')
r.logs.should.not.include('apple')
})

it('completes options for a command', function () {
var r = checkUsage(function () {
return yargs(['--get-yargs-completions'])
.command('foo', 'foo command', function (subYargs) {
subYargs.options({
bar: {
describe: 'bar option'
}
})
.help('help')
.argv
})
.completion()
.argv
}, ['./completion', '--get-yargs-completions', 'foo', '--b'])

r.logs.should.have.length(2)
r.logs.should.include('--bar')
r.logs.should.include('--help')
})

it('completes options for the correct command', function () {
var r = checkUsage(function () {
return yargs(['--get-yargs-completions'])
.command('cmd1', 'first command', function (subYargs) {
subYargs.options({
opt1: {
describe: 'first option'
}
})
.argv
})
.command('cmd2', 'second command', function (subYargs) {
subYargs.options({
opt2: {
describe: 'second option'
}
})
.argv
})
.completion()
.argv
}, ['./completion', '--get-yargs-completions', 'cmd2', '--o'])

r.logs.should.have.length(1)
r.logs.should.include('--opt2')
})

it('works if command has no options', function () {
var r = checkUsage(function () {
return yargs(['--get-yargs-completions'])
.command('foo', 'foo command', function (subYargs) {
subYargs.completion().argv
})
.completion()
.argv
}, ['./completion', '--get-yargs-completions', 'foo', '--b'])

r.logs.should.have.length(0)
})

it("returns arguments as completion suggestion, if next contains '-'", function () {
var r = checkUsage(function () {
return yargs(['--get-yargs-completions'])
Expand Down