An npm package to do some custom command line<tab><tab>
completion for
any system command, using the node api and JS to provide your own
completion, for both bash/zsh shell.
Made possible using the same technique as npm (whose completion is quite awesome) relying on a bash/zsh completion shell script bridge to do the actual completion from node's land.
Latest released version (when it'll get released)
npm install tabtab
Latest dev code:
npm install https://github.com/mklabs/node-tabtab/tarball/master
You can add completion pretty easily in your node cli script:
#!/usr/bin/env node
var tabtab = require('tabtab');
if(process.argv.slice(2)[0] === 'completion') return tabtab.complete('pkgname', function(err, data) {
// simply return here if there's an error or data not provided.
// stderr not showing on completions
if(err || !data) return;
if(/^--\w?/.test(data.last)) return tabtab.log(['help', 'version'], data, '--');
if(/^-\w?/.test(data.last)) return tabtab.log(['n', 'o', 'd', 'e'], data, '-');
tabtab.log(['list', 'of', 'commands'], data);
});
// The rest of your script
...
Simply replace pkgname
by the name of your package. The complete
callback get's called with data only in the context of a completion
command.
The data
object holds interesting value to drive the output of the
completion:
line
: full command being completedwords
: number of wordpoint
: cursor positionpartial
: tabing in the middle of a word: foo bar baz bar foobarrrrrrrlast
: last word of the linelastPartial
: last partial of the lineprev
: the previous word
Installing the completion for your cli app is done very much like npm does:
. <(pkgname completion)
It'll enables tab-completion for the pkgname
executable. Adding it to
your ~/.bashrc or ~/.zshrc will make the completions available
everywhere (not only the current shell).
Main completion method, has support for installation and actual completion.
tabtab.complete(completed, completer, callback);
- completed: name of the command to complete
- completer: Optional name of the command to call on completion (when not set, completed and completer are the same)
- callback: get called when a tab-completion command happens.
completed and completer are there only to set up and build the correct
bash/zsh script, based on the lib/completion.sh
template (which is
based on npm's completion shell script)
Helper to return completion output and log to standard output.
tabtab.log(['list', 'of', 'values'], data, prefix);
- values: Array of values to complete against.
- data: the data object returned by the complete callback, used mainly to filter results accordingly upon the text that is supplied by the user.
- prefix: Optional a prefix to add to the completion results, useful
for options to add dashes (eg.
-
or--
).
Helper to return the list of short and long options, parsed from the
usual --help
output of a command (cake/rake -H, vagrant, commander -h,
optimist.help(), ...)
var parsed = completion.parseOut(optimist.help());
console.log(parsed.shorts);
console.log(parsed.longs);
Using a spawned process:
exec('rake -H', function(err, stdout, stderr) {
if(err) return;
var parsed = parseOut(stdout);
if(/^--\w?/.test(o.last)) return log(parsed.longs, data, '--');
if(/^-\w?/.test(o.last)) return log(parsed.shorts, data, '-');
});
same purpose as parseOut, but for parsing tasks from an help command (cake/rake -T, vagrant, etc.)
exec('cake', function(err, stdout, stderr) { if(err) return; var parsed = tasks = parseTasks(stdout, 'cake'); log(tasks, o); });
- stdout: string of help output.
- prefix: prefix used internally to build the RegExp that is used to parse tasks from stdout.
npm does pretty amazing stuff with its completion feature. Bash and zsh provides command tab-completion, which allow you to complete the names of commands in your $PATH. Usually these functions means bash scripting, and in the case of npm, it is partially true.
There is a special npm completion
command you may want to look around,
if not already.
npm completion
Running this should dump this
script
to the console. This script works with both bash/zsh and map the correct
completion functions to the npm executable. These functions takes care
of parsing the COMP_*
variables available when hitting TAB to complete
a command, set them up as environment variables and run the npm completion
command followed by -- words
where words match value of
the command being completed.
This means that using this technique npm manage to perform bash/zsh completion using node and JavaScript. Actually, the comprehensiveness of npm completion is quite amazing.
This whole package/module is based entirely on npm's code and @isaacs work.