UNPKG

cli-input

Version:

Prompt and user input library.

183 lines (150 loc) 3.76 kB
var readline , rl , rlopts , history; var Mute = process.env.NODE_ENV === 'test-mute' ? require('mute-stream') : require('./mute'); var errors = { cancel: new Error('cancelled'), timeout: new Error('timed out') } errors.cancel.cancel = true; errors.timeout.timeout = true; function getReadline() { var ver = process.version.replace(/^v/, ''); var vers = ver.split('.'); var minor = parseInt(vers[1]); // use readline version imported from v0.11.x if(minor < 11 && !process.env.CLI_INPUT_NO_READLINE_PATCH) { readline = require('./patch')(); }else{ readline = require('readline'); } } function open(opts) { //console.log('opening rl interface %j', history); getReadline(); close(); opts = opts || {}; opts.input = opts.input || process.stdin opts.output = opts.output || process.stdout opts.terminal = !!(opts.terminal || opts.output.isTTY) rl = readline.createInterface(opts) if(history) { rl.history = history.slice(0); } rlopts = opts; return rl; } function close() { if(rl) { rl.close(); rl.removeAllListeners(); rl = null; } } function read (opts, cb) { var input = opts.input || process.stdin var output = opts.output || process.stdout opts.rl = opts.rl || {}; var prompt = (opts.prompt || ''); var silent = opts.silent var timeout = opts.timeout , rlopts , m; var def = '' + opts.default || ''; var terminal = !!(opts.terminal || output.isTTY) var mrl; if(!rl) { open(opts.rl); } if(silent) { m = new Mute( { replace: opts.replace, prompt: prompt, length: opts.length || prompt.length }) m.pipe(output, {end: false}) output = m; history = rl.history; rl.close(); mrl = readline.createInterface( {input: input, output: output, terminal: terminal}); rl = mrl; }else{ history = rl.history; } rl.setPrompt(prompt, opts.length || prompt.length); rl.prompt(); if(silent) { output.mute() }else if(opts.value) { rl.line = '' + opts.value; rl.cursor = opts.value.length; //console.log('has value %s', opts.value); //console.log('has value length %s', opts.value.length); //rl.cursor = 0; rl._refreshLine(); // value is always a one shot deal opts.value = null; } var timer; rl.on('line', onLine); rl.on('error', onError); function onsigint() { if(rl) rl.close() onError(errors.cancel); //process.emit('SIGINT'); } //rl.on('SIGINIT', onsigint); process.on('SIGINT', onsigint); if(timeout) { timer = setTimeout(function () { onError(errors.timeout) }, timeout) } if(opts.emitter) { opts.emitter.emit('ready', opts, rl); } function done (err, line) { rl.removeListener('line', onLine); rl.removeListener('error', onError); process.removeListener('SIGINT', onsigint); // keep reference before closing // so we can pass to the callback var interface = rl; clearTimeout(timer); if(silent) { mrl.close(); //rl.resume(); //opts.rl.output = process.stdout; output.unmute() output.end() close(); } // get *undefined* string from mute stream on no input if(silent && line == "undefined") line = ''; if(err) return cb(err, null, interface); cb(null, line, interface); } function onError (err) { done(err); } function onLine (line) { if(silent) { output.unmute() //output.write('\r\n') } // truncate the \n at the end. line = line.replace(/\r?\n$/, '') if(!line && opts.default) { line = opts.default; } done(null, line); } } read.open = open; read.errors = errors; read.rl = rl; module.exports = read;