You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
113 lines
2.4 KiB
113 lines
2.4 KiB
|
|
module.exports = read |
|
|
|
var readline = require('readline') |
|
var Mute = require('mute-stream') |
|
|
|
function read (opts, cb) { |
|
if (opts.num) { |
|
throw new Error('read() no longer accepts a char number limit') |
|
} |
|
|
|
if (typeof opts.default !== 'undefined' && |
|
typeof opts.default !== 'string' && |
|
typeof opts.default !== 'number') { |
|
throw new Error('default value must be string or number') |
|
} |
|
|
|
var input = opts.input || process.stdin |
|
var output = opts.output || process.stdout |
|
var prompt = (opts.prompt || '').trim() + ' ' |
|
var silent = opts.silent |
|
var editDef = false |
|
var timeout = opts.timeout |
|
|
|
var def = opts.default || '' |
|
if (def) { |
|
if (silent) { |
|
prompt += '(<default hidden>) ' |
|
} else if (opts.edit) { |
|
editDef = true |
|
} else { |
|
prompt += '(' + def + ') ' |
|
} |
|
} |
|
var terminal = !!(opts.terminal || output.isTTY) |
|
|
|
var m = new Mute({ replace: opts.replace, prompt: prompt }) |
|
m.pipe(output, {end: false}) |
|
output = m |
|
var rlOpts = { input: input, output: output, terminal: terminal } |
|
|
|
if (process.version.match(/^v0\.6/)) { |
|
var rl = readline.createInterface(rlOpts.input, rlOpts.output) |
|
} else { |
|
var rl = readline.createInterface(rlOpts) |
|
} |
|
|
|
|
|
output.unmute() |
|
rl.setPrompt(prompt) |
|
rl.prompt() |
|
if (silent) { |
|
output.mute() |
|
} else if (editDef) { |
|
rl.line = def |
|
rl.cursor = def.length |
|
rl._refreshLine() |
|
} |
|
|
|
var called = false |
|
rl.on('line', onLine) |
|
rl.on('error', onError) |
|
|
|
rl.on('SIGINT', function () { |
|
rl.close() |
|
onError(new Error('canceled')) |
|
}) |
|
|
|
var timer |
|
if (timeout) { |
|
timer = setTimeout(function () { |
|
onError(new Error('timed out')) |
|
}, timeout) |
|
} |
|
|
|
function done () { |
|
called = true |
|
rl.close() |
|
|
|
if (process.version.match(/^v0\.6/)) { |
|
rl.input.removeAllListeners('data') |
|
rl.input.removeAllListeners('keypress') |
|
rl.input.pause() |
|
} |
|
|
|
clearTimeout(timer) |
|
output.mute() |
|
output.end() |
|
} |
|
|
|
function onError (er) { |
|
if (called) return |
|
done() |
|
return cb(er) |
|
} |
|
|
|
function onLine (line) { |
|
if (called) return |
|
if (silent && terminal) { |
|
output.unmute() |
|
output.write('\r\n') |
|
} |
|
done() |
|
// truncate the \n at the end. |
|
line = line.replace(/\r?\n$/, '') |
|
var isDefault = !!(editDef && line === def) |
|
if (def && !line) { |
|
isDefault = true |
|
line = def |
|
} |
|
cb(null, line, isDefault) |
|
} |
|
}
|
|
|