read.js
2.37 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
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)
}
}