222 lines
6.5 KiB
Markdown
222 lines
6.5 KiB
Markdown
# readlineSync
|
|
|
|
Synchronous [Readline](http://nodejs.org/api/readline.html) for interactively running.
|
|
The interface is used with `process.stdin` and `process.stdout` in order to accept user input.
|
|
|
|
## Example
|
|
|
|
```js
|
|
var readlineSync = require('readline-sync');
|
|
var userName = readlineSync.question('May I have your name? :'); // Wait for user's response.
|
|
var favFood = readlineSync.question('Hi ' + userName + '! What is your favorite food? :');
|
|
console.log('Oh, ' + userName + ' likes ' + favFood + '!');
|
|
```
|
|
|
|
```shell
|
|
May I have your name? :AnSeki
|
|
Hi AnSeki! What is your favorite food? :chocolate
|
|
Oh, AnSeki likes chocolate!
|
|
```
|
|
|
|
## Installation
|
|
|
|
```
|
|
npm install readline-sync
|
|
```
|
|
|
|
## Methods
|
|
|
|
### question
|
|
|
|
```js
|
|
line = readlineSync.question([query[, options]])
|
|
```
|
|
|
|
Displays the `query` to the user, and then returns the user's response after it has been typed.
|
|
You can specify `options`. (see [Options](#options))
|
|
|
|
The `query` may be string, or may not be (e.g. number, Date, Object, etc.). This is converted to string (i.e. `toString` method is called) before it is displayed every time.
|
|
|
|
### prompt
|
|
|
|
```js
|
|
line = readlineSync.prompt([options])
|
|
```
|
|
|
|
Displays the current prompt (See `setPrompt` method) to the user, and then returns the user's response after it has been typed.
|
|
You can specify `options`. (see [Options](#options))
|
|
|
|
### setPrompt
|
|
|
|
```js
|
|
currentPrompt = readlineSync.setPrompt([prompt])
|
|
```
|
|
|
|
Sets the prompt, for example when you run `node` on the command line, you see `> `, which is node's prompt. (See `prompt` method)
|
|
|
|
The `prompt` may be string, or may not be (e.g. number, Date, Object, etc.). This is converted to string (i.e. `toString` method is called) before it is displayed every time.
|
|
For example, `[foo-directory]#` like a bash shell that show the current directory.
|
|
|
|
```js
|
|
// Object that has toString method.
|
|
readlineSync.setPrompt({
|
|
toString: function() {
|
|
return '[' + require('path').basename(process.cwd()) + ']# '; // Get and show current directory.
|
|
}
|
|
})
|
|
```
|
|
|
|
### setEncoding
|
|
|
|
```js
|
|
currentEncoding = readlineSync.setEncoding([encoding])
|
|
```
|
|
|
|
Set the encoding method of input (user's response) and output (`prompt` method and `question` method). Defaults to 'utf8'.
|
|
|
|
### setPrint
|
|
|
|
```js
|
|
readlineSync.setPrint([funcPrint])
|
|
```
|
|
|
|
The specified `funcPrint` Function is called when any outputs (`prompt` method and `question` method). Defaults to `undefined`.
|
|
The `funcPrint` is given two arguments the output text and `encoding`.
|
|
|
|
![sample](cl_01.png)
|
|
|
|
For example, this is used to pass plain texts to the Logger, when texts are colored.
|
|
|
|
```js
|
|
var readlineSync = require('readline-sync'),
|
|
user, pw, cmd;
|
|
require('colors');
|
|
|
|
readlineSync.setPrint(function(display, encoding) {
|
|
logger.log(display.stripColors); // Remove control characters.
|
|
});
|
|
|
|
console.log('Your account required.'.grey);
|
|
user = readlineSync.question('USER NAME'.white.inverse + ': ');
|
|
pw = readlineSync.question('PASSWORD'.white.inverse + ': ', {noEchoBack: true});
|
|
// Authorization ...
|
|
console.log(('Welcome, ' + user + '!').green.bold);
|
|
|
|
readlineSync.setPrompt('> '.bold.red);
|
|
cmd = readlineSync.prompt();
|
|
```
|
|
|
|
## Options
|
|
|
|
An `options` Object can be specified to `prompt` method and `question` method. This Object can have following properties.
|
|
|
|
### noEchoBack
|
|
|
|
Type: Boolean
|
|
Default: `false`
|
|
|
|
If `true` is specified, echo back is avoided. It is used to hide the secret text (e.g. password) which is typed by user on screen.
|
|
For example:
|
|
|
|
```js
|
|
password = readlineSync.question('PASSWORD :', {noEchoBack: true});
|
|
console.log('Login ...');
|
|
```
|
|
|
|
The typed text is not shown on screen.
|
|
|
|
```shell
|
|
PASSWORD :
|
|
Login ...
|
|
```
|
|
|
|
### noTrim
|
|
|
|
Type: Boolean
|
|
Default: `false`
|
|
|
|
By default, the leading and trailing white spaces are removed from typed text. If `true` is specified, those are not removed.
|
|
|
|
## With Task Runner
|
|
|
|
The easy way to control the flow of task runner by the user's response:
|
|
* [Grunt](http://gruntjs.com/) plugin: [grunt-confirm](https://github.com/anseki/grunt-confirm)
|
|
* [gulp](http://gulpjs.com/) plugin: [gulp-confirm](https://github.com/anseki/gulp-confirm)
|
|
|
|
If you want to control the flow of task runner (e.g. [Grunt](http://gruntjs.com/)), call readlineSync in a task callback that is called by task runner. Then the flow of tasks is paused and it is controlled by user.
|
|
|
|
Example: by using [grunt-task-helper](https://github.com/anseki/grunt-task-helper)
|
|
|
|
```shell
|
|
$ grunt
|
|
Running "fileCopy" task
|
|
Files already exist:
|
|
file-a.png
|
|
file-b.js
|
|
Overwrite? (y/n) :y
|
|
file-a.png copied.
|
|
file-b.js copied.
|
|
Done.
|
|
```
|
|
|
|
`Gruntfile.js`
|
|
|
|
```js
|
|
grunt.initConfig({
|
|
taskHelper: {
|
|
fileCopy: {
|
|
options: {
|
|
handlerByTask: function() {
|
|
// Abort the task if user don't want.
|
|
return readlineSync.question('Overwrite? (y/n) :')
|
|
.toLowerCase() === 'y';
|
|
// Or process.exit()
|
|
},
|
|
filesArray: []
|
|
},
|
|
...
|
|
}
|
|
},
|
|
copy: {
|
|
fileCopy: {
|
|
files: '<%= taskHelper.fileCopy.options.filesArray %>'
|
|
}
|
|
}
|
|
});
|
|
```
|
|
|
|
## Note
|
|
|
|
### Platforms
|
|
|
|
The your Node and OS may not support interactively reading from stdin. The stdin interfaces are different by platforms.
|
|
If in those platforms, an error is thrown.
|
|
|
|
```js
|
|
try {
|
|
answer = readlineSync.question('What is your favorite food? :');
|
|
} catch (e) {
|
|
console.error(e);
|
|
process.exit(1);
|
|
}
|
|
```
|
|
|
|
### Reading by shell
|
|
|
|
readlineSync tries reading from stdin by shell if it is needed. And, it use "piping via files" for synchronous running.
|
|
As everyone knows, "piping via files" is no good. It blocks event loop and a process. It may make your script be slow.
|
|
|
|
Why did I choose it? :
|
|
|
|
+ The best solution is [child_process.execSync](https://github.com/joyent/node/blob/master/doc/api/child_process.markdown#child_processexecsynccommand-options) in core modules of Node. But it is not supported by current version.
|
|
+ The good modules (native addon) for synchronous execution exist. But node-gyp can't compile those in some platforms or Node versions.
|
|
+ I think that the security is important more than the speed. Some modules have problem about security. (Those don't protect data.) I think that the speed is not needed usually, because readlineSync is used while user types keys.
|
|
|
|
Someday, I may rewrite readlineSync to use child_process.execSync, or safety module.
|
|
|
|
## Release History
|
|
* 2015-01-27 v0.5.0 Add `options.noTrim`.
|
|
* 2014-07-12 v0.4.0 Add `options.noEchoBack`.
|
|
* 2014-07-12 v0.3.0 Add `setPrint()`.
|
|
* 2013-08-30 v0.2.0 Rewrite exporting methods.
|
|
* 2013-08-29 v0.1.0 Initial release.
|