Comparing version 0.3.5 to 0.4.0
@@ -6,13 +6,2 @@ /** | ||
var _ = require("lodash"); | ||
var async = require("async"); | ||
var clc = require("cli-color"); | ||
var readlineFacade = require("./utils/readline"); | ||
var utils = require("./utils/utils"); | ||
/** | ||
* Module exports | ||
*/ | ||
var inquirer = module.exports; | ||
@@ -37,3 +26,8 @@ | ||
inquirer.ui = { | ||
BottomBar: require("./ui/bottom-bar"), | ||
Prompt: require("./ui/prompt") | ||
}; | ||
/** | ||
@@ -47,105 +41,3 @@ * Public CLI helper interface | ||
inquirer.prompt = function( questions, allDone ) { | ||
var self = this; | ||
// Instantiate the Readline interface | ||
// @Note: Don't reassign if already present (allow test to override the Stream) | ||
this.rl || (this.rl = readlineFacade.createInterface()); | ||
this.rl.resume(); | ||
// Keep global reference to the answers | ||
this.answers = {}; | ||
// Make sure questions is an array. | ||
if ( !_.isArray(questions) ) { | ||
questions = [questions]; | ||
} | ||
// Propagate keypress events directly on the readline | ||
process.stdin.on( "keypress", this.onKeypress ); | ||
// Make sure new prompt start on a newline when closing | ||
self.rl.on( "SIGINT", this.onForceClose ); | ||
// Control flow functions | ||
var onCompletion = function() { | ||
// Remove events listeners | ||
this.rl.removeListener( "SIGINT", this.onForceClose ); | ||
process.stdin.removeListener( "keypress", this.onKeypress ); | ||
// Close the readline | ||
this.rl.output.end(); | ||
this.rl.pause(); | ||
this.rl.close(); | ||
this.rl = null; | ||
if ( _.isFunction(allDone) ) { | ||
allDone(this.answers); | ||
} | ||
}.bind(this); | ||
var onEach = function( question, done ) { | ||
// Callback to save answer and continu to next question | ||
var after = function( answer ) { | ||
this.answers[question.name] = answer; | ||
done( null ); | ||
}.bind(this); | ||
// Default type to input | ||
if ( !this.prompts[question.type] ) { | ||
question.type = "input"; | ||
} | ||
if ( _.isFunction(question.default) ) { | ||
question.default = question.default( this.answers ); | ||
} | ||
if ( _.isFunction(question.choices) ) { | ||
question.choices = question.choices( this.answers ); | ||
} | ||
var prompt = new this.prompts[question.type]( question, this.rl ); | ||
// Check if prompt should be runned (if `when` return true) | ||
utils.runAsync( prompt.opt.when, function( continu ) { | ||
if( continu ) { | ||
prompt.run( after ); | ||
} else { | ||
done( null ); | ||
} | ||
}, this.answers ); | ||
}.bind(this); | ||
// Start running the questions | ||
async.mapSeries( questions, onEach, onCompletion ); | ||
return new inquirer.ui.Prompt( questions, allDone ); | ||
}; | ||
/** | ||
* Propagate keypress to the readline | ||
* @return {null} | ||
*/ | ||
inquirer.onKeypress = function( s, key ) { | ||
// Ignore `enter` key (readline `line` event is the only one we care for) | ||
if ( key && (key.name === "enter" || key.name === "return") ) return; | ||
if ( this.rl ) { | ||
this.rl.emit( "keypress", s, key ); | ||
} | ||
}.bind(inquirer); | ||
/** | ||
* Handle the ^C exit | ||
* @return {null} | ||
*/ | ||
inquirer.onForceClose = function() { | ||
this.rl.output.unmute(); | ||
process.stdout.write("\033[?25h"); // show cursor | ||
this.rl.close(); | ||
console.log("\n"); // Line return | ||
}.bind(inquirer); |
@@ -26,3 +26,3 @@ /** | ||
// Don't process Choice and Separator object | ||
if ( val instanceof Choice || val instanceof Separator ) { | ||
if ( val instanceof Choice || val.type === "separator" ) { | ||
return val; | ||
@@ -29,0 +29,0 @@ } |
@@ -27,3 +27,3 @@ /** | ||
this.choices = _.map( choices, function( val ) { | ||
if ( val instanceof Separator ) { | ||
if ( val.type === "separator" ) { | ||
return val; | ||
@@ -172,4 +172,4 @@ } | ||
var section = infinite.splice( topIndex, pageSize ).join("\n"); | ||
return section + "\n" + clc.blackBright("(Move up and down to reveal more choices)"); | ||
return section + "\n(Move up and down to reveal more choices)"; | ||
}.bind(this); | ||
}; |
@@ -21,2 +21,3 @@ /** | ||
function Separator( line ) { | ||
this.type = "separator"; | ||
this.line = line || "--------"; | ||
@@ -33,3 +34,3 @@ } | ||
Separator.exclude = function( obj ) { | ||
return !(obj instanceof Separator); | ||
return obj.type !== "separator"; | ||
}; | ||
@@ -36,0 +37,0 @@ |
@@ -12,2 +12,3 @@ /** | ||
var Choices = require("../objects/choices"); | ||
var tty = require("../utils/tty"); | ||
@@ -59,3 +60,5 @@ | ||
_.extend( Prompt.prototype, tty ); | ||
/** | ||
@@ -91,54 +94,2 @@ * Start the Inquiry session and manage output value filtering | ||
/** | ||
* Remove the prompt from screen | ||
* @param {Number} Extra lines to remove (probably to compensate the "enter" key line | ||
* return) | ||
* @return {Prompt} self | ||
*/ | ||
Prompt.prototype.clean = function( extra ) { | ||
_.isNumber(extra) || (extra = 0); | ||
var len = this.height + extra; | ||
while ( len-- ) { | ||
readline.moveCursor(this.rl.output, -clc.width, 0); | ||
readline.clearLine(this.rl.output, 0); | ||
if ( len ) readline.moveCursor(this.rl.output, 0, -1); | ||
} | ||
return this; | ||
}; | ||
/** | ||
* Move cursor down by `x` | ||
* @param {Number} x How far to go down (default to 1) | ||
* @return {Prompt} self | ||
*/ | ||
Prompt.prototype.down = function( x ) { | ||
_.isNumber(x) || (x = 1); | ||
// @bug: Write new lines instead of moving cursor as unix system don't allocate a new | ||
// line when the cursor is moved over there. | ||
while ( x-- ) { | ||
this.write("\n"); | ||
} | ||
return this; | ||
}; | ||
/** | ||
* Move cursor up by `x` | ||
* @param {Number} x How far to go up (default to 1) | ||
* @return {Prompt} self | ||
*/ | ||
Prompt.prototype.up = function( x ) { | ||
_.isNumber(x) || (x = 1); | ||
readline.moveCursor( this.rl.output, 0, -x ); | ||
return this; | ||
}; | ||
/** | ||
* Write error message | ||
@@ -245,59 +196,1 @@ * @param {String} Error Error message | ||
}; | ||
/** | ||
* Write a string to the stdout | ||
* @return {Self} | ||
*/ | ||
Prompt.prototype.write = function( str ) { | ||
this.rl.output.write( str ); | ||
return this; | ||
}; | ||
/** | ||
* Hide cursor | ||
* @return {Prompt} self | ||
*/ | ||
Prompt.prototype.hideCursor = function() { | ||
return this.write("\033[?25l"); | ||
}; | ||
/** | ||
* Show cursor | ||
* @return {Prompt} self | ||
*/ | ||
Prompt.prototype.showCursor = function() { | ||
return this.write("\033[?25h"); | ||
}; | ||
/** | ||
* Remember the cursor position | ||
* @return {Prompt} Self | ||
*/ | ||
Prompt.prototype.cacheCursorPos = function() { | ||
this.cursorPos = this.rl._getCursorPos(); | ||
return this; | ||
}; | ||
/** | ||
* Restore the cursor position to where it has been previously stored. | ||
* @return {Prompt} Self | ||
*/ | ||
Prompt.prototype.restoreCursorPos = function() { | ||
if ( !this.cursorPos ) return; | ||
var line = this.rl._prompt + this.rl.line; | ||
readline.moveCursor(this.rl.output, -line.length, 0); | ||
readline.moveCursor(this.rl.output, this.cursorPos.cols, 0); | ||
this.cursorPos = null; | ||
return this; | ||
}; | ||
@@ -31,2 +31,10 @@ /** | ||
if ( _.isArray(this.opt.default) ) { | ||
this.opt.choices.forEach(function( choice ) { | ||
if ( this.opt.default.indexOf(choice.value) >= 0 ) { | ||
choice.checked = true; | ||
} | ||
}, this); | ||
} | ||
this.firstRender = true; | ||
@@ -83,3 +91,3 @@ this.pointer = 0; | ||
if ( this.firstRender ) { | ||
message += clc.blackBright("(Press <space> to select)"); | ||
message += "(Press <space> to select)"; | ||
} | ||
@@ -186,3 +194,3 @@ | ||
this.choices.forEach(function( choice, i ) { | ||
if ( choice instanceof Separator ) { | ||
if ( choice.type === "separator" ) { | ||
separatorOffset++; | ||
@@ -189,0 +197,0 @@ output += " " + choice + "\n"; |
@@ -114,3 +114,3 @@ /** | ||
if ( choice instanceof Separator ) { | ||
if ( choice.type === "separator" ) { | ||
output += " " + choice; | ||
@@ -236,3 +236,3 @@ return; | ||
if ( choice instanceof Separator ) { | ||
if ( choice.type === "separator" ) { | ||
output += " " + choice; | ||
@@ -239,0 +239,0 @@ return; |
@@ -35,2 +35,4 @@ /** | ||
var def = this.opt.default; | ||
// Default being a Number | ||
if ( _.isNumber(def) && def >= 0 && def < this.opt.choices.realLength ) { | ||
@@ -40,2 +42,7 @@ this.selected = def; | ||
// Default being a String | ||
if ( _.isString(def) ) { | ||
this.selected = this.opt.choices.pluck("value").indexOf( def ); | ||
} | ||
this.opt.choices.setRender( listRender ); | ||
@@ -89,3 +96,3 @@ | ||
if ( this.firstRender ) { | ||
message += clc.blackBright("(Use arrow keys)"); | ||
message += "(Use arrow keys)"; | ||
} | ||
@@ -172,3 +179,3 @@ | ||
this.choices.forEach(function( choice, i ) { | ||
if ( choice instanceof Separator ) { | ||
if ( choice.type === "separator" ) { | ||
separatorOffset++; | ||
@@ -175,0 +182,0 @@ output += " " + choice + "\n"; |
@@ -163,3 +163,3 @@ /** | ||
if ( choice instanceof Separator ) { | ||
if ( choice.type === "separator" ) { | ||
separatorOffset++; | ||
@@ -166,0 +166,0 @@ output += " " + choice; |
{ | ||
"name": "inquirer", | ||
"version": "0.3.5", | ||
"version": "0.4.0", | ||
"description": "A collection of common interactive command line user interfaces.", | ||
@@ -22,6 +22,7 @@ "main": "lib/inquirer.js", | ||
"dependencies": { | ||
"lodash": "~1.2.1", | ||
"lodash": "~2.4.1", | ||
"async": "~0.2.8", | ||
"cli-color": "~0.2.2", | ||
"mute-stream": "0.0.3" | ||
"mute-stream": "0.0.4", | ||
"through": "~2.3.4" | ||
}, | ||
@@ -31,10 +32,11 @@ "devDependencies": { | ||
"grunt-cli": "~0.1.8", | ||
"grunt-simple-mocha": "~0.4.0", | ||
"mocha": "~1.9.0", | ||
"chai": "~1.6.0", | ||
"grunt-contrib-jshint": "~0.5.1", | ||
"mocha": "~1.15.1", | ||
"chai": "~1.8.1", | ||
"grunt-contrib-jshint": "~0.7.2", | ||
"sinon": "~1.7.2", | ||
"proxyquire": "~0.4.1", | ||
"grunt-release": "~0.3.3" | ||
"grunt-release": "~0.6.0", | ||
"mockery": "~1.4.0", | ||
"grunt-mocha-test": "~0.8.1", | ||
"cmdify": "0.0.4" | ||
} | ||
} |
@@ -69,3 +69,3 @@ Inquirer.js [![Build Status](https://travis-ci.org/SBoudrias/Inquirer.js.png?branch=master)](http://travis-ci.org/SBoudrias/Inquirer.js) | ||
+ **message**: (String) The question to print. | ||
+ **default**: (String|Function) Default value to use if nothing is entered, or a function that returns the default value. If defined as a function, the first parameter will be the current inquirer session answers. | ||
+ **default**: (String|Number|Array|Function) Default value(s) to use if nothing is entered, or a function that returns the default value(s). If defined as a function, the first parameter will be the current inquirer session answers. | ||
+ **choices**: (Array|Function) Choices array or a function returning a choices array. If defined as a function, the first parameter will be the current inquirer session answers. | ||
@@ -75,3 +75,3 @@ Array values can be simple `strings`, or `objects` containing a `name` (to display) and a `value` properties (to save in the answers hash). Values can also be [a `Separator`](#separator). | ||
+ **filter**: (Function) Receive the user input and return the filtered value to be used inside the program. The value returned will be added to the _Answers_ hash. | ||
+ **when**: (Function) Receive the current user answers hash and should return `true` or `false` depending on wheter or not this question should be asked. | ||
+ **when**: (Function) Receive the current user answers hash and should return `true` or `false` depending on whether or not this question should be asked. | ||
@@ -128,2 +128,4 @@ `validate`, `filter` and `when` functions can be asynchronously using `this.async()`. You just have to pass the value you'd normally return to the callback option. | ||
Separator instances have a property `type` equal to `separator`. This should allow tools façading Inquirer interface from detecting separator types in lists. | ||
Prompts type | ||
@@ -137,3 +139,3 @@ --------------------- | ||
Take `type`, `name`, `message`, `choices`[, `default`, `filter`] properties. (Note that | ||
default must be the choice `index` in the array) | ||
default must be the choice `index` in the array or a choice `value`) | ||
@@ -164,3 +166,3 @@ ![List prompt](https://dl.dropboxusercontent.com/u/59696254/inquirer/list-prompt.png) | ||
Take `type`, `name`, `message`, `choices`[, `filter`, `validate`] properties. | ||
Take `type`, `name`, `message`, `choices`[, `filter`, `validate`, `default`] properties. `default` is expected to be an Array of the checked choices value. | ||
@@ -189,4 +191,31 @@ Choices marked as `{ checked: true }` will be checked by default. | ||
User Interfaces and layouts | ||
--------------------- | ||
Along with the prompts, Inquirer offers some basic text UI. | ||
### Bottom Bar - `inquirer.ui.BottomBar` | ||
This UI present a fixed text at the bottom of a free text zone. This is useful to keep a message to the bottom of the screen while outputting command outputs on the higher section. | ||
``` | ||
var ui = new inquirer.ui.BottomBar(); | ||
// pipe a Stream to the log zone | ||
outputStream.pipe( ui.log ); | ||
// Or simply write output | ||
ui.log.write("something just happened."); | ||
ui.log.write("Almost over, standby!"); | ||
// During processing, update the bottom bar content to display a loader | ||
// or output a progress bar, etc | ||
ui.updateBottomBar("new bottom bar content"); | ||
``` | ||
### Prompt - `inquirer.ui.Prompt` | ||
This is UI layout used to run prompt. This layout is returned by `inquirer.prompt` and you should probably always use `inquirer.prompt` to interface with this UI. | ||
Support (OS - terminals) | ||
@@ -193,0 +222,0 @@ ===================== |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
258
58925
5
10
22
1680
+ Addedthrough@~2.3.4
+ Addedlodash@2.4.2(transitive)
+ Addedmute-stream@0.0.4(transitive)
+ Addedthrough@2.3.8(transitive)
- Removedlodash@1.2.1(transitive)
- Removedmute-stream@0.0.3(transitive)
Updatedlodash@~2.4.1
Updatedmute-stream@0.0.4