From 8be0b184e72f8ba09da81a67fdcbe5710e21bd04 Mon Sep 17 00:00:00 2001 From: Branden Visser Date: Sun, 25 May 2014 19:13:42 -0400 Subject: [PATCH] Add help auto-complete, update readme --- README.md | 9 ++++++++- commands/help.js | 13 +++++++++++++ lib/util.js | 11 +++++++++++ 3 files changed, 32 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index e05d4d7..4e0bb30 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,8 @@ Currently: * Parsing of string command input into an argv array * Multi-line commands -* Tab auto-complete for commands based on available commands +* Tab auto-complete to choose command to run +* Custom tab auto-complete implementation for command-specific arguments * API and Model for creating and loading your own commands * Flexible error handling * Custom PS1 and PS2 prompts @@ -236,6 +237,12 @@ unknown$ iam branden branden$ quit ``` +### Custom Auto-complete + +It is possible to implement auto-complete for your custom commands. Provide an `autocomplete` function in your command implementation that takes a `session`, `args` array and `callback([err], [replacementsArray])`. + +See the [readline auto-complete explanation](https://github.com/mrvisser/node-readcommand#auto-complete) for more details, and the [help command](https://github.com/mrvisser/node-corporal/blob/master/commands/help.js) contains a reference implementation that returns auto-completions for command names for which to show help. + ### Command Contexts It is possible to filter the commands available based on a custom context. For example, if your shell application requires authentication, you may want to provide some commands only to users when they are authenticated. Contexts allow you to accomplish this. diff --git a/commands/help.js b/commands/help.js index 3b81fc4..bf2c323 100644 --- a/commands/help.js +++ b/commands/help.js @@ -85,6 +85,19 @@ module.exports = { } return callback(); + }, + 'autocomplete': function(session, args, callback) { + if (args.length !== 1) { + return callback(); + } + + // Filter by command names + return callback(null, _.chain(session.commands().get()) + .keys() + .filter(function(commandName) { + return (commandName.indexOf(args[0]) === 0); + }) + .value()); } }; diff --git a/lib/util.js b/lib/util.js index 4237ed6..2ff5498 100644 --- a/lib/util.js +++ b/lib/util.js @@ -195,6 +195,9 @@ function _createPs(session, psVar) { */ function _createAutocomplete(session) { return function(args, callback) { + args = args.slice(); + + // First handle the case where this is an auto-suggest based on finding the command name var allCommandNames = _.keys(session.commands().get()); if (_.isEmpty(args)) { return callback(null, allCommandNames); @@ -204,6 +207,14 @@ function _createAutocomplete(session) { })); } + // We presumably have a command argument already, feed the remaining arguments into the + // commands autocomplete implementation + var commandName = args.shift(); + var command = session.commands().get(commandName); + if (command && _.isFunction(command.autocomplete)) { + return command.autocomplete(session, args, callback); + } + return callback(null, []); }; }