@socketsecurity/cli-with-sentry 0.14.137 → 0.14.138
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/blessed/LICENSE +20 -0
- package/dist/blessed/lib/alias.js +519 -0
- package/dist/blessed/lib/blessed.js +32 -0
- package/dist/blessed/lib/colors.js +490 -0
- package/dist/blessed/lib/events.js +195 -0
- package/dist/blessed/lib/gpmclient.js +245 -0
- package/dist/blessed/lib/helpers.js +170 -0
- package/dist/blessed/lib/keys.js +512 -0
- package/dist/blessed/lib/program.js +4530 -0
- package/dist/blessed/lib/tput.js +3111 -0
- package/dist/blessed/lib/unicode.js +912 -0
- package/dist/blessed/lib/widget.js +60 -0
- package/dist/blessed/lib/widgets/ansiimage.js +173 -0
- package/dist/blessed/lib/widgets/bigtext.js +170 -0
- package/dist/blessed/lib/widgets/box.js +34 -0
- package/dist/blessed/lib/widgets/button.js +62 -0
- package/dist/blessed/lib/widgets/checkbox.js +95 -0
- package/dist/blessed/lib/widgets/element.js +2871 -0
- package/dist/blessed/lib/widgets/filemanager.js +223 -0
- package/dist/blessed/lib/widgets/form.js +301 -0
- package/dist/blessed/lib/widgets/image.js +71 -0
- package/dist/blessed/lib/widgets/input.js +34 -0
- package/dist/blessed/lib/widgets/layout.js +249 -0
- package/dist/blessed/lib/widgets/line.js +59 -0
- package/dist/blessed/lib/widgets/list.js +652 -0
- package/dist/blessed/lib/widgets/listbar.js +452 -0
- package/dist/blessed/lib/widgets/listtable.js +265 -0
- package/dist/blessed/lib/widgets/loading.js +88 -0
- package/dist/blessed/lib/widgets/log.js +82 -0
- package/dist/blessed/lib/widgets/message.js +145 -0
- package/dist/blessed/lib/widgets/node.js +314 -0
- package/dist/blessed/lib/widgets/overlayimage.js +794 -0
- package/dist/blessed/lib/widgets/progressbar.js +166 -0
- package/dist/blessed/lib/widgets/prompt.js +127 -0
- package/dist/blessed/lib/widgets/question.js +129 -0
- package/dist/blessed/lib/widgets/radiobutton.js +62 -0
- package/dist/blessed/lib/widgets/radioset.js +36 -0
- package/dist/blessed/lib/widgets/screen.js +2485 -0
- package/dist/blessed/lib/widgets/scrollablebox.js +415 -0
- package/dist/blessed/lib/widgets/scrollabletext.js +35 -0
- package/dist/blessed/lib/widgets/table.js +383 -0
- package/dist/blessed/lib/widgets/terminal.js +452 -0
- package/dist/blessed/lib/widgets/text.js +35 -0
- package/dist/blessed/lib/widgets/textarea.js +376 -0
- package/dist/blessed/lib/widgets/textbox.js +79 -0
- package/dist/blessed/lib/widgets/video.js +130 -0
- package/dist/blessed/usr/fonts/AUTHORS +1 -0
- package/dist/blessed/usr/fonts/LICENSE +94 -0
- package/dist/blessed/usr/fonts/README +340 -0
- package/dist/blessed/usr/fonts/ter-u14b.json +17826 -0
- package/dist/blessed/usr/fonts/ter-u14n.json +17826 -0
- package/dist/blessed/usr/linux +0 -0
- package/dist/blessed/usr/windows-ansi +0 -0
- package/dist/blessed/usr/xterm +0 -0
- package/dist/blessed/usr/xterm-256color +0 -0
- package/dist/blessed/usr/xterm.termcap +243 -0
- package/dist/blessed/usr/xterm.terminfo +1977 -0
- package/dist/blessed/vendor/tng.js +1876 -0
- package/dist/blessed-contrib/LICENSE.md +21 -0
- package/dist/blessed-contrib/lib/layout/carousel.js +82 -0
- package/dist/blessed-contrib/lib/layout/grid.js +46 -0
- package/dist/blessed-contrib/lib/server-utils.js +83 -0
- package/dist/blessed-contrib/lib/utils.js +73 -0
- package/dist/blessed-contrib/lib/widget/canvas.js +52 -0
- package/dist/blessed-contrib/lib/widget/charts/bar.js +99 -0
- package/dist/blessed-contrib/lib/widget/charts/line.js +311 -0
- package/dist/blessed-contrib/lib/widget/charts/stacked-bar.js +245 -0
- package/dist/blessed-contrib/lib/widget/donut.js +183 -0
- package/dist/blessed-contrib/lib/widget/gauge-list.js +111 -0
- package/dist/blessed-contrib/lib/widget/gauge.js +127 -0
- package/dist/blessed-contrib/lib/widget/lcd.js +497 -0
- package/dist/blessed-contrib/lib/widget/log.js +32 -0
- package/dist/blessed-contrib/lib/widget/map.js +97 -0
- package/dist/blessed-contrib/lib/widget/markdown.js +68 -0
- package/dist/blessed-contrib/lib/widget/picture.js +61 -0
- package/dist/blessed-contrib/lib/widget/sparkline.js +66 -0
- package/dist/blessed-contrib/lib/widget/table.js +141 -0
- package/dist/blessed-contrib/lib/widget/tree.js +179 -0
- package/dist/blessed-contrib/node_modules/ansi-regex/index.js +6 -0
- package/dist/blessed-contrib/node_modules/ansi-regex/license +21 -0
- package/dist/blessed-contrib/node_modules/ansi-regex/package.json +64 -0
- package/dist/blessed-contrib/node_modules/ansi-regex/readme.md +39 -0
- package/dist/blessed-contrib/node_modules/ansi-styles/index.js +67 -0
- package/dist/blessed-contrib/node_modules/ansi-styles/license +21 -0
- package/dist/blessed-contrib/node_modules/ansi-styles/package.json +50 -0
- package/dist/blessed-contrib/node_modules/ansi-styles/readme.md +86 -0
- package/dist/blessed-contrib/node_modules/chalk/index.js +118 -0
- package/dist/blessed-contrib/node_modules/chalk/license +21 -0
- package/dist/blessed-contrib/node_modules/chalk/package.json +70 -0
- package/dist/blessed-contrib/node_modules/chalk/readme.md +213 -0
- package/dist/blessed-contrib/node_modules/escape-string-regexp/index.js +13 -0
- package/dist/blessed-contrib/node_modules/escape-string-regexp/license +21 -0
- package/dist/blessed-contrib/node_modules/escape-string-regexp/package.json +41 -0
- package/dist/blessed-contrib/node_modules/escape-string-regexp/readme.md +27 -0
- package/dist/blessed-contrib/node_modules/strip-ansi/index.js +8 -0
- package/dist/blessed-contrib/node_modules/strip-ansi/license +21 -0
- package/dist/blessed-contrib/node_modules/strip-ansi/package.json +57 -0
- package/dist/blessed-contrib/node_modules/strip-ansi/readme.md +33 -0
- package/dist/blessed-contrib/node_modules/supports-color/index.js +52 -0
- package/dist/blessed-contrib/node_modules/supports-color/license +21 -0
- package/dist/blessed-contrib/node_modules/supports-color/package.json +49 -0
- package/dist/blessed-contrib/node_modules/supports-color/readme.md +36 -0
- package/dist/cli.js +9 -8
- package/dist/cli.js.map +1 -1
- package/dist/instrument-with-sentry.js +2 -2
- package/dist/instrument-with-sentry.js.map +1 -1
- package/dist/shadow-npm-inject.js +2 -2
- package/dist/shadow-npm-inject.js.map +1 -1
- package/package.json +4 -4
|
@@ -0,0 +1,4530 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* program.js - basic curses-like functionality for blessed.
|
|
3
|
+
* Copyright (c) 2013-2015, Christopher Jeffrey and contributors (MIT License).
|
|
4
|
+
* https://github.com/chjj/blessed
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Modules
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
const EventEmitter = require('node:events').EventEmitter,
|
|
12
|
+
StringDecoder = require('node:string_decoder').StringDecoder,
|
|
13
|
+
cp = require('node:child_process'),
|
|
14
|
+
util = require('node:util'),
|
|
15
|
+
fs = require('node:fs')
|
|
16
|
+
|
|
17
|
+
const Tput = require('./tput'),
|
|
18
|
+
colors = require('./colors'),
|
|
19
|
+
slice = Array.prototype.slice
|
|
20
|
+
|
|
21
|
+
const nextTick = global.setImmediate || process.nextTick.bind(process)
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Program
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
function Program(options) {
|
|
28
|
+
const self = this
|
|
29
|
+
|
|
30
|
+
if (!(this instanceof Program)) {
|
|
31
|
+
return new Program(options)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
Program.bind(this)
|
|
35
|
+
|
|
36
|
+
EventEmitter.call(this)
|
|
37
|
+
|
|
38
|
+
if (!options || Object.getPrototypeOf(options) !== Object.prototype) {
|
|
39
|
+
options = {
|
|
40
|
+
input: arguments[0],
|
|
41
|
+
output: arguments[1]
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
this.options = options
|
|
46
|
+
this.input = options.input || process.stdin
|
|
47
|
+
this.output = options.output || process.stdout
|
|
48
|
+
|
|
49
|
+
options.log = options.log || options.dump
|
|
50
|
+
if (options.log) {
|
|
51
|
+
this._logger = fs.createWriteStream(options.log)
|
|
52
|
+
if (options.dump) {
|
|
53
|
+
this.setupDump()
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
this.zero = options.zero !== false
|
|
58
|
+
this.useBuffer = options.buffer
|
|
59
|
+
|
|
60
|
+
this.x = 0
|
|
61
|
+
this.y = 0
|
|
62
|
+
this.savedX = 0
|
|
63
|
+
this.savedY = 0
|
|
64
|
+
|
|
65
|
+
this.cols = this.output.columns || 1
|
|
66
|
+
this.rows = this.output.rows || 1
|
|
67
|
+
|
|
68
|
+
this.scrollTop = 0
|
|
69
|
+
this.scrollBottom = this.rows - 1
|
|
70
|
+
|
|
71
|
+
this._terminal =
|
|
72
|
+
options.terminal ||
|
|
73
|
+
options.term ||
|
|
74
|
+
process.env.TERM ||
|
|
75
|
+
(process.platform === 'win32' ? 'windows-ansi' : 'xterm')
|
|
76
|
+
|
|
77
|
+
this._terminal = this._terminal.toLowerCase()
|
|
78
|
+
|
|
79
|
+
// OSX
|
|
80
|
+
this.isOSXTerm = process.env.TERM_PROGRAM === 'Apple_Terminal'
|
|
81
|
+
this.isiTerm2 =
|
|
82
|
+
process.env.TERM_PROGRAM === 'iTerm.app' || !!process.env.ITERM_SESSION_ID
|
|
83
|
+
|
|
84
|
+
// VTE
|
|
85
|
+
// NOTE: lxterminal does not provide an env variable to check for.
|
|
86
|
+
// NOTE: gnome-terminal and sakura use a later version of VTE
|
|
87
|
+
// which provides VTE_VERSION as well as supports SGR events.
|
|
88
|
+
this.isXFCE = /xfce/i.test(process.env.COLORTERM)
|
|
89
|
+
this.isTerminator = !!process.env.TERMINATOR_UUID
|
|
90
|
+
this.isLXDE = false
|
|
91
|
+
this.isVTE =
|
|
92
|
+
!!process.env.VTE_VERSION || this.isXFCE || this.isTerminator || this.isLXDE
|
|
93
|
+
|
|
94
|
+
// xterm and rxvt - not accurate
|
|
95
|
+
this.isRxvt = /rxvt/i.test(process.env.COLORTERM)
|
|
96
|
+
this.isXterm = false
|
|
97
|
+
|
|
98
|
+
this.tmux = !!process.env.TMUX
|
|
99
|
+
this.tmuxVersion = (function () {
|
|
100
|
+
if (!self.tmux) {
|
|
101
|
+
return 2
|
|
102
|
+
}
|
|
103
|
+
try {
|
|
104
|
+
const version = cp.execFileSync('tmux', ['-V'], { encoding: 'utf8' })
|
|
105
|
+
return +/^tmux ([\d.]+)/i.exec(version.trim().split('\n')[0])[1]
|
|
106
|
+
} catch (e) {
|
|
107
|
+
return 2
|
|
108
|
+
}
|
|
109
|
+
})()
|
|
110
|
+
|
|
111
|
+
this._buf = ''
|
|
112
|
+
this._flush = this.flush.bind(this)
|
|
113
|
+
|
|
114
|
+
if (options.tput !== false) {
|
|
115
|
+
this.setupTput()
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
this.listen()
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
Program.global = null
|
|
122
|
+
|
|
123
|
+
Program.total = 0
|
|
124
|
+
|
|
125
|
+
Program.instances = []
|
|
126
|
+
|
|
127
|
+
Program.bind = function (program) {
|
|
128
|
+
if (!Program.global) {
|
|
129
|
+
Program.global = program
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if (!~Program.instances.indexOf(program)) {
|
|
133
|
+
Program.instances.push(program)
|
|
134
|
+
program.index = Program.total
|
|
135
|
+
Program.total++
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
if (Program._bound) {
|
|
139
|
+
return
|
|
140
|
+
}
|
|
141
|
+
Program._bound = true
|
|
142
|
+
|
|
143
|
+
unshiftEvent(
|
|
144
|
+
process,
|
|
145
|
+
'exit',
|
|
146
|
+
(Program._exitHandler = function () {
|
|
147
|
+
Program.instances.forEach(function (program) {
|
|
148
|
+
// Potentially reset window title on exit:
|
|
149
|
+
// if (program._originalTitle) {
|
|
150
|
+
// program.setTitle(program._originalTitle);
|
|
151
|
+
// }
|
|
152
|
+
// Ensure the buffer is flushed (it should
|
|
153
|
+
// always be at this point, but who knows).
|
|
154
|
+
program.flush()
|
|
155
|
+
// Ensure _exiting is set (could technically
|
|
156
|
+
// use process._exiting).
|
|
157
|
+
program._exiting = true
|
|
158
|
+
})
|
|
159
|
+
})
|
|
160
|
+
)
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
Object.setPrototypeOf(Program.prototype, EventEmitter.prototype)
|
|
164
|
+
|
|
165
|
+
Program.prototype.type = 'program'
|
|
166
|
+
|
|
167
|
+
Program.prototype.log = function () {
|
|
168
|
+
return this._log('LOG', util.format.apply(util, arguments))
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
Program.prototype.debug = function () {
|
|
172
|
+
if (!this.options.debug) {
|
|
173
|
+
return
|
|
174
|
+
}
|
|
175
|
+
return this._log('DEBUG', util.format.apply(util, arguments))
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
Program.prototype._log = function (pre, msg) {
|
|
179
|
+
if (!this._logger) {
|
|
180
|
+
return
|
|
181
|
+
}
|
|
182
|
+
return this._logger.write(pre + ': ' + msg + '\n-\n')
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
Program.prototype.setupDump = function () {
|
|
186
|
+
const self = this,
|
|
187
|
+
write = this.output.write,
|
|
188
|
+
decoder = new StringDecoder('utf8')
|
|
189
|
+
|
|
190
|
+
function stringify(data) {
|
|
191
|
+
return caret(
|
|
192
|
+
data.replace(/\r/g, '\\r').replace(/\n/g, '\\n').replace(/\t/g, '\\t')
|
|
193
|
+
).replace(/[^ -~]/g, function (ch) {
|
|
194
|
+
if (ch.charCodeAt(0) > 0xff) {
|
|
195
|
+
return ch
|
|
196
|
+
}
|
|
197
|
+
ch = ch.charCodeAt(0).toString(16)
|
|
198
|
+
if (ch.length > 2) {
|
|
199
|
+
if (ch.length < 4) {
|
|
200
|
+
ch = '0' + ch
|
|
201
|
+
}
|
|
202
|
+
return '\\u' + ch
|
|
203
|
+
}
|
|
204
|
+
if (ch.length < 2) {
|
|
205
|
+
ch = '0' + ch
|
|
206
|
+
}
|
|
207
|
+
return '\\x' + ch
|
|
208
|
+
})
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
function caret(data) {
|
|
212
|
+
return data.replace(/[\0\x80\x1b-\x1f\x7f\x01-\x1a]/g, function (ch) {
|
|
213
|
+
switch (ch) {
|
|
214
|
+
case '\0':
|
|
215
|
+
case '\x80':
|
|
216
|
+
ch = '@'
|
|
217
|
+
break
|
|
218
|
+
case '\x1b':
|
|
219
|
+
ch = '['
|
|
220
|
+
break
|
|
221
|
+
case '\x1c':
|
|
222
|
+
ch = '\\'
|
|
223
|
+
break
|
|
224
|
+
case '\x1d':
|
|
225
|
+
ch = ']'
|
|
226
|
+
break
|
|
227
|
+
case '\x1e':
|
|
228
|
+
ch = '^'
|
|
229
|
+
break
|
|
230
|
+
case '\x1f':
|
|
231
|
+
ch = '_'
|
|
232
|
+
break
|
|
233
|
+
case '\x7f':
|
|
234
|
+
ch = '?'
|
|
235
|
+
break
|
|
236
|
+
default:
|
|
237
|
+
ch = ch.charCodeAt(0)
|
|
238
|
+
// From ('A' - 64) to ('Z' - 64).
|
|
239
|
+
if (ch >= 1 && ch <= 26) {
|
|
240
|
+
ch = String.fromCharCode(ch + 64)
|
|
241
|
+
} else {
|
|
242
|
+
return String.fromCharCode(ch)
|
|
243
|
+
}
|
|
244
|
+
break
|
|
245
|
+
}
|
|
246
|
+
return '^' + ch
|
|
247
|
+
})
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
this.input.on('data', function (data) {
|
|
251
|
+
self._log('IN', stringify(decoder.write(data)))
|
|
252
|
+
})
|
|
253
|
+
|
|
254
|
+
this.output.write = function (data) {
|
|
255
|
+
self._log('OUT', stringify(data))
|
|
256
|
+
return write.apply(this, arguments)
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
Program.prototype.setupTput = function () {
|
|
261
|
+
if (this._tputSetup) {
|
|
262
|
+
return
|
|
263
|
+
}
|
|
264
|
+
this._tputSetup = true
|
|
265
|
+
|
|
266
|
+
const self = this,
|
|
267
|
+
options = this.options,
|
|
268
|
+
write = this._write.bind(this)
|
|
269
|
+
|
|
270
|
+
const tput = (this.tput = new Tput({
|
|
271
|
+
terminal: this.terminal,
|
|
272
|
+
padding: options.padding,
|
|
273
|
+
extended: options.extended,
|
|
274
|
+
printf: options.printf,
|
|
275
|
+
termcap: options.termcap,
|
|
276
|
+
forceUnicode: options.forceUnicode
|
|
277
|
+
}))
|
|
278
|
+
|
|
279
|
+
if (tput.error) {
|
|
280
|
+
nextTick(function () {
|
|
281
|
+
self.emit('warning', tput.error.message)
|
|
282
|
+
})
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
if (tput.padding) {
|
|
286
|
+
nextTick(function () {
|
|
287
|
+
self.emit('warning', 'Terminfo padding has been enabled.')
|
|
288
|
+
})
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
this.put = function () {
|
|
292
|
+
const args = slice.call(arguments),
|
|
293
|
+
cap = args.shift()
|
|
294
|
+
|
|
295
|
+
if (tput[cap]) {
|
|
296
|
+
return this._write(tput[cap].apply(tput, args))
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
Object.keys(tput).forEach(function (key) {
|
|
301
|
+
if (self[key] == null) {
|
|
302
|
+
self[key] = tput[key]
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
if (typeof tput[key] !== 'function') {
|
|
306
|
+
self.put[key] = tput[key]
|
|
307
|
+
return
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
if (tput.padding) {
|
|
311
|
+
self.put[key] = function () {
|
|
312
|
+
return tput._print(tput[key].apply(tput, arguments), write)
|
|
313
|
+
}
|
|
314
|
+
} else {
|
|
315
|
+
self.put[key] = function () {
|
|
316
|
+
return self._write(tput[key].apply(tput, arguments))
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
})
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
Program.prototype.__defineGetter__('terminal', function () {
|
|
323
|
+
return this._terminal
|
|
324
|
+
})
|
|
325
|
+
|
|
326
|
+
Program.prototype.__defineSetter__('terminal', function (terminal) {
|
|
327
|
+
this.setTerminal(terminal)
|
|
328
|
+
return this.terminal
|
|
329
|
+
})
|
|
330
|
+
|
|
331
|
+
Program.prototype.setTerminal = function (terminal) {
|
|
332
|
+
this._terminal = terminal.toLowerCase()
|
|
333
|
+
delete this._tputSetup
|
|
334
|
+
this.setupTput()
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
Program.prototype.has = function (name) {
|
|
338
|
+
return this.tput ? this.tput.has(name) : false
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
Program.prototype.term = function (is) {
|
|
342
|
+
return this.terminal.indexOf(is) === 0
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
Program.prototype.listen = function () {
|
|
346
|
+
const self = this
|
|
347
|
+
|
|
348
|
+
// Potentially reset window title on exit:
|
|
349
|
+
// if (!this.isRxvt) {
|
|
350
|
+
// if (!this.isVTE) this.setTitleModeFeature(3);
|
|
351
|
+
// this.manipulateWindow(21, function(err, data) {
|
|
352
|
+
// if (err) return;
|
|
353
|
+
// self._originalTitle = data.text;
|
|
354
|
+
// });
|
|
355
|
+
// }
|
|
356
|
+
|
|
357
|
+
// Listen for keys/mouse on input
|
|
358
|
+
if (!this.input._blessedInput) {
|
|
359
|
+
this.input._blessedInput = 1
|
|
360
|
+
this._listenInput()
|
|
361
|
+
} else {
|
|
362
|
+
this.input._blessedInput++
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
this.on(
|
|
366
|
+
'newListener',
|
|
367
|
+
(this._newHandler = function fn(type) {
|
|
368
|
+
if (type === 'keypress' || type === 'mouse') {
|
|
369
|
+
self.removeListener('newListener', fn)
|
|
370
|
+
if (self.input.setRawMode && !self.input.isRaw) {
|
|
371
|
+
self.input.setRawMode(true)
|
|
372
|
+
self.input.resume()
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
})
|
|
376
|
+
)
|
|
377
|
+
|
|
378
|
+
this.on('newListener', function fn(type) {
|
|
379
|
+
if (type === 'mouse') {
|
|
380
|
+
self.removeListener('newListener', fn)
|
|
381
|
+
self.bindMouse()
|
|
382
|
+
}
|
|
383
|
+
})
|
|
384
|
+
|
|
385
|
+
// Listen for resize on output
|
|
386
|
+
if (!this.output._blessedOutput) {
|
|
387
|
+
this.output._blessedOutput = 1
|
|
388
|
+
this._listenOutput()
|
|
389
|
+
} else {
|
|
390
|
+
this.output._blessedOutput++
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
Program.prototype._listenInput = function () {
|
|
395
|
+
const keys = require('./keys'),
|
|
396
|
+
self = this
|
|
397
|
+
|
|
398
|
+
// Input
|
|
399
|
+
this.input.on(
|
|
400
|
+
'keypress',
|
|
401
|
+
(this.input._keypressHandler = function (ch, key) {
|
|
402
|
+
key = key || { ch: ch }
|
|
403
|
+
|
|
404
|
+
if (
|
|
405
|
+
key.name === 'undefined' &&
|
|
406
|
+
(key.code === '[M' || key.code === '[I' || key.code === '[O')
|
|
407
|
+
) {
|
|
408
|
+
// A mouse sequence. The `keys` module doesn't understand these.
|
|
409
|
+
return
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
if (key.name === 'undefined') {
|
|
413
|
+
// Not sure what this is, but we should probably ignore it.
|
|
414
|
+
return
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
if (key.name === 'enter' && key.sequence === '\n') {
|
|
418
|
+
key.name = 'linefeed'
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
if (key.name === 'return' && key.sequence === '\r') {
|
|
422
|
+
self.input.emit('keypress', ch, merge({}, key, { name: 'enter' }))
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
const name =
|
|
426
|
+
(key.ctrl ? 'C-' : '') +
|
|
427
|
+
(key.meta ? 'M-' : '') +
|
|
428
|
+
(key.shift && key.name ? 'S-' : '') +
|
|
429
|
+
(key.name || ch)
|
|
430
|
+
|
|
431
|
+
key.full = name
|
|
432
|
+
|
|
433
|
+
Program.instances.forEach(function (program) {
|
|
434
|
+
if (program.input !== self.input) {
|
|
435
|
+
return
|
|
436
|
+
}
|
|
437
|
+
program.emit('keypress', ch, key)
|
|
438
|
+
program.emit('key ' + name, ch, key)
|
|
439
|
+
})
|
|
440
|
+
})
|
|
441
|
+
)
|
|
442
|
+
|
|
443
|
+
this.input.on(
|
|
444
|
+
'data',
|
|
445
|
+
(this.input._dataHandler = function (data) {
|
|
446
|
+
Program.instances.forEach(function (program) {
|
|
447
|
+
if (program.input !== self.input) {
|
|
448
|
+
return
|
|
449
|
+
}
|
|
450
|
+
program.emit('data', data)
|
|
451
|
+
})
|
|
452
|
+
})
|
|
453
|
+
)
|
|
454
|
+
|
|
455
|
+
keys.emitKeypressEvents(this.input)
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
Program.prototype._listenOutput = function () {
|
|
459
|
+
const self = this
|
|
460
|
+
|
|
461
|
+
if (!this.output.isTTY) {
|
|
462
|
+
nextTick(function () {
|
|
463
|
+
self.emit('warning', 'Output is not a TTY')
|
|
464
|
+
})
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
// Output
|
|
468
|
+
function resize() {
|
|
469
|
+
Program.instances.forEach(function (program) {
|
|
470
|
+
if (program.output !== self.output) {
|
|
471
|
+
return
|
|
472
|
+
}
|
|
473
|
+
program.cols = program.output.columns
|
|
474
|
+
program.rows = program.output.rows
|
|
475
|
+
program.emit('resize')
|
|
476
|
+
})
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
this.output.on(
|
|
480
|
+
'resize',
|
|
481
|
+
(this.output._resizeHandler = function () {
|
|
482
|
+
Program.instances.forEach(function (program) {
|
|
483
|
+
if (program.output !== self.output) {
|
|
484
|
+
return
|
|
485
|
+
}
|
|
486
|
+
if (!program.options.resizeTimeout) {
|
|
487
|
+
return resize()
|
|
488
|
+
}
|
|
489
|
+
if (program._resizeTimer) {
|
|
490
|
+
clearTimeout(program._resizeTimer)
|
|
491
|
+
delete program._resizeTimer
|
|
492
|
+
}
|
|
493
|
+
const time =
|
|
494
|
+
typeof program.options.resizeTimeout === 'number'
|
|
495
|
+
? program.options.resizeTimeout
|
|
496
|
+
: 300
|
|
497
|
+
program._resizeTimer = setTimeout(resize, time)
|
|
498
|
+
})
|
|
499
|
+
})
|
|
500
|
+
)
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
Program.prototype.destroy = function () {
|
|
504
|
+
const index = Program.instances.indexOf(this)
|
|
505
|
+
|
|
506
|
+
if (~index) {
|
|
507
|
+
Program.instances.splice(index, 1)
|
|
508
|
+
Program.total--
|
|
509
|
+
|
|
510
|
+
this.flush()
|
|
511
|
+
this._exiting = true
|
|
512
|
+
|
|
513
|
+
Program.global = Program.instances[0]
|
|
514
|
+
|
|
515
|
+
if (Program.total === 0) {
|
|
516
|
+
Program.global = null
|
|
517
|
+
|
|
518
|
+
process.removeListener('exit', Program._exitHandler)
|
|
519
|
+
delete Program._exitHandler
|
|
520
|
+
|
|
521
|
+
delete Program._bound
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
this.input._blessedInput--
|
|
525
|
+
this.output._blessedOutput--
|
|
526
|
+
|
|
527
|
+
if (this.input._blessedInput === 0) {
|
|
528
|
+
this.input.removeListener('keypress', this.input._keypressHandler)
|
|
529
|
+
this.input.removeListener('data', this.input._dataHandler)
|
|
530
|
+
delete this.input._keypressHandler
|
|
531
|
+
delete this.input._dataHandler
|
|
532
|
+
|
|
533
|
+
if (this.input.setRawMode) {
|
|
534
|
+
if (this.input.isRaw) {
|
|
535
|
+
this.input.setRawMode(false)
|
|
536
|
+
}
|
|
537
|
+
if (!this.input.destroyed) {
|
|
538
|
+
this.input.pause()
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
if (this.output._blessedOutput === 0) {
|
|
544
|
+
this.output.removeListener('resize', this.output._resizeHandler)
|
|
545
|
+
delete this.output._resizeHandler
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
this.removeListener('newListener', this._newHandler)
|
|
549
|
+
delete this._newHandler
|
|
550
|
+
|
|
551
|
+
this.destroyed = true
|
|
552
|
+
this.emit('destroy')
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
Program.prototype.key = function (key, listener) {
|
|
557
|
+
if (typeof key === 'string') {
|
|
558
|
+
key = key.split(/\s*,\s*/)
|
|
559
|
+
}
|
|
560
|
+
key.forEach(function (key) {
|
|
561
|
+
return this.on('key ' + key, listener)
|
|
562
|
+
}, this)
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
Program.prototype.onceKey = function (key, listener) {
|
|
566
|
+
if (typeof key === 'string') {
|
|
567
|
+
key = key.split(/\s*,\s*/)
|
|
568
|
+
}
|
|
569
|
+
key.forEach(function (key) {
|
|
570
|
+
return this.once('key ' + key, listener)
|
|
571
|
+
}, this)
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
Program.prototype.unkey = Program.prototype.removeKey = function (
|
|
575
|
+
key,
|
|
576
|
+
listener
|
|
577
|
+
) {
|
|
578
|
+
if (typeof key === 'string') {
|
|
579
|
+
key = key.split(/\s*,\s*/)
|
|
580
|
+
}
|
|
581
|
+
key.forEach(function (key) {
|
|
582
|
+
return this.removeListener('key ' + key, listener)
|
|
583
|
+
}, this)
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
// XTerm mouse events
|
|
587
|
+
// http://invisible-island.net/xterm/ctlseqs/ctlseqs.html#Mouse%20Tracking
|
|
588
|
+
// To better understand these
|
|
589
|
+
// the xterm code is very helpful:
|
|
590
|
+
// Relevant files:
|
|
591
|
+
// button.c, charproc.c, misc.c
|
|
592
|
+
// Relevant functions in xterm/button.c:
|
|
593
|
+
// BtnCode, EmitButtonCode, EditorButton, SendMousePosition
|
|
594
|
+
// send a mouse event:
|
|
595
|
+
// regular/utf8: ^[[M Cb Cx Cy
|
|
596
|
+
// urxvt: ^[[ Cb ; Cx ; Cy M
|
|
597
|
+
// sgr: ^[[ Cb ; Cx ; Cy M/m
|
|
598
|
+
// vt300: ^[[ 24(1/3/5)~ [ Cx , Cy ] \r
|
|
599
|
+
// locator: CSI P e ; P b ; P r ; P c ; P p & w
|
|
600
|
+
// motion example of a left click:
|
|
601
|
+
// ^[[M 3<^[[M@4<^[[M@5<^[[M@6<^[[M@7<^[[M#7<
|
|
602
|
+
// mouseup, mousedown, mousewheel
|
|
603
|
+
// left click: ^[[M 3<^[[M#3<
|
|
604
|
+
// mousewheel up: ^[[M`3>
|
|
605
|
+
Program.prototype.bindMouse = function () {
|
|
606
|
+
if (this._boundMouse) {
|
|
607
|
+
return
|
|
608
|
+
}
|
|
609
|
+
this._boundMouse = true
|
|
610
|
+
|
|
611
|
+
const decoder = new StringDecoder('utf8'),
|
|
612
|
+
self = this
|
|
613
|
+
|
|
614
|
+
this.on('data', function (data) {
|
|
615
|
+
const text = decoder.write(data)
|
|
616
|
+
if (!text) {
|
|
617
|
+
return
|
|
618
|
+
}
|
|
619
|
+
self._bindMouse(text, data)
|
|
620
|
+
})
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
Program.prototype._bindMouse = function (s, buf) {
|
|
624
|
+
let self = this,
|
|
625
|
+
key,
|
|
626
|
+
parts,
|
|
627
|
+
b,
|
|
628
|
+
x,
|
|
629
|
+
y,
|
|
630
|
+
mod,
|
|
631
|
+
params,
|
|
632
|
+
down,
|
|
633
|
+
page,
|
|
634
|
+
button
|
|
635
|
+
|
|
636
|
+
key = {
|
|
637
|
+
name: undefined,
|
|
638
|
+
ctrl: false,
|
|
639
|
+
meta: false,
|
|
640
|
+
shift: false
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
if (Buffer.isBuffer(s)) {
|
|
644
|
+
if (s[0] > 127 && s[1] === undefined) {
|
|
645
|
+
s[0] -= 128
|
|
646
|
+
s = '\x1b' + s.toString('utf-8')
|
|
647
|
+
} else {
|
|
648
|
+
s = s.toString('utf-8')
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
// if (this.8bit) {
|
|
653
|
+
// s = s.replace(/\233/g, '\x1b[');
|
|
654
|
+
// buf = new Buffer(s, 'utf8');
|
|
655
|
+
// }
|
|
656
|
+
|
|
657
|
+
// XTerm / X10 for buggy VTE
|
|
658
|
+
// VTE can only send unsigned chars and no unicode for coords. This limits
|
|
659
|
+
// them to 0xff. However, normally the x10 protocol does not allow a byte
|
|
660
|
+
// under 0x20, but since VTE can have the bytes overflow, we can consider
|
|
661
|
+
// bytes below 0x20 to be up to 0xff + 0x20. This gives a limit of 287. Since
|
|
662
|
+
// characters ranging from 223 to 248 confuse javascript's utf parser, we
|
|
663
|
+
// need to parse the raw binary. We can detect whether the terminal is using
|
|
664
|
+
// a bugged VTE version by examining the coordinates and seeing whether they
|
|
665
|
+
// are a value they would never otherwise be with a properly implemented x10
|
|
666
|
+
// protocol. This method of detecting VTE is only 99% reliable because we
|
|
667
|
+
// can't check if the coords are 0x00 (255) since that is a valid x10 coord
|
|
668
|
+
// technically.
|
|
669
|
+
const bx = s.charCodeAt(4)
|
|
670
|
+
const by = s.charCodeAt(5)
|
|
671
|
+
if (
|
|
672
|
+
buf[0] === 0x1b &&
|
|
673
|
+
buf[1] === 0x5b &&
|
|
674
|
+
buf[2] === 0x4d &&
|
|
675
|
+
(this.isVTE ||
|
|
676
|
+
bx >= 65533 ||
|
|
677
|
+
by >= 65533 ||
|
|
678
|
+
(bx > 0x00 && bx < 0x20) ||
|
|
679
|
+
(by > 0x00 && by < 0x20) ||
|
|
680
|
+
(buf[4] > 223 && buf[4] < 248 && buf.length === 6) ||
|
|
681
|
+
(buf[5] > 223 && buf[5] < 248 && buf.length === 6))
|
|
682
|
+
) {
|
|
683
|
+
b = buf[3]
|
|
684
|
+
x = buf[4]
|
|
685
|
+
y = buf[5]
|
|
686
|
+
|
|
687
|
+
// unsigned char overflow.
|
|
688
|
+
if (x < 0x20) {
|
|
689
|
+
x += 0xff
|
|
690
|
+
}
|
|
691
|
+
if (y < 0x20) {
|
|
692
|
+
y += 0xff
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
// Convert the coordinates into a
|
|
696
|
+
// properly formatted x10 utf8 sequence.
|
|
697
|
+
s =
|
|
698
|
+
'\x1b[M' +
|
|
699
|
+
String.fromCharCode(b) +
|
|
700
|
+
String.fromCharCode(x) +
|
|
701
|
+
String.fromCharCode(y)
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
// XTerm / X10
|
|
705
|
+
if ((parts = /^\x1b\[M([\x00\u0020-\uffff]{3})/.exec(s))) {
|
|
706
|
+
b = parts[1].charCodeAt(0)
|
|
707
|
+
x = parts[1].charCodeAt(1)
|
|
708
|
+
y = parts[1].charCodeAt(2)
|
|
709
|
+
|
|
710
|
+
key.name = 'mouse'
|
|
711
|
+
key.type = 'X10'
|
|
712
|
+
|
|
713
|
+
key.raw = [b, x, y, parts[0]]
|
|
714
|
+
key.buf = buf
|
|
715
|
+
key.x = x - 32
|
|
716
|
+
key.y = y - 32
|
|
717
|
+
|
|
718
|
+
if (this.zero) {
|
|
719
|
+
key.x--, key.y--
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
if (x === 0) {
|
|
723
|
+
key.x = 255
|
|
724
|
+
}
|
|
725
|
+
if (y === 0) {
|
|
726
|
+
key.y = 255
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
mod = b >> 2
|
|
730
|
+
key.shift = !!(mod & 1)
|
|
731
|
+
key.meta = !!((mod >> 1) & 1)
|
|
732
|
+
key.ctrl = !!((mod >> 2) & 1)
|
|
733
|
+
|
|
734
|
+
b -= 32
|
|
735
|
+
|
|
736
|
+
if ((b >> 6) & 1) {
|
|
737
|
+
key.action = b & 1 ? 'wheeldown' : 'wheelup'
|
|
738
|
+
key.button = 'middle'
|
|
739
|
+
} else if (b === 3) {
|
|
740
|
+
// NOTE: x10 and urxvt have no way
|
|
741
|
+
// of telling which button mouseup used.
|
|
742
|
+
key.action = 'mouseup'
|
|
743
|
+
key.button = this._lastButton || 'unknown'
|
|
744
|
+
delete this._lastButton
|
|
745
|
+
} else {
|
|
746
|
+
key.action = 'mousedown'
|
|
747
|
+
button = b & 3
|
|
748
|
+
key.button =
|
|
749
|
+
button === 0
|
|
750
|
+
? 'left'
|
|
751
|
+
: button === 1
|
|
752
|
+
? 'middle'
|
|
753
|
+
: button === 2
|
|
754
|
+
? 'right'
|
|
755
|
+
: 'unknown'
|
|
756
|
+
this._lastButton = key.button
|
|
757
|
+
}
|
|
758
|
+
|
|
759
|
+
// Probably a movement.
|
|
760
|
+
// The *newer* VTE gets mouse movements comepletely wrong.
|
|
761
|
+
// This presents a problem: older versions of VTE that get it right might
|
|
762
|
+
// be confused by the second conditional in the if statement.
|
|
763
|
+
// NOTE: Possibly just switch back to the if statement below.
|
|
764
|
+
// none, shift, ctrl, alt
|
|
765
|
+
// gnome: 32, 36, 48, 40
|
|
766
|
+
// xterm: 35, _, 51, _
|
|
767
|
+
// urxvt: 35, _, _, _
|
|
768
|
+
// if (key.action === 'mousedown' && key.button === 'unknown') {
|
|
769
|
+
if (
|
|
770
|
+
b === 35 ||
|
|
771
|
+
b === 39 ||
|
|
772
|
+
b === 51 ||
|
|
773
|
+
b === 43 ||
|
|
774
|
+
(this.isVTE && (b === 32 || b === 36 || b === 48 || b === 40))
|
|
775
|
+
) {
|
|
776
|
+
delete key.button
|
|
777
|
+
key.action = 'mousemove'
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
self.emit('mouse', key)
|
|
781
|
+
|
|
782
|
+
return
|
|
783
|
+
}
|
|
784
|
+
|
|
785
|
+
// URxvt
|
|
786
|
+
if ((parts = /^\x1b\[(\d+;\d+;\d+)M/.exec(s))) {
|
|
787
|
+
params = parts[1].split(';')
|
|
788
|
+
b = +params[0]
|
|
789
|
+
x = +params[1]
|
|
790
|
+
y = +params[2]
|
|
791
|
+
|
|
792
|
+
key.name = 'mouse'
|
|
793
|
+
key.type = 'urxvt'
|
|
794
|
+
|
|
795
|
+
key.raw = [b, x, y, parts[0]]
|
|
796
|
+
key.buf = buf
|
|
797
|
+
key.x = x
|
|
798
|
+
key.y = y
|
|
799
|
+
|
|
800
|
+
if (this.zero) {
|
|
801
|
+
key.x--, key.y--
|
|
802
|
+
}
|
|
803
|
+
|
|
804
|
+
mod = b >> 2
|
|
805
|
+
key.shift = !!(mod & 1)
|
|
806
|
+
key.meta = !!((mod >> 1) & 1)
|
|
807
|
+
key.ctrl = !!((mod >> 2) & 1)
|
|
808
|
+
|
|
809
|
+
// XXX Bug in urxvt after wheelup/down on mousemove
|
|
810
|
+
// NOTE: This may be different than 128/129 depending
|
|
811
|
+
// on mod keys.
|
|
812
|
+
if (b === 128 || b === 129) {
|
|
813
|
+
b = 67
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
b -= 32
|
|
817
|
+
|
|
818
|
+
if ((b >> 6) & 1) {
|
|
819
|
+
key.action = b & 1 ? 'wheeldown' : 'wheelup'
|
|
820
|
+
key.button = 'middle'
|
|
821
|
+
} else if (b === 3) {
|
|
822
|
+
// NOTE: x10 and urxvt have no way
|
|
823
|
+
// of telling which button mouseup used.
|
|
824
|
+
key.action = 'mouseup'
|
|
825
|
+
key.button = this._lastButton || 'unknown'
|
|
826
|
+
delete this._lastButton
|
|
827
|
+
} else {
|
|
828
|
+
key.action = 'mousedown'
|
|
829
|
+
button = b & 3
|
|
830
|
+
key.button =
|
|
831
|
+
button === 0
|
|
832
|
+
? 'left'
|
|
833
|
+
: button === 1
|
|
834
|
+
? 'middle'
|
|
835
|
+
: button === 2
|
|
836
|
+
? 'right'
|
|
837
|
+
: 'unknown'
|
|
838
|
+
// NOTE: 0/32 = mousemove, 32/64 = mousemove with left down
|
|
839
|
+
// if ((b >> 1) === 32)
|
|
840
|
+
this._lastButton = key.button
|
|
841
|
+
}
|
|
842
|
+
|
|
843
|
+
// Probably a movement.
|
|
844
|
+
// The *newer* VTE gets mouse movements comepletely wrong.
|
|
845
|
+
// This presents a problem: older versions of VTE that get it right might
|
|
846
|
+
// be confused by the second conditional in the if statement.
|
|
847
|
+
// NOTE: Possibly just switch back to the if statement below.
|
|
848
|
+
// none, shift, ctrl, alt
|
|
849
|
+
// urxvt: 35, _, _, _
|
|
850
|
+
// gnome: 32, 36, 48, 40
|
|
851
|
+
// if (key.action === 'mousedown' && key.button === 'unknown') {
|
|
852
|
+
if (
|
|
853
|
+
b === 35 ||
|
|
854
|
+
b === 39 ||
|
|
855
|
+
b === 51 ||
|
|
856
|
+
b === 43 ||
|
|
857
|
+
(this.isVTE && (b === 32 || b === 36 || b === 48 || b === 40))
|
|
858
|
+
) {
|
|
859
|
+
delete key.button
|
|
860
|
+
key.action = 'mousemove'
|
|
861
|
+
}
|
|
862
|
+
|
|
863
|
+
self.emit('mouse', key)
|
|
864
|
+
|
|
865
|
+
return
|
|
866
|
+
}
|
|
867
|
+
|
|
868
|
+
// SGR
|
|
869
|
+
if ((parts = /^\x1b\[<(\d+;\d+;\d+)([mM])/.exec(s))) {
|
|
870
|
+
down = parts[2] === 'M'
|
|
871
|
+
params = parts[1].split(';')
|
|
872
|
+
b = +params[0]
|
|
873
|
+
x = +params[1]
|
|
874
|
+
y = +params[2]
|
|
875
|
+
|
|
876
|
+
key.name = 'mouse'
|
|
877
|
+
key.type = 'sgr'
|
|
878
|
+
|
|
879
|
+
key.raw = [b, x, y, parts[0]]
|
|
880
|
+
key.buf = buf
|
|
881
|
+
key.x = x
|
|
882
|
+
key.y = y
|
|
883
|
+
|
|
884
|
+
if (this.zero) {
|
|
885
|
+
key.x--, key.y--
|
|
886
|
+
}
|
|
887
|
+
|
|
888
|
+
mod = b >> 2
|
|
889
|
+
key.shift = !!(mod & 1)
|
|
890
|
+
key.meta = !!((mod >> 1) & 1)
|
|
891
|
+
key.ctrl = !!((mod >> 2) & 1)
|
|
892
|
+
|
|
893
|
+
if ((b >> 6) & 1) {
|
|
894
|
+
key.action = b & 1 ? 'wheeldown' : 'wheelup'
|
|
895
|
+
key.button = 'middle'
|
|
896
|
+
} else {
|
|
897
|
+
key.action = down ? 'mousedown' : 'mouseup'
|
|
898
|
+
button = b & 3
|
|
899
|
+
key.button =
|
|
900
|
+
button === 0
|
|
901
|
+
? 'left'
|
|
902
|
+
: button === 1
|
|
903
|
+
? 'middle'
|
|
904
|
+
: button === 2
|
|
905
|
+
? 'right'
|
|
906
|
+
: 'unknown'
|
|
907
|
+
}
|
|
908
|
+
|
|
909
|
+
// Probably a movement.
|
|
910
|
+
// The *newer* VTE gets mouse movements comepletely wrong.
|
|
911
|
+
// This presents a problem: older versions of VTE that get it right might
|
|
912
|
+
// be confused by the second conditional in the if statement.
|
|
913
|
+
// NOTE: Possibly just switch back to the if statement below.
|
|
914
|
+
// none, shift, ctrl, alt
|
|
915
|
+
// xterm: 35, _, 51, _
|
|
916
|
+
// gnome: 32, 36, 48, 40
|
|
917
|
+
// if (key.action === 'mousedown' && key.button === 'unknown') {
|
|
918
|
+
if (
|
|
919
|
+
b === 35 ||
|
|
920
|
+
b === 39 ||
|
|
921
|
+
b === 51 ||
|
|
922
|
+
b === 43 ||
|
|
923
|
+
(this.isVTE && (b === 32 || b === 36 || b === 48 || b === 40))
|
|
924
|
+
) {
|
|
925
|
+
delete key.button
|
|
926
|
+
key.action = 'mousemove'
|
|
927
|
+
}
|
|
928
|
+
|
|
929
|
+
self.emit('mouse', key)
|
|
930
|
+
|
|
931
|
+
return
|
|
932
|
+
}
|
|
933
|
+
|
|
934
|
+
// DEC
|
|
935
|
+
// The xterm mouse documentation says there is a
|
|
936
|
+
// `<` prefix, the DECRQLP says there is no prefix.
|
|
937
|
+
if ((parts = /^\x1b\[<(\d+;\d+;\d+;\d+)&w/.exec(s))) {
|
|
938
|
+
params = parts[1].split(';')
|
|
939
|
+
b = +params[0]
|
|
940
|
+
x = +params[1]
|
|
941
|
+
y = +params[2]
|
|
942
|
+
page = +params[3]
|
|
943
|
+
|
|
944
|
+
key.name = 'mouse'
|
|
945
|
+
key.type = 'dec'
|
|
946
|
+
|
|
947
|
+
key.raw = [b, x, y, parts[0]]
|
|
948
|
+
key.buf = buf
|
|
949
|
+
key.x = x
|
|
950
|
+
key.y = y
|
|
951
|
+
key.page = page
|
|
952
|
+
|
|
953
|
+
if (this.zero) {
|
|
954
|
+
key.x--, key.y--
|
|
955
|
+
}
|
|
956
|
+
|
|
957
|
+
key.action = b === 3 ? 'mouseup' : 'mousedown'
|
|
958
|
+
|
|
959
|
+
key.button =
|
|
960
|
+
b === 2 ? 'left' : b === 4 ? 'middle' : b === 6 ? 'right' : 'unknown'
|
|
961
|
+
|
|
962
|
+
self.emit('mouse', key)
|
|
963
|
+
|
|
964
|
+
return
|
|
965
|
+
}
|
|
966
|
+
|
|
967
|
+
// vt300
|
|
968
|
+
if ((parts = /^\x1b\[24([0135])~\[(\d+),(\d+)\]\r/.exec(s))) {
|
|
969
|
+
b = +parts[1]
|
|
970
|
+
x = +parts[2]
|
|
971
|
+
y = +parts[3]
|
|
972
|
+
|
|
973
|
+
key.name = 'mouse'
|
|
974
|
+
key.type = 'vt300'
|
|
975
|
+
|
|
976
|
+
key.raw = [b, x, y, parts[0]]
|
|
977
|
+
key.buf = buf
|
|
978
|
+
key.x = x
|
|
979
|
+
key.y = y
|
|
980
|
+
|
|
981
|
+
if (this.zero) {
|
|
982
|
+
key.x--, key.y--
|
|
983
|
+
}
|
|
984
|
+
|
|
985
|
+
key.action = 'mousedown'
|
|
986
|
+
key.button =
|
|
987
|
+
b === 1 ? 'left' : b === 2 ? 'middle' : b === 5 ? 'right' : 'unknown'
|
|
988
|
+
|
|
989
|
+
self.emit('mouse', key)
|
|
990
|
+
|
|
991
|
+
return
|
|
992
|
+
}
|
|
993
|
+
|
|
994
|
+
if ((parts = /^\x1b\[(O|I)/.exec(s))) {
|
|
995
|
+
key.action = parts[1] === 'I' ? 'focus' : 'blur'
|
|
996
|
+
|
|
997
|
+
self.emit('mouse', key)
|
|
998
|
+
self.emit(key.action)
|
|
999
|
+
|
|
1000
|
+
return
|
|
1001
|
+
}
|
|
1002
|
+
}
|
|
1003
|
+
|
|
1004
|
+
// gpm support for linux vc
|
|
1005
|
+
Program.prototype.enableGpm = function () {
|
|
1006
|
+
const self = this
|
|
1007
|
+
const gpmclient = require('./gpmclient')
|
|
1008
|
+
|
|
1009
|
+
if (this.gpm) {
|
|
1010
|
+
return
|
|
1011
|
+
}
|
|
1012
|
+
|
|
1013
|
+
this.gpm = gpmclient()
|
|
1014
|
+
|
|
1015
|
+
this.gpm.on('btndown', function (btn, modifier, x, y) {
|
|
1016
|
+
x--, y--
|
|
1017
|
+
|
|
1018
|
+
const key = {
|
|
1019
|
+
name: 'mouse',
|
|
1020
|
+
type: 'GPM',
|
|
1021
|
+
action: 'mousedown',
|
|
1022
|
+
button: self.gpm.ButtonName(btn),
|
|
1023
|
+
raw: [btn, modifier, x, y],
|
|
1024
|
+
x: x,
|
|
1025
|
+
y: y,
|
|
1026
|
+
shift: self.gpm.hasShiftKey(modifier),
|
|
1027
|
+
meta: self.gpm.hasMetaKey(modifier),
|
|
1028
|
+
ctrl: self.gpm.hasCtrlKey(modifier)
|
|
1029
|
+
}
|
|
1030
|
+
|
|
1031
|
+
self.emit('mouse', key)
|
|
1032
|
+
})
|
|
1033
|
+
|
|
1034
|
+
this.gpm.on('btnup', function (btn, modifier, x, y) {
|
|
1035
|
+
x--, y--
|
|
1036
|
+
|
|
1037
|
+
const key = {
|
|
1038
|
+
name: 'mouse',
|
|
1039
|
+
type: 'GPM',
|
|
1040
|
+
action: 'mouseup',
|
|
1041
|
+
button: self.gpm.ButtonName(btn),
|
|
1042
|
+
raw: [btn, modifier, x, y],
|
|
1043
|
+
x: x,
|
|
1044
|
+
y: y,
|
|
1045
|
+
shift: self.gpm.hasShiftKey(modifier),
|
|
1046
|
+
meta: self.gpm.hasMetaKey(modifier),
|
|
1047
|
+
ctrl: self.gpm.hasCtrlKey(modifier)
|
|
1048
|
+
}
|
|
1049
|
+
|
|
1050
|
+
self.emit('mouse', key)
|
|
1051
|
+
})
|
|
1052
|
+
|
|
1053
|
+
this.gpm.on('move', function (btn, modifier, x, y) {
|
|
1054
|
+
x--, y--
|
|
1055
|
+
|
|
1056
|
+
const key = {
|
|
1057
|
+
name: 'mouse',
|
|
1058
|
+
type: 'GPM',
|
|
1059
|
+
action: 'mousemove',
|
|
1060
|
+
button: self.gpm.ButtonName(btn),
|
|
1061
|
+
raw: [btn, modifier, x, y],
|
|
1062
|
+
x: x,
|
|
1063
|
+
y: y,
|
|
1064
|
+
shift: self.gpm.hasShiftKey(modifier),
|
|
1065
|
+
meta: self.gpm.hasMetaKey(modifier),
|
|
1066
|
+
ctrl: self.gpm.hasCtrlKey(modifier)
|
|
1067
|
+
}
|
|
1068
|
+
|
|
1069
|
+
self.emit('mouse', key)
|
|
1070
|
+
})
|
|
1071
|
+
|
|
1072
|
+
this.gpm.on('drag', function (btn, modifier, x, y) {
|
|
1073
|
+
x--, y--
|
|
1074
|
+
|
|
1075
|
+
const key = {
|
|
1076
|
+
name: 'mouse',
|
|
1077
|
+
type: 'GPM',
|
|
1078
|
+
action: 'mousemove',
|
|
1079
|
+
button: self.gpm.ButtonName(btn),
|
|
1080
|
+
raw: [btn, modifier, x, y],
|
|
1081
|
+
x: x,
|
|
1082
|
+
y: y,
|
|
1083
|
+
shift: self.gpm.hasShiftKey(modifier),
|
|
1084
|
+
meta: self.gpm.hasMetaKey(modifier),
|
|
1085
|
+
ctrl: self.gpm.hasCtrlKey(modifier)
|
|
1086
|
+
}
|
|
1087
|
+
|
|
1088
|
+
self.emit('mouse', key)
|
|
1089
|
+
})
|
|
1090
|
+
|
|
1091
|
+
this.gpm.on('mousewheel', function (btn, modifier, x, y, dx, dy) {
|
|
1092
|
+
const key = {
|
|
1093
|
+
name: 'mouse',
|
|
1094
|
+
type: 'GPM',
|
|
1095
|
+
action: dy > 0 ? 'wheelup' : 'wheeldown',
|
|
1096
|
+
button: self.gpm.ButtonName(btn),
|
|
1097
|
+
raw: [btn, modifier, x, y, dx, dy],
|
|
1098
|
+
x: x,
|
|
1099
|
+
y: y,
|
|
1100
|
+
shift: self.gpm.hasShiftKey(modifier),
|
|
1101
|
+
meta: self.gpm.hasMetaKey(modifier),
|
|
1102
|
+
ctrl: self.gpm.hasCtrlKey(modifier)
|
|
1103
|
+
}
|
|
1104
|
+
|
|
1105
|
+
self.emit('mouse', key)
|
|
1106
|
+
})
|
|
1107
|
+
}
|
|
1108
|
+
|
|
1109
|
+
Program.prototype.disableGpm = function () {
|
|
1110
|
+
if (this.gpm) {
|
|
1111
|
+
this.gpm.stop()
|
|
1112
|
+
delete this.gpm
|
|
1113
|
+
}
|
|
1114
|
+
}
|
|
1115
|
+
|
|
1116
|
+
// All possible responses from the terminal
|
|
1117
|
+
Program.prototype.bindResponse = function () {
|
|
1118
|
+
if (this._boundResponse) {
|
|
1119
|
+
return
|
|
1120
|
+
}
|
|
1121
|
+
this._boundResponse = true
|
|
1122
|
+
|
|
1123
|
+
const decoder = new StringDecoder('utf8'),
|
|
1124
|
+
self = this
|
|
1125
|
+
|
|
1126
|
+
this.on('data', function (data) {
|
|
1127
|
+
data = decoder.write(data)
|
|
1128
|
+
if (!data) {
|
|
1129
|
+
return
|
|
1130
|
+
}
|
|
1131
|
+
self._bindResponse(data)
|
|
1132
|
+
})
|
|
1133
|
+
}
|
|
1134
|
+
|
|
1135
|
+
Program.prototype._bindResponse = function (s) {
|
|
1136
|
+
let out = {},
|
|
1137
|
+
parts
|
|
1138
|
+
|
|
1139
|
+
if (Buffer.isBuffer(s)) {
|
|
1140
|
+
if (s[0] > 127 && s[1] === undefined) {
|
|
1141
|
+
s[0] -= 128
|
|
1142
|
+
s = '\x1b' + s.toString('utf-8')
|
|
1143
|
+
} else {
|
|
1144
|
+
s = s.toString('utf-8')
|
|
1145
|
+
}
|
|
1146
|
+
}
|
|
1147
|
+
|
|
1148
|
+
// CSI P s c
|
|
1149
|
+
// Send Device Attributes (Primary DA).
|
|
1150
|
+
// CSI > P s c
|
|
1151
|
+
// Send Device Attributes (Secondary DA).
|
|
1152
|
+
if ((parts = /^\x1b\[(\?|>)(\d*(?:;\d*)*)c/.exec(s))) {
|
|
1153
|
+
parts = parts[2].split(';').map(function (ch) {
|
|
1154
|
+
return +ch || 0
|
|
1155
|
+
})
|
|
1156
|
+
|
|
1157
|
+
out.event = 'device-attributes'
|
|
1158
|
+
out.code = 'DA'
|
|
1159
|
+
|
|
1160
|
+
if (parts[1] === '?') {
|
|
1161
|
+
out.type = 'primary-attribute'
|
|
1162
|
+
// VT100-style params:
|
|
1163
|
+
if (parts[0] === 1 && parts[2] === 2) {
|
|
1164
|
+
out.term = 'vt100'
|
|
1165
|
+
out.advancedVideo = true
|
|
1166
|
+
} else if (parts[0] === 1 && parts[2] === 0) {
|
|
1167
|
+
out.term = 'vt101'
|
|
1168
|
+
} else if (parts[0] === 6) {
|
|
1169
|
+
out.term = 'vt102'
|
|
1170
|
+
} else if (
|
|
1171
|
+
parts[0] === 60 &&
|
|
1172
|
+
parts[1] === 1 &&
|
|
1173
|
+
parts[2] === 2 &&
|
|
1174
|
+
parts[3] === 6 &&
|
|
1175
|
+
parts[4] === 8 &&
|
|
1176
|
+
parts[5] === 9 &&
|
|
1177
|
+
parts[6] === 15
|
|
1178
|
+
) {
|
|
1179
|
+
out.term = 'vt220'
|
|
1180
|
+
} else {
|
|
1181
|
+
// VT200-style params:
|
|
1182
|
+
parts.forEach(function (attr) {
|
|
1183
|
+
switch (attr) {
|
|
1184
|
+
case 1:
|
|
1185
|
+
out.cols132 = true
|
|
1186
|
+
break
|
|
1187
|
+
case 2:
|
|
1188
|
+
out.printer = true
|
|
1189
|
+
break
|
|
1190
|
+
case 6:
|
|
1191
|
+
out.selectiveErase = true
|
|
1192
|
+
break
|
|
1193
|
+
case 8:
|
|
1194
|
+
out.userDefinedKeys = true
|
|
1195
|
+
break
|
|
1196
|
+
case 9:
|
|
1197
|
+
out.nationalReplacementCharsets = true
|
|
1198
|
+
break
|
|
1199
|
+
case 15:
|
|
1200
|
+
out.technicalCharacters = true
|
|
1201
|
+
break
|
|
1202
|
+
case 18:
|
|
1203
|
+
out.userWindows = true
|
|
1204
|
+
break
|
|
1205
|
+
case 21:
|
|
1206
|
+
out.horizontalScrolling = true
|
|
1207
|
+
break
|
|
1208
|
+
case 22:
|
|
1209
|
+
out.ansiColor = true
|
|
1210
|
+
break
|
|
1211
|
+
case 29:
|
|
1212
|
+
out.ansiTextLocator = true
|
|
1213
|
+
break
|
|
1214
|
+
}
|
|
1215
|
+
})
|
|
1216
|
+
}
|
|
1217
|
+
} else {
|
|
1218
|
+
out.type = 'secondary-attribute'
|
|
1219
|
+
switch (parts[0]) {
|
|
1220
|
+
case 0:
|
|
1221
|
+
out.term = 'vt100'
|
|
1222
|
+
break
|
|
1223
|
+
case 1:
|
|
1224
|
+
out.term = 'vt220'
|
|
1225
|
+
break
|
|
1226
|
+
case 2:
|
|
1227
|
+
out.term = 'vt240'
|
|
1228
|
+
break
|
|
1229
|
+
case 18:
|
|
1230
|
+
out.term = 'vt330'
|
|
1231
|
+
break
|
|
1232
|
+
case 19:
|
|
1233
|
+
out.term = 'vt340'
|
|
1234
|
+
break
|
|
1235
|
+
case 24:
|
|
1236
|
+
out.term = 'vt320'
|
|
1237
|
+
break
|
|
1238
|
+
case 41:
|
|
1239
|
+
out.term = 'vt420'
|
|
1240
|
+
break
|
|
1241
|
+
case 61:
|
|
1242
|
+
out.term = 'vt510'
|
|
1243
|
+
break
|
|
1244
|
+
case 64:
|
|
1245
|
+
out.term = 'vt520'
|
|
1246
|
+
break
|
|
1247
|
+
case 65:
|
|
1248
|
+
out.term = 'vt525'
|
|
1249
|
+
break
|
|
1250
|
+
}
|
|
1251
|
+
out.firmwareVersion = parts[1]
|
|
1252
|
+
out.romCartridgeRegistrationNumber = parts[2]
|
|
1253
|
+
}
|
|
1254
|
+
|
|
1255
|
+
// LEGACY
|
|
1256
|
+
out.deviceAttributes = out
|
|
1257
|
+
|
|
1258
|
+
this.emit('response', out)
|
|
1259
|
+
this.emit('response ' + out.event, out)
|
|
1260
|
+
|
|
1261
|
+
return
|
|
1262
|
+
}
|
|
1263
|
+
|
|
1264
|
+
// CSI Ps n Device Status Report (DSR).
|
|
1265
|
+
// Ps = 5 -> Status Report. Result (``OK'') is
|
|
1266
|
+
// CSI 0 n
|
|
1267
|
+
// CSI ? Ps n
|
|
1268
|
+
// Device Status Report (DSR, DEC-specific).
|
|
1269
|
+
// Ps = 1 5 -> Report Printer status as CSI ? 1 0 n (ready).
|
|
1270
|
+
// or CSI ? 1 1 n (not ready).
|
|
1271
|
+
// Ps = 2 5 -> Report UDK status as CSI ? 2 0 n (unlocked)
|
|
1272
|
+
// or CSI ? 2 1 n (locked).
|
|
1273
|
+
// Ps = 2 6 -> Report Keyboard status as
|
|
1274
|
+
// CSI ? 2 7 ; 1 ; 0 ; 0 n (North American).
|
|
1275
|
+
// The last two parameters apply to VT400 & up, and denote key-
|
|
1276
|
+
// board ready and LK01 respectively.
|
|
1277
|
+
// Ps = 5 3 -> Report Locator status as
|
|
1278
|
+
// CSI ? 5 3 n Locator available, if compiled-in, or
|
|
1279
|
+
// CSI ? 5 0 n No Locator, if not.
|
|
1280
|
+
if ((parts = /^\x1b\[(\?)?(\d+)(?:;(\d+);(\d+);(\d+))?n/.exec(s))) {
|
|
1281
|
+
out.event = 'device-status'
|
|
1282
|
+
out.code = 'DSR'
|
|
1283
|
+
|
|
1284
|
+
if (!parts[1] && parts[2] === '0' && !parts[3]) {
|
|
1285
|
+
out.type = 'device-status'
|
|
1286
|
+
out.status = 'OK'
|
|
1287
|
+
|
|
1288
|
+
// LEGACY
|
|
1289
|
+
out.deviceStatus = out.status
|
|
1290
|
+
|
|
1291
|
+
this.emit('response', out)
|
|
1292
|
+
this.emit('response ' + out.event, out)
|
|
1293
|
+
|
|
1294
|
+
return
|
|
1295
|
+
}
|
|
1296
|
+
|
|
1297
|
+
if (parts[1] && (parts[2] === '10' || parts[2] === '11') && !parts[3]) {
|
|
1298
|
+
out.type = 'printer-status'
|
|
1299
|
+
out.status = parts[2] === '10' ? 'ready' : 'not ready'
|
|
1300
|
+
|
|
1301
|
+
// LEGACY
|
|
1302
|
+
out.printerStatus = out.status
|
|
1303
|
+
|
|
1304
|
+
this.emit('response', out)
|
|
1305
|
+
this.emit('response ' + out.event, out)
|
|
1306
|
+
|
|
1307
|
+
return
|
|
1308
|
+
}
|
|
1309
|
+
|
|
1310
|
+
if (parts[1] && (parts[2] === '20' || parts[2] === '21') && !parts[3]) {
|
|
1311
|
+
out.type = 'udk-status'
|
|
1312
|
+
out.status = parts[2] === '20' ? 'unlocked' : 'locked'
|
|
1313
|
+
|
|
1314
|
+
// LEGACY
|
|
1315
|
+
out.UDKStatus = out.status
|
|
1316
|
+
|
|
1317
|
+
this.emit('response', out)
|
|
1318
|
+
this.emit('response ' + out.event, out)
|
|
1319
|
+
|
|
1320
|
+
return
|
|
1321
|
+
}
|
|
1322
|
+
|
|
1323
|
+
if (
|
|
1324
|
+
parts[1] &&
|
|
1325
|
+
parts[2] === '27' &&
|
|
1326
|
+
parts[3] === '1' &&
|
|
1327
|
+
parts[4] === '0' &&
|
|
1328
|
+
parts[5] === '0'
|
|
1329
|
+
) {
|
|
1330
|
+
out.type = 'keyboard-status'
|
|
1331
|
+
out.status = 'OK'
|
|
1332
|
+
|
|
1333
|
+
// LEGACY
|
|
1334
|
+
out.keyboardStatus = out.status
|
|
1335
|
+
|
|
1336
|
+
this.emit('response', out)
|
|
1337
|
+
this.emit('response ' + out.event, out)
|
|
1338
|
+
|
|
1339
|
+
return
|
|
1340
|
+
}
|
|
1341
|
+
|
|
1342
|
+
if (parts[1] && (parts[2] === '53' || parts[2] === '50') && !parts[3]) {
|
|
1343
|
+
out.type = 'locator-status'
|
|
1344
|
+
out.status = parts[2] === '53' ? 'available' : 'unavailable'
|
|
1345
|
+
|
|
1346
|
+
// LEGACY
|
|
1347
|
+
out.locator = out.status
|
|
1348
|
+
|
|
1349
|
+
this.emit('response', out)
|
|
1350
|
+
this.emit('response ' + out.event, out)
|
|
1351
|
+
|
|
1352
|
+
return
|
|
1353
|
+
}
|
|
1354
|
+
|
|
1355
|
+
out.type = 'error'
|
|
1356
|
+
out.text = 'Unhandled: ' + JSON.stringify(parts)
|
|
1357
|
+
|
|
1358
|
+
// LEGACY
|
|
1359
|
+
out.error = out.text
|
|
1360
|
+
|
|
1361
|
+
this.emit('response', out)
|
|
1362
|
+
this.emit('response ' + out.event, out)
|
|
1363
|
+
|
|
1364
|
+
return
|
|
1365
|
+
}
|
|
1366
|
+
|
|
1367
|
+
// CSI Ps n Device Status Report (DSR).
|
|
1368
|
+
// Ps = 6 -> Report Cursor Position (CPR) [row;column].
|
|
1369
|
+
// Result is
|
|
1370
|
+
// CSI r ; c R
|
|
1371
|
+
// CSI ? Ps n
|
|
1372
|
+
// Device Status Report (DSR, DEC-specific).
|
|
1373
|
+
// Ps = 6 -> Report Cursor Position (CPR) [row;column] as CSI
|
|
1374
|
+
// ? r ; c R (assumes page is zero).
|
|
1375
|
+
if ((parts = /^\x1b\[(\?)?(\d+);(\d+)R/.exec(s))) {
|
|
1376
|
+
out.event = 'device-status'
|
|
1377
|
+
out.code = 'DSR'
|
|
1378
|
+
out.type = 'cursor-status'
|
|
1379
|
+
|
|
1380
|
+
out.status = {
|
|
1381
|
+
x: +parts[3],
|
|
1382
|
+
y: +parts[2],
|
|
1383
|
+
page: !parts[1] ? undefined : 0
|
|
1384
|
+
}
|
|
1385
|
+
|
|
1386
|
+
out.x = out.status.x
|
|
1387
|
+
out.y = out.status.y
|
|
1388
|
+
out.page = out.status.page
|
|
1389
|
+
|
|
1390
|
+
// LEGACY
|
|
1391
|
+
out.cursor = out.status
|
|
1392
|
+
|
|
1393
|
+
this.emit('response', out)
|
|
1394
|
+
this.emit('response ' + out.event, out)
|
|
1395
|
+
|
|
1396
|
+
return
|
|
1397
|
+
}
|
|
1398
|
+
|
|
1399
|
+
// CSI Ps ; Ps ; Ps t
|
|
1400
|
+
// Window manipulation (from dtterm, as well as extensions).
|
|
1401
|
+
// These controls may be disabled using the allowWindowOps
|
|
1402
|
+
// resource. Valid values for the first (and any additional
|
|
1403
|
+
// parameters) are:
|
|
1404
|
+
// Ps = 1 1 -> Report xterm window state. If the xterm window
|
|
1405
|
+
// is open (non-iconified), it returns CSI 1 t . If the xterm
|
|
1406
|
+
// window is iconified, it returns CSI 2 t .
|
|
1407
|
+
// Ps = 1 3 -> Report xterm window position. Result is CSI 3
|
|
1408
|
+
// ; x ; y t
|
|
1409
|
+
// Ps = 1 4 -> Report xterm window in pixels. Result is CSI
|
|
1410
|
+
// 4 ; height ; width t
|
|
1411
|
+
// Ps = 1 8 -> Report the size of the text area in characters.
|
|
1412
|
+
// Result is CSI 8 ; height ; width t
|
|
1413
|
+
// Ps = 1 9 -> Report the size of the screen in characters.
|
|
1414
|
+
// Result is CSI 9 ; height ; width t
|
|
1415
|
+
if ((parts = /^\x1b\[(\d+)(?:;(\d+);(\d+))?t/.exec(s))) {
|
|
1416
|
+
out.event = 'window-manipulation'
|
|
1417
|
+
out.code = ''
|
|
1418
|
+
|
|
1419
|
+
if ((parts[1] === '1' || parts[1] === '2') && !parts[2]) {
|
|
1420
|
+
out.type = 'window-state'
|
|
1421
|
+
out.state = parts[1] === '1' ? 'non-iconified' : 'iconified'
|
|
1422
|
+
|
|
1423
|
+
// LEGACY
|
|
1424
|
+
out.windowState = out.state
|
|
1425
|
+
|
|
1426
|
+
this.emit('response', out)
|
|
1427
|
+
this.emit('response ' + out.event, out)
|
|
1428
|
+
|
|
1429
|
+
return
|
|
1430
|
+
}
|
|
1431
|
+
|
|
1432
|
+
if (parts[1] === '3' && parts[2]) {
|
|
1433
|
+
out.type = 'window-position'
|
|
1434
|
+
|
|
1435
|
+
out.position = {
|
|
1436
|
+
x: +parts[2],
|
|
1437
|
+
y: +parts[3]
|
|
1438
|
+
}
|
|
1439
|
+
out.x = out.position.x
|
|
1440
|
+
out.y = out.position.y
|
|
1441
|
+
|
|
1442
|
+
// LEGACY
|
|
1443
|
+
out.windowPosition = out.position
|
|
1444
|
+
|
|
1445
|
+
this.emit('response', out)
|
|
1446
|
+
this.emit('response ' + out.event, out)
|
|
1447
|
+
|
|
1448
|
+
return
|
|
1449
|
+
}
|
|
1450
|
+
|
|
1451
|
+
if (parts[1] === '4' && parts[2]) {
|
|
1452
|
+
out.type = 'window-size-pixels'
|
|
1453
|
+
out.size = {
|
|
1454
|
+
height: +parts[2],
|
|
1455
|
+
width: +parts[3]
|
|
1456
|
+
}
|
|
1457
|
+
out.height = out.size.height
|
|
1458
|
+
out.width = out.size.width
|
|
1459
|
+
|
|
1460
|
+
// LEGACY
|
|
1461
|
+
out.windowSizePixels = out.size
|
|
1462
|
+
|
|
1463
|
+
this.emit('response', out)
|
|
1464
|
+
this.emit('response ' + out.event, out)
|
|
1465
|
+
|
|
1466
|
+
return
|
|
1467
|
+
}
|
|
1468
|
+
|
|
1469
|
+
if (parts[1] === '8' && parts[2]) {
|
|
1470
|
+
out.type = 'textarea-size'
|
|
1471
|
+
out.size = {
|
|
1472
|
+
height: +parts[2],
|
|
1473
|
+
width: +parts[3]
|
|
1474
|
+
}
|
|
1475
|
+
out.height = out.size.height
|
|
1476
|
+
out.width = out.size.width
|
|
1477
|
+
|
|
1478
|
+
// LEGACY
|
|
1479
|
+
out.textAreaSizeCharacters = out.size
|
|
1480
|
+
|
|
1481
|
+
this.emit('response', out)
|
|
1482
|
+
this.emit('response ' + out.event, out)
|
|
1483
|
+
|
|
1484
|
+
return
|
|
1485
|
+
}
|
|
1486
|
+
|
|
1487
|
+
if (parts[1] === '9' && parts[2]) {
|
|
1488
|
+
out.type = 'screen-size'
|
|
1489
|
+
out.size = {
|
|
1490
|
+
height: +parts[2],
|
|
1491
|
+
width: +parts[3]
|
|
1492
|
+
}
|
|
1493
|
+
out.height = out.size.height
|
|
1494
|
+
out.width = out.size.width
|
|
1495
|
+
|
|
1496
|
+
// LEGACY
|
|
1497
|
+
out.screenSizeCharacters = out.size
|
|
1498
|
+
|
|
1499
|
+
this.emit('response', out)
|
|
1500
|
+
this.emit('response ' + out.event, out)
|
|
1501
|
+
|
|
1502
|
+
return
|
|
1503
|
+
}
|
|
1504
|
+
|
|
1505
|
+
out.type = 'error'
|
|
1506
|
+
out.text = 'Unhandled: ' + JSON.stringify(parts)
|
|
1507
|
+
|
|
1508
|
+
// LEGACY
|
|
1509
|
+
out.error = out.text
|
|
1510
|
+
|
|
1511
|
+
this.emit('response', out)
|
|
1512
|
+
this.emit('response ' + out.event, out)
|
|
1513
|
+
|
|
1514
|
+
return
|
|
1515
|
+
}
|
|
1516
|
+
|
|
1517
|
+
// rxvt-unicode does not support window manipulation
|
|
1518
|
+
// Result Normal: OSC l/L 0xEF 0xBF 0xBD
|
|
1519
|
+
// Result ASCII: OSC l/L 0x1c (file separator)
|
|
1520
|
+
// Result UTF8->ASCII: OSC l/L 0xFD
|
|
1521
|
+
// Test with:
|
|
1522
|
+
// echo -ne '\ePtmux;\e\e[>3t\e\\'
|
|
1523
|
+
// sleep 2 && echo -ne '\ePtmux;\e\e[21t\e\\' & cat -v
|
|
1524
|
+
// -
|
|
1525
|
+
// echo -ne '\e[>3t'
|
|
1526
|
+
// sleep 2 && echo -ne '\e[21t' & cat -v
|
|
1527
|
+
if ((parts = /^\x1b\](l|L)([^\x07\x1b]*)$/.exec(s))) {
|
|
1528
|
+
parts[2] = 'rxvt'
|
|
1529
|
+
s = '\x1b]' + parts[1] + parts[2] + '\x1b\\'
|
|
1530
|
+
}
|
|
1531
|
+
|
|
1532
|
+
// CSI Ps ; Ps ; Ps t
|
|
1533
|
+
// Window manipulation (from dtterm, as well as extensions).
|
|
1534
|
+
// These controls may be disabled using the allowWindowOps
|
|
1535
|
+
// resource. Valid values for the first (and any additional
|
|
1536
|
+
// parameters) are:
|
|
1537
|
+
// Ps = 2 0 -> Report xterm window's icon label. Result is
|
|
1538
|
+
// OSC L label ST
|
|
1539
|
+
// Ps = 2 1 -> Report xterm window's title. Result is OSC l
|
|
1540
|
+
// label ST
|
|
1541
|
+
if ((parts = /^\x1b\](l|L)([^\x07\x1b]*)(?:\x07|\x1b\\)/.exec(s))) {
|
|
1542
|
+
out.event = 'window-manipulation'
|
|
1543
|
+
out.code = ''
|
|
1544
|
+
|
|
1545
|
+
if (parts[1] === 'L') {
|
|
1546
|
+
out.type = 'window-icon-label'
|
|
1547
|
+
out.text = parts[2]
|
|
1548
|
+
|
|
1549
|
+
// LEGACY
|
|
1550
|
+
out.windowIconLabel = out.text
|
|
1551
|
+
|
|
1552
|
+
this.emit('response', out)
|
|
1553
|
+
this.emit('response ' + out.event, out)
|
|
1554
|
+
|
|
1555
|
+
return
|
|
1556
|
+
}
|
|
1557
|
+
|
|
1558
|
+
if (parts[1] === 'l') {
|
|
1559
|
+
out.type = 'window-title'
|
|
1560
|
+
out.text = parts[2]
|
|
1561
|
+
|
|
1562
|
+
// LEGACY
|
|
1563
|
+
out.windowTitle = out.text
|
|
1564
|
+
|
|
1565
|
+
this.emit('response', out)
|
|
1566
|
+
this.emit('response ' + out.event, out)
|
|
1567
|
+
|
|
1568
|
+
return
|
|
1569
|
+
}
|
|
1570
|
+
|
|
1571
|
+
out.type = 'error'
|
|
1572
|
+
out.text = 'Unhandled: ' + JSON.stringify(parts)
|
|
1573
|
+
|
|
1574
|
+
// LEGACY
|
|
1575
|
+
out.error = out.text
|
|
1576
|
+
|
|
1577
|
+
this.emit('response', out)
|
|
1578
|
+
this.emit('response ' + out.event, out)
|
|
1579
|
+
|
|
1580
|
+
return
|
|
1581
|
+
}
|
|
1582
|
+
|
|
1583
|
+
// CSI Ps ' |
|
|
1584
|
+
// Request Locator Position (DECRQLP).
|
|
1585
|
+
// -> CSI Pe ; Pb ; Pr ; Pc ; Pp & w
|
|
1586
|
+
// Parameters are [event;button;row;column;page].
|
|
1587
|
+
// Valid values for the event:
|
|
1588
|
+
// Pe = 0 -> locator unavailable - no other parameters sent.
|
|
1589
|
+
// Pe = 1 -> request - xterm received a DECRQLP.
|
|
1590
|
+
// Pe = 2 -> left button down.
|
|
1591
|
+
// Pe = 3 -> left button up.
|
|
1592
|
+
// Pe = 4 -> middle button down.
|
|
1593
|
+
// Pe = 5 -> middle button up.
|
|
1594
|
+
// Pe = 6 -> right button down.
|
|
1595
|
+
// Pe = 7 -> right button up.
|
|
1596
|
+
// Pe = 8 -> M4 button down.
|
|
1597
|
+
// Pe = 9 -> M4 button up.
|
|
1598
|
+
// Pe = 1 0 -> locator outside filter rectangle.
|
|
1599
|
+
// ``button'' parameter is a bitmask indicating which buttons are
|
|
1600
|
+
// pressed:
|
|
1601
|
+
// Pb = 0 <- no buttons down.
|
|
1602
|
+
// Pb & 1 <- right button down.
|
|
1603
|
+
// Pb & 2 <- middle button down.
|
|
1604
|
+
// Pb & 4 <- left button down.
|
|
1605
|
+
// Pb & 8 <- M4 button down.
|
|
1606
|
+
// ``row'' and ``column'' parameters are the coordinates of the
|
|
1607
|
+
// locator position in the xterm window, encoded as ASCII deci-
|
|
1608
|
+
// mal.
|
|
1609
|
+
// The ``page'' parameter is not used by xterm, and will be omit-
|
|
1610
|
+
// ted.
|
|
1611
|
+
// NOTE:
|
|
1612
|
+
// This is already implemented in the _bindMouse
|
|
1613
|
+
// method, but it might make more sense here.
|
|
1614
|
+
// The xterm mouse documentation says there is a
|
|
1615
|
+
// `<` prefix, the DECRQLP says there is no prefix.
|
|
1616
|
+
if ((parts = /^\x1b\[(\d+(?:;\d+){4})&w/.exec(s))) {
|
|
1617
|
+
parts = parts[1].split(';').map(function (ch) {
|
|
1618
|
+
return +ch
|
|
1619
|
+
})
|
|
1620
|
+
|
|
1621
|
+
out.event = 'locator-position'
|
|
1622
|
+
out.code = 'DECRQLP'
|
|
1623
|
+
|
|
1624
|
+
switch (parts[0]) {
|
|
1625
|
+
case 0:
|
|
1626
|
+
out.status = 'locator-unavailable'
|
|
1627
|
+
break
|
|
1628
|
+
case 1:
|
|
1629
|
+
out.status = 'request'
|
|
1630
|
+
break
|
|
1631
|
+
case 2:
|
|
1632
|
+
out.status = 'left-button-down'
|
|
1633
|
+
break
|
|
1634
|
+
case 3:
|
|
1635
|
+
out.status = 'left-button-up'
|
|
1636
|
+
break
|
|
1637
|
+
case 4:
|
|
1638
|
+
out.status = 'middle-button-down'
|
|
1639
|
+
break
|
|
1640
|
+
case 5:
|
|
1641
|
+
out.status = 'middle-button-up'
|
|
1642
|
+
break
|
|
1643
|
+
case 6:
|
|
1644
|
+
out.status = 'right-button-down'
|
|
1645
|
+
break
|
|
1646
|
+
case 7:
|
|
1647
|
+
out.status = 'right-button-up'
|
|
1648
|
+
break
|
|
1649
|
+
case 8:
|
|
1650
|
+
out.status = 'm4-button-down'
|
|
1651
|
+
break
|
|
1652
|
+
case 9:
|
|
1653
|
+
out.status = 'm4-button-up'
|
|
1654
|
+
break
|
|
1655
|
+
case 10:
|
|
1656
|
+
out.status = 'locator-outside'
|
|
1657
|
+
break
|
|
1658
|
+
}
|
|
1659
|
+
|
|
1660
|
+
out.mask = parts[1]
|
|
1661
|
+
out.row = parts[2]
|
|
1662
|
+
out.col = parts[3]
|
|
1663
|
+
out.page = parts[4]
|
|
1664
|
+
|
|
1665
|
+
// LEGACY
|
|
1666
|
+
out.locatorPosition = out
|
|
1667
|
+
|
|
1668
|
+
this.emit('response', out)
|
|
1669
|
+
this.emit('response ' + out.event, out)
|
|
1670
|
+
|
|
1671
|
+
return
|
|
1672
|
+
}
|
|
1673
|
+
|
|
1674
|
+
// OSC Ps ; Pt BEL
|
|
1675
|
+
// OSC Ps ; Pt ST
|
|
1676
|
+
// Set Text Parameters
|
|
1677
|
+
if ((parts = /^\x1b\](\d+);([^\x07\x1b]+)(?:\x07|\x1b\\)/.exec(s))) {
|
|
1678
|
+
out.event = 'text-params'
|
|
1679
|
+
out.code = 'Set Text Parameters'
|
|
1680
|
+
out.ps = +s[1]
|
|
1681
|
+
out.pt = s[2]
|
|
1682
|
+
this.emit('response', out)
|
|
1683
|
+
this.emit('response ' + out.event, out)
|
|
1684
|
+
}
|
|
1685
|
+
}
|
|
1686
|
+
|
|
1687
|
+
Program.prototype.response = function (name, text, callback, noBypass) {
|
|
1688
|
+
const self = this
|
|
1689
|
+
|
|
1690
|
+
if (arguments.length === 2) {
|
|
1691
|
+
callback = text
|
|
1692
|
+
text = name
|
|
1693
|
+
name = null
|
|
1694
|
+
}
|
|
1695
|
+
|
|
1696
|
+
if (!callback) {
|
|
1697
|
+
callback = function () {}
|
|
1698
|
+
}
|
|
1699
|
+
|
|
1700
|
+
this.bindResponse()
|
|
1701
|
+
|
|
1702
|
+
name = name ? 'response ' + name : 'response'
|
|
1703
|
+
|
|
1704
|
+
let onresponse
|
|
1705
|
+
|
|
1706
|
+
this.once(
|
|
1707
|
+
name,
|
|
1708
|
+
(onresponse = function (event) {
|
|
1709
|
+
if (timeout) {
|
|
1710
|
+
clearTimeout(timeout)
|
|
1711
|
+
}
|
|
1712
|
+
if (event.type === 'error') {
|
|
1713
|
+
return callback(new Error(event.event + ': ' + event.text))
|
|
1714
|
+
}
|
|
1715
|
+
return callback(null, event)
|
|
1716
|
+
})
|
|
1717
|
+
)
|
|
1718
|
+
|
|
1719
|
+
const timeout = setTimeout(function () {
|
|
1720
|
+
self.removeListener(name, onresponse)
|
|
1721
|
+
return callback(new Error('Timeout.'))
|
|
1722
|
+
}, 2000)
|
|
1723
|
+
|
|
1724
|
+
return noBypass ? this._write(text) : this._twrite(text)
|
|
1725
|
+
}
|
|
1726
|
+
|
|
1727
|
+
Program.prototype._owrite = Program.prototype.write = function (text) {
|
|
1728
|
+
if (!this.output.writable) {
|
|
1729
|
+
return
|
|
1730
|
+
}
|
|
1731
|
+
return this.output.write(text)
|
|
1732
|
+
}
|
|
1733
|
+
|
|
1734
|
+
Program.prototype._buffer = function (text) {
|
|
1735
|
+
if (this._exiting) {
|
|
1736
|
+
this.flush()
|
|
1737
|
+
this._owrite(text)
|
|
1738
|
+
return
|
|
1739
|
+
}
|
|
1740
|
+
|
|
1741
|
+
if (this._buf) {
|
|
1742
|
+
this._buf += text
|
|
1743
|
+
return
|
|
1744
|
+
}
|
|
1745
|
+
|
|
1746
|
+
this._buf = text
|
|
1747
|
+
|
|
1748
|
+
nextTick(this._flush)
|
|
1749
|
+
|
|
1750
|
+
return true
|
|
1751
|
+
}
|
|
1752
|
+
|
|
1753
|
+
Program.prototype.flush = function () {
|
|
1754
|
+
if (!this._buf) {
|
|
1755
|
+
return
|
|
1756
|
+
}
|
|
1757
|
+
this._owrite(this._buf)
|
|
1758
|
+
this._buf = ''
|
|
1759
|
+
}
|
|
1760
|
+
|
|
1761
|
+
Program.prototype._write = function (text) {
|
|
1762
|
+
if (this.ret) {
|
|
1763
|
+
return text
|
|
1764
|
+
}
|
|
1765
|
+
if (this.useBuffer) {
|
|
1766
|
+
return this._buffer(text)
|
|
1767
|
+
}
|
|
1768
|
+
return this._owrite(text)
|
|
1769
|
+
}
|
|
1770
|
+
|
|
1771
|
+
// Example: `DCS tmux; ESC Pt ST`
|
|
1772
|
+
// Real: `DCS tmux; ESC Pt ESC \`
|
|
1773
|
+
Program.prototype._twrite = function (data) {
|
|
1774
|
+
let self = this,
|
|
1775
|
+
iterations = 0,
|
|
1776
|
+
timer
|
|
1777
|
+
|
|
1778
|
+
if (this.tmux) {
|
|
1779
|
+
// Replace all STs with BELs so they can be nested within the DCS code.
|
|
1780
|
+
data = data.replace(/\x1b\\/g, '\x07')
|
|
1781
|
+
|
|
1782
|
+
// Wrap in tmux forward DCS:
|
|
1783
|
+
data = '\x1bPtmux;\x1b' + data + '\x1b\\'
|
|
1784
|
+
|
|
1785
|
+
// If we've never even flushed yet, it means we're still in
|
|
1786
|
+
// the normal buffer. Wait for alt screen buffer.
|
|
1787
|
+
if (this.output.bytesWritten === 0) {
|
|
1788
|
+
timer = setInterval(function () {
|
|
1789
|
+
if (self.output.bytesWritten > 0 || ++iterations === 50) {
|
|
1790
|
+
clearInterval(timer)
|
|
1791
|
+
self.flush()
|
|
1792
|
+
self._owrite(data)
|
|
1793
|
+
}
|
|
1794
|
+
}, 100)
|
|
1795
|
+
return true
|
|
1796
|
+
}
|
|
1797
|
+
|
|
1798
|
+
// NOTE: Flushing the buffer is required in some cases.
|
|
1799
|
+
// The DCS code must be at the start of the output.
|
|
1800
|
+
this.flush()
|
|
1801
|
+
|
|
1802
|
+
// Write out raw now that the buffer is flushed.
|
|
1803
|
+
return this._owrite(data)
|
|
1804
|
+
}
|
|
1805
|
+
|
|
1806
|
+
return this._write(data)
|
|
1807
|
+
}
|
|
1808
|
+
|
|
1809
|
+
Program.prototype.echo = Program.prototype.print = function (text, attr) {
|
|
1810
|
+
return attr ? this._write(this.text(text, attr)) : this._write(text)
|
|
1811
|
+
}
|
|
1812
|
+
|
|
1813
|
+
Program.prototype._ncoords = function () {
|
|
1814
|
+
if (this.x < 0) {
|
|
1815
|
+
this.x = 0
|
|
1816
|
+
} else if (this.x >= this.cols) {
|
|
1817
|
+
this.x = this.cols - 1
|
|
1818
|
+
}
|
|
1819
|
+
if (this.y < 0) {
|
|
1820
|
+
this.y = 0
|
|
1821
|
+
} else if (this.y >= this.rows) {
|
|
1822
|
+
this.y = this.rows - 1
|
|
1823
|
+
}
|
|
1824
|
+
}
|
|
1825
|
+
|
|
1826
|
+
Program.prototype.setx = function (x) {
|
|
1827
|
+
return this.cursorCharAbsolute(x)
|
|
1828
|
+
// return this.charPosAbsolute(x);
|
|
1829
|
+
}
|
|
1830
|
+
|
|
1831
|
+
Program.prototype.sety = function (y) {
|
|
1832
|
+
return this.linePosAbsolute(y)
|
|
1833
|
+
}
|
|
1834
|
+
|
|
1835
|
+
Program.prototype.move = function (x, y) {
|
|
1836
|
+
return this.cursorPos(y, x)
|
|
1837
|
+
}
|
|
1838
|
+
|
|
1839
|
+
// TODO: Fix cud and cuu calls.
|
|
1840
|
+
Program.prototype.omove = function (x, y) {
|
|
1841
|
+
if (!this.zero) {
|
|
1842
|
+
x = (x || 1) - 1
|
|
1843
|
+
y = (y || 1) - 1
|
|
1844
|
+
} else {
|
|
1845
|
+
x = x || 0
|
|
1846
|
+
y = y || 0
|
|
1847
|
+
}
|
|
1848
|
+
if (y === this.y && x === this.x) {
|
|
1849
|
+
return
|
|
1850
|
+
}
|
|
1851
|
+
if (y === this.y) {
|
|
1852
|
+
if (x > this.x) {
|
|
1853
|
+
this.cuf(x - this.x)
|
|
1854
|
+
} else if (x < this.x) {
|
|
1855
|
+
this.cub(this.x - x)
|
|
1856
|
+
}
|
|
1857
|
+
} else if (x === this.x) {
|
|
1858
|
+
if (y > this.y) {
|
|
1859
|
+
this.cud(y - this.y)
|
|
1860
|
+
} else if (y < this.y) {
|
|
1861
|
+
this.cuu(this.y - y)
|
|
1862
|
+
}
|
|
1863
|
+
} else {
|
|
1864
|
+
if (!this.zero) {
|
|
1865
|
+
x++, y++
|
|
1866
|
+
}
|
|
1867
|
+
this.cup(y, x)
|
|
1868
|
+
}
|
|
1869
|
+
}
|
|
1870
|
+
|
|
1871
|
+
Program.prototype.rsetx = function (x) {
|
|
1872
|
+
// return this.HPositionRelative(x);
|
|
1873
|
+
if (!x) {
|
|
1874
|
+
return
|
|
1875
|
+
}
|
|
1876
|
+
return x > 0 ? this.forward(x) : this.back(-x)
|
|
1877
|
+
}
|
|
1878
|
+
|
|
1879
|
+
Program.prototype.rsety = function (y) {
|
|
1880
|
+
// return this.VPositionRelative(y);
|
|
1881
|
+
if (!y) {
|
|
1882
|
+
return
|
|
1883
|
+
}
|
|
1884
|
+
return y > 0 ? this.up(y) : this.down(-y)
|
|
1885
|
+
}
|
|
1886
|
+
|
|
1887
|
+
Program.prototype.rmove = function (x, y) {
|
|
1888
|
+
this.rsetx(x)
|
|
1889
|
+
this.rsety(y)
|
|
1890
|
+
}
|
|
1891
|
+
|
|
1892
|
+
Program.prototype.simpleInsert = function (ch, i, attr) {
|
|
1893
|
+
return this._write(this.repeat(ch, i), attr)
|
|
1894
|
+
}
|
|
1895
|
+
|
|
1896
|
+
Program.prototype.repeat = function (ch, i) {
|
|
1897
|
+
if (!i || i < 0) {
|
|
1898
|
+
i = 0
|
|
1899
|
+
}
|
|
1900
|
+
return Array(i + 1).join(ch)
|
|
1901
|
+
}
|
|
1902
|
+
|
|
1903
|
+
Program.prototype.__defineGetter__('title', function () {
|
|
1904
|
+
return this._title
|
|
1905
|
+
})
|
|
1906
|
+
|
|
1907
|
+
Program.prototype.__defineSetter__('title', function (title) {
|
|
1908
|
+
this.setTitle(title)
|
|
1909
|
+
return this._title
|
|
1910
|
+
})
|
|
1911
|
+
|
|
1912
|
+
// Specific to iTerm2, but I think it's really cool.
|
|
1913
|
+
// Example:
|
|
1914
|
+
// if (!screen.copyToClipboard(text)) {
|
|
1915
|
+
// execClipboardProgram(text);
|
|
1916
|
+
// }
|
|
1917
|
+
Program.prototype.copyToClipboard = function (text) {
|
|
1918
|
+
if (this.isiTerm2) {
|
|
1919
|
+
this._twrite('\x1b]50;CopyToCliboard=' + text + '\x07')
|
|
1920
|
+
return true
|
|
1921
|
+
}
|
|
1922
|
+
return false
|
|
1923
|
+
}
|
|
1924
|
+
|
|
1925
|
+
// Only XTerm and iTerm2. If you know of any others, post them.
|
|
1926
|
+
Program.prototype.cursorShape = function (shape, blink) {
|
|
1927
|
+
if (this.isiTerm2) {
|
|
1928
|
+
switch (shape) {
|
|
1929
|
+
case 'block':
|
|
1930
|
+
if (!blink) {
|
|
1931
|
+
this._twrite('\x1b]50;CursorShape=0;BlinkingCursorEnabled=0\x07')
|
|
1932
|
+
} else {
|
|
1933
|
+
this._twrite('\x1b]50;CursorShape=0;BlinkingCursorEnabled=1\x07')
|
|
1934
|
+
}
|
|
1935
|
+
break
|
|
1936
|
+
case 'underline':
|
|
1937
|
+
if (!blink) {
|
|
1938
|
+
// this._twrite('\x1b]50;CursorShape=n;BlinkingCursorEnabled=0\x07');
|
|
1939
|
+
} else {
|
|
1940
|
+
// this._twrite('\x1b]50;CursorShape=n;BlinkingCursorEnabled=1\x07');
|
|
1941
|
+
}
|
|
1942
|
+
break
|
|
1943
|
+
case 'line':
|
|
1944
|
+
if (!blink) {
|
|
1945
|
+
this._twrite('\x1b]50;CursorShape=1;BlinkingCursorEnabled=0\x07')
|
|
1946
|
+
} else {
|
|
1947
|
+
this._twrite('\x1b]50;CursorShape=1;BlinkingCursorEnabled=1\x07')
|
|
1948
|
+
}
|
|
1949
|
+
break
|
|
1950
|
+
}
|
|
1951
|
+
return true
|
|
1952
|
+
} else if (this.term('xterm') || this.term('screen')) {
|
|
1953
|
+
switch (shape) {
|
|
1954
|
+
case 'block':
|
|
1955
|
+
if (!blink) {
|
|
1956
|
+
this._twrite('\x1b[0 q')
|
|
1957
|
+
} else {
|
|
1958
|
+
this._twrite('\x1b[1 q')
|
|
1959
|
+
}
|
|
1960
|
+
break
|
|
1961
|
+
case 'underline':
|
|
1962
|
+
if (!blink) {
|
|
1963
|
+
this._twrite('\x1b[2 q')
|
|
1964
|
+
} else {
|
|
1965
|
+
this._twrite('\x1b[3 q')
|
|
1966
|
+
}
|
|
1967
|
+
break
|
|
1968
|
+
case 'line':
|
|
1969
|
+
if (!blink) {
|
|
1970
|
+
this._twrite('\x1b[4 q')
|
|
1971
|
+
} else {
|
|
1972
|
+
this._twrite('\x1b[5 q')
|
|
1973
|
+
}
|
|
1974
|
+
break
|
|
1975
|
+
}
|
|
1976
|
+
return true
|
|
1977
|
+
}
|
|
1978
|
+
return false
|
|
1979
|
+
}
|
|
1980
|
+
|
|
1981
|
+
Program.prototype.cursorColor = function (color) {
|
|
1982
|
+
if (this.term('xterm') || this.term('rxvt') || this.term('screen')) {
|
|
1983
|
+
this._twrite('\x1b]12;' + color + '\x07')
|
|
1984
|
+
return true
|
|
1985
|
+
}
|
|
1986
|
+
return false
|
|
1987
|
+
}
|
|
1988
|
+
|
|
1989
|
+
Program.prototype.cursorReset = Program.prototype.resetCursor = function () {
|
|
1990
|
+
if (this.term('xterm') || this.term('rxvt') || this.term('screen')) {
|
|
1991
|
+
// XXX
|
|
1992
|
+
// return this.resetColors();
|
|
1993
|
+
this._twrite('\x1b[0 q')
|
|
1994
|
+
this._twrite('\x1b]112\x07')
|
|
1995
|
+
// urxvt doesnt support OSC 112
|
|
1996
|
+
this._twrite('\x1b]12;white\x07')
|
|
1997
|
+
return true
|
|
1998
|
+
}
|
|
1999
|
+
return false
|
|
2000
|
+
}
|
|
2001
|
+
|
|
2002
|
+
Program.prototype.getTextParams = function (param, callback) {
|
|
2003
|
+
return this.response(
|
|
2004
|
+
'text-params',
|
|
2005
|
+
'\x1b]' + param + ';?\x07',
|
|
2006
|
+
function (err, data) {
|
|
2007
|
+
if (err) {
|
|
2008
|
+
return callback(err)
|
|
2009
|
+
}
|
|
2010
|
+
return callback(null, data.pt)
|
|
2011
|
+
}
|
|
2012
|
+
)
|
|
2013
|
+
}
|
|
2014
|
+
|
|
2015
|
+
Program.prototype.getCursorColor = function (callback) {
|
|
2016
|
+
return this.getTextParams(12, callback)
|
|
2017
|
+
}
|
|
2018
|
+
|
|
2019
|
+
/**
|
|
2020
|
+
* Normal
|
|
2021
|
+
*/
|
|
2022
|
+
|
|
2023
|
+
//Program.prototype.pad =
|
|
2024
|
+
Program.prototype.nul = function () {
|
|
2025
|
+
//if (this.has('pad')) return this.put.pad();
|
|
2026
|
+
return this._write('\x80')
|
|
2027
|
+
}
|
|
2028
|
+
|
|
2029
|
+
Program.prototype.bel = Program.prototype.bell = function () {
|
|
2030
|
+
if (this.has('bel')) {
|
|
2031
|
+
return this.put.bel()
|
|
2032
|
+
}
|
|
2033
|
+
return this._write('\x07')
|
|
2034
|
+
}
|
|
2035
|
+
|
|
2036
|
+
Program.prototype.vtab = function () {
|
|
2037
|
+
this.y++
|
|
2038
|
+
this._ncoords()
|
|
2039
|
+
return this._write('\x0b')
|
|
2040
|
+
}
|
|
2041
|
+
|
|
2042
|
+
Program.prototype.ff = Program.prototype.form = function () {
|
|
2043
|
+
if (this.has('ff')) {
|
|
2044
|
+
return this.put.ff()
|
|
2045
|
+
}
|
|
2046
|
+
return this._write('\x0c')
|
|
2047
|
+
}
|
|
2048
|
+
|
|
2049
|
+
Program.prototype.kbs = Program.prototype.backspace = function () {
|
|
2050
|
+
this.x--
|
|
2051
|
+
this._ncoords()
|
|
2052
|
+
if (this.has('kbs')) {
|
|
2053
|
+
return this.put.kbs()
|
|
2054
|
+
}
|
|
2055
|
+
return this._write('\x08')
|
|
2056
|
+
}
|
|
2057
|
+
|
|
2058
|
+
Program.prototype.ht = Program.prototype.tab = function () {
|
|
2059
|
+
this.x += 8
|
|
2060
|
+
this._ncoords()
|
|
2061
|
+
if (this.has('ht')) {
|
|
2062
|
+
return this.put.ht()
|
|
2063
|
+
}
|
|
2064
|
+
return this._write('\t')
|
|
2065
|
+
}
|
|
2066
|
+
|
|
2067
|
+
Program.prototype.shiftOut = function () {
|
|
2068
|
+
// if (this.has('S2')) return this.put.S2();
|
|
2069
|
+
return this._write('\x0e')
|
|
2070
|
+
}
|
|
2071
|
+
|
|
2072
|
+
Program.prototype.shiftIn = function () {
|
|
2073
|
+
// if (this.has('S3')) return this.put.S3();
|
|
2074
|
+
return this._write('\x0f')
|
|
2075
|
+
}
|
|
2076
|
+
|
|
2077
|
+
Program.prototype.cr = Program.prototype.return = function () {
|
|
2078
|
+
this.x = 0
|
|
2079
|
+
if (this.has('cr')) {
|
|
2080
|
+
return this.put.cr()
|
|
2081
|
+
}
|
|
2082
|
+
return this._write('\r')
|
|
2083
|
+
}
|
|
2084
|
+
|
|
2085
|
+
Program.prototype.nel =
|
|
2086
|
+
Program.prototype.newline =
|
|
2087
|
+
Program.prototype.feed =
|
|
2088
|
+
function () {
|
|
2089
|
+
if (
|
|
2090
|
+
this.tput &&
|
|
2091
|
+
this.tput.bools.eat_newline_glitch &&
|
|
2092
|
+
this.x >= this.cols
|
|
2093
|
+
) {
|
|
2094
|
+
return
|
|
2095
|
+
}
|
|
2096
|
+
this.x = 0
|
|
2097
|
+
this.y++
|
|
2098
|
+
this._ncoords()
|
|
2099
|
+
if (this.has('nel')) {
|
|
2100
|
+
return this.put.nel()
|
|
2101
|
+
}
|
|
2102
|
+
return this._write('\n')
|
|
2103
|
+
}
|
|
2104
|
+
|
|
2105
|
+
/**
|
|
2106
|
+
* Esc
|
|
2107
|
+
*/
|
|
2108
|
+
|
|
2109
|
+
// ESC D Index (IND is 0x84).
|
|
2110
|
+
Program.prototype.ind = Program.prototype.index = function () {
|
|
2111
|
+
this.y++
|
|
2112
|
+
this._ncoords()
|
|
2113
|
+
if (this.tput) {
|
|
2114
|
+
return this.put.ind()
|
|
2115
|
+
}
|
|
2116
|
+
return this._write('\x1bD')
|
|
2117
|
+
}
|
|
2118
|
+
|
|
2119
|
+
// ESC M Reverse Index (RI is 0x8d).
|
|
2120
|
+
Program.prototype.ri =
|
|
2121
|
+
Program.prototype.reverse =
|
|
2122
|
+
Program.prototype.reverseIndex =
|
|
2123
|
+
function () {
|
|
2124
|
+
this.y--
|
|
2125
|
+
this._ncoords()
|
|
2126
|
+
if (this.tput) {
|
|
2127
|
+
return this.put.ri()
|
|
2128
|
+
}
|
|
2129
|
+
return this._write('\x1bM')
|
|
2130
|
+
}
|
|
2131
|
+
|
|
2132
|
+
// ESC E Next Line (NEL is 0x85).
|
|
2133
|
+
Program.prototype.nextLine = function () {
|
|
2134
|
+
this.y++
|
|
2135
|
+
this.x = 0
|
|
2136
|
+
this._ncoords()
|
|
2137
|
+
if (this.has('nel')) {
|
|
2138
|
+
return this.put.nel()
|
|
2139
|
+
}
|
|
2140
|
+
return this._write('\x1bE')
|
|
2141
|
+
}
|
|
2142
|
+
|
|
2143
|
+
// ESC c Full Reset (RIS).
|
|
2144
|
+
Program.prototype.reset = function () {
|
|
2145
|
+
this.x = this.y = 0
|
|
2146
|
+
if (this.has('rs1') || this.has('ris')) {
|
|
2147
|
+
return this.has('rs1') ? this.put.rs1() : this.put.ris()
|
|
2148
|
+
}
|
|
2149
|
+
return this._write('\x1bc')
|
|
2150
|
+
}
|
|
2151
|
+
|
|
2152
|
+
// ESC H Tab Set (HTS is 0x88).
|
|
2153
|
+
Program.prototype.tabSet = function () {
|
|
2154
|
+
if (this.tput) {
|
|
2155
|
+
return this.put.hts()
|
|
2156
|
+
}
|
|
2157
|
+
return this._write('\x1bH')
|
|
2158
|
+
}
|
|
2159
|
+
|
|
2160
|
+
// ESC 7 Save Cursor (DECSC).
|
|
2161
|
+
Program.prototype.sc = Program.prototype.saveCursor = function (key) {
|
|
2162
|
+
if (key) {
|
|
2163
|
+
return this.lsaveCursor(key)
|
|
2164
|
+
}
|
|
2165
|
+
this.savedX = this.x || 0
|
|
2166
|
+
this.savedY = this.y || 0
|
|
2167
|
+
if (this.tput) {
|
|
2168
|
+
return this.put.sc()
|
|
2169
|
+
}
|
|
2170
|
+
return this._write('\x1b7')
|
|
2171
|
+
}
|
|
2172
|
+
|
|
2173
|
+
// ESC 8 Restore Cursor (DECRC).
|
|
2174
|
+
Program.prototype.rc = Program.prototype.restoreCursor = function (key, hide) {
|
|
2175
|
+
if (key) {
|
|
2176
|
+
return this.lrestoreCursor(key, hide)
|
|
2177
|
+
}
|
|
2178
|
+
this.x = this.savedX || 0
|
|
2179
|
+
this.y = this.savedY || 0
|
|
2180
|
+
if (this.tput) {
|
|
2181
|
+
return this.put.rc()
|
|
2182
|
+
}
|
|
2183
|
+
return this._write('\x1b8')
|
|
2184
|
+
}
|
|
2185
|
+
|
|
2186
|
+
// Save Cursor Locally
|
|
2187
|
+
Program.prototype.lsaveCursor = function (key) {
|
|
2188
|
+
key = key || 'local'
|
|
2189
|
+
this._saved = this._saved || {}
|
|
2190
|
+
this._saved[key] = this._saved[key] || {}
|
|
2191
|
+
this._saved[key].x = this.x
|
|
2192
|
+
this._saved[key].y = this.y
|
|
2193
|
+
this._saved[key].hidden = this.cursorHidden
|
|
2194
|
+
}
|
|
2195
|
+
|
|
2196
|
+
// Restore Cursor Locally
|
|
2197
|
+
Program.prototype.lrestoreCursor = function (key, hide) {
|
|
2198
|
+
let pos
|
|
2199
|
+
key = key || 'local'
|
|
2200
|
+
if (!this._saved || !this._saved[key]) {
|
|
2201
|
+
return
|
|
2202
|
+
}
|
|
2203
|
+
pos = this._saved[key]
|
|
2204
|
+
//delete this._saved[key];
|
|
2205
|
+
this.cup(pos.y, pos.x)
|
|
2206
|
+
if (hide && pos.hidden !== this.cursorHidden) {
|
|
2207
|
+
if (pos.hidden) {
|
|
2208
|
+
this.hideCursor()
|
|
2209
|
+
} else {
|
|
2210
|
+
this.showCursor()
|
|
2211
|
+
}
|
|
2212
|
+
}
|
|
2213
|
+
}
|
|
2214
|
+
|
|
2215
|
+
// ESC # 3 DEC line height/width
|
|
2216
|
+
Program.prototype.lineHeight = function () {
|
|
2217
|
+
return this._write('\x1b#')
|
|
2218
|
+
}
|
|
2219
|
+
|
|
2220
|
+
// ESC (,),*,+,-,. Designate G0-G2 Character Set.
|
|
2221
|
+
Program.prototype.charset = function (val, level) {
|
|
2222
|
+
level = level || 0
|
|
2223
|
+
|
|
2224
|
+
// See also:
|
|
2225
|
+
// acs_chars / acsc / ac
|
|
2226
|
+
// enter_alt_charset_mode / smacs / as
|
|
2227
|
+
// exit_alt_charset_mode / rmacs / ae
|
|
2228
|
+
// enter_pc_charset_mode / smpch / S2
|
|
2229
|
+
// exit_pc_charset_mode / rmpch / S3
|
|
2230
|
+
|
|
2231
|
+
switch (level) {
|
|
2232
|
+
case 0:
|
|
2233
|
+
level = '('
|
|
2234
|
+
break
|
|
2235
|
+
case 1:
|
|
2236
|
+
level = ')'
|
|
2237
|
+
break
|
|
2238
|
+
case 2:
|
|
2239
|
+
level = '*'
|
|
2240
|
+
break
|
|
2241
|
+
case 3:
|
|
2242
|
+
level = '+'
|
|
2243
|
+
break
|
|
2244
|
+
}
|
|
2245
|
+
|
|
2246
|
+
const name = typeof val === 'string' ? val.toLowerCase() : val
|
|
2247
|
+
|
|
2248
|
+
switch (name) {
|
|
2249
|
+
case 'acs':
|
|
2250
|
+
case 'scld': // DEC Special Character and Line Drawing Set.
|
|
2251
|
+
if (this.tput) {
|
|
2252
|
+
return this.put.smacs()
|
|
2253
|
+
}
|
|
2254
|
+
val = '0'
|
|
2255
|
+
break
|
|
2256
|
+
case 'uk': // UK
|
|
2257
|
+
val = 'A'
|
|
2258
|
+
break
|
|
2259
|
+
case 'us': // United States (USASCII).
|
|
2260
|
+
case 'usascii':
|
|
2261
|
+
case 'ascii':
|
|
2262
|
+
if (this.tput) {
|
|
2263
|
+
return this.put.rmacs()
|
|
2264
|
+
}
|
|
2265
|
+
val = 'B'
|
|
2266
|
+
break
|
|
2267
|
+
case 'dutch': // Dutch
|
|
2268
|
+
val = '4'
|
|
2269
|
+
break
|
|
2270
|
+
case 'finnish': // Finnish
|
|
2271
|
+
val = 'C'
|
|
2272
|
+
val = '5'
|
|
2273
|
+
break
|
|
2274
|
+
case 'french': // French
|
|
2275
|
+
val = 'R'
|
|
2276
|
+
break
|
|
2277
|
+
case 'frenchcanadian': // FrenchCanadian
|
|
2278
|
+
val = 'Q'
|
|
2279
|
+
break
|
|
2280
|
+
case 'german': // German
|
|
2281
|
+
val = 'K'
|
|
2282
|
+
break
|
|
2283
|
+
case 'italian': // Italian
|
|
2284
|
+
val = 'Y'
|
|
2285
|
+
break
|
|
2286
|
+
case 'norwegiandanish': // NorwegianDanish
|
|
2287
|
+
val = 'E'
|
|
2288
|
+
val = '6'
|
|
2289
|
+
break
|
|
2290
|
+
case 'spanish': // Spanish
|
|
2291
|
+
val = 'Z'
|
|
2292
|
+
break
|
|
2293
|
+
case 'swedish': // Swedish
|
|
2294
|
+
val = 'H'
|
|
2295
|
+
val = '7'
|
|
2296
|
+
break
|
|
2297
|
+
case 'swiss': // Swiss
|
|
2298
|
+
val = '='
|
|
2299
|
+
break
|
|
2300
|
+
case 'isolatin': // ISOLatin (actually /A)
|
|
2301
|
+
val = '/A'
|
|
2302
|
+
break
|
|
2303
|
+
default: // Default
|
|
2304
|
+
if (this.tput) {
|
|
2305
|
+
return this.put.rmacs()
|
|
2306
|
+
}
|
|
2307
|
+
val = 'B'
|
|
2308
|
+
break
|
|
2309
|
+
}
|
|
2310
|
+
|
|
2311
|
+
return this._write('\x1b(' + val)
|
|
2312
|
+
}
|
|
2313
|
+
|
|
2314
|
+
Program.prototype.enter_alt_charset_mode =
|
|
2315
|
+
Program.prototype.as =
|
|
2316
|
+
Program.prototype.smacs =
|
|
2317
|
+
function () {
|
|
2318
|
+
return this.charset('acs')
|
|
2319
|
+
}
|
|
2320
|
+
|
|
2321
|
+
Program.prototype.exit_alt_charset_mode =
|
|
2322
|
+
Program.prototype.ae =
|
|
2323
|
+
Program.prototype.rmacs =
|
|
2324
|
+
function () {
|
|
2325
|
+
return this.charset('ascii')
|
|
2326
|
+
}
|
|
2327
|
+
|
|
2328
|
+
// ESC N
|
|
2329
|
+
// Single Shift Select of G2 Character Set
|
|
2330
|
+
// ( SS2 is 0x8e). This affects next character only.
|
|
2331
|
+
// ESC O
|
|
2332
|
+
// Single Shift Select of G3 Character Set
|
|
2333
|
+
// ( SS3 is 0x8f). This affects next character only.
|
|
2334
|
+
// ESC n
|
|
2335
|
+
// Invoke the G2 Character Set as GL (LS2).
|
|
2336
|
+
// ESC o
|
|
2337
|
+
// Invoke the G3 Character Set as GL (LS3).
|
|
2338
|
+
// ESC |
|
|
2339
|
+
// Invoke the G3 Character Set as GR (LS3R).
|
|
2340
|
+
// ESC }
|
|
2341
|
+
// Invoke the G2 Character Set as GR (LS2R).
|
|
2342
|
+
// ESC ~
|
|
2343
|
+
// Invoke the G1 Character Set as GR (LS1R).
|
|
2344
|
+
Program.prototype.setG = function (val) {
|
|
2345
|
+
// if (this.tput) return this.put.S2();
|
|
2346
|
+
// if (this.tput) return this.put.S3();
|
|
2347
|
+
switch (val) {
|
|
2348
|
+
case 1:
|
|
2349
|
+
val = '~' // GR
|
|
2350
|
+
break
|
|
2351
|
+
case 2:
|
|
2352
|
+
val = 'n' // GL
|
|
2353
|
+
val = '}' // GR
|
|
2354
|
+
val = 'N' // Next Char Only
|
|
2355
|
+
break
|
|
2356
|
+
case 3:
|
|
2357
|
+
val = 'o' // GL
|
|
2358
|
+
val = '|' // GR
|
|
2359
|
+
val = 'O' // Next Char Only
|
|
2360
|
+
break
|
|
2361
|
+
}
|
|
2362
|
+
return this._write('\x1b' + val)
|
|
2363
|
+
}
|
|
2364
|
+
|
|
2365
|
+
/**
|
|
2366
|
+
* OSC
|
|
2367
|
+
*/
|
|
2368
|
+
|
|
2369
|
+
// OSC Ps ; Pt ST
|
|
2370
|
+
// OSC Ps ; Pt BEL
|
|
2371
|
+
// Set Text Parameters.
|
|
2372
|
+
Program.prototype.setTitle = function (title) {
|
|
2373
|
+
this._title = title
|
|
2374
|
+
|
|
2375
|
+
// if (this.term('screen')) {
|
|
2376
|
+
// // Tmux pane
|
|
2377
|
+
// // if (this.tmux) {
|
|
2378
|
+
// // return this._write('\x1b]2;' + title + '\x1b\\');
|
|
2379
|
+
// // }
|
|
2380
|
+
// return this._write('\x1bk' + title + '\x1b\\');
|
|
2381
|
+
// }
|
|
2382
|
+
|
|
2383
|
+
return this._twrite('\x1b]0;' + title + '\x07')
|
|
2384
|
+
}
|
|
2385
|
+
|
|
2386
|
+
// OSC Ps ; Pt ST
|
|
2387
|
+
// OSC Ps ; Pt BEL
|
|
2388
|
+
// Reset colors
|
|
2389
|
+
Program.prototype.resetColors = function (param) {
|
|
2390
|
+
if (this.has('Cr')) {
|
|
2391
|
+
return this.put.Cr(param)
|
|
2392
|
+
}
|
|
2393
|
+
return this._twrite('\x1b]112\x07')
|
|
2394
|
+
//return this._twrite('\x1b]112;' + param + '\x07');
|
|
2395
|
+
}
|
|
2396
|
+
|
|
2397
|
+
// OSC Ps ; Pt ST
|
|
2398
|
+
// OSC Ps ; Pt BEL
|
|
2399
|
+
// Change dynamic colors
|
|
2400
|
+
Program.prototype.dynamicColors = function (param) {
|
|
2401
|
+
if (this.has('Cs')) {
|
|
2402
|
+
return this.put.Cs(param)
|
|
2403
|
+
}
|
|
2404
|
+
return this._twrite('\x1b]12;' + param + '\x07')
|
|
2405
|
+
}
|
|
2406
|
+
|
|
2407
|
+
// OSC Ps ; Pt ST
|
|
2408
|
+
// OSC Ps ; Pt BEL
|
|
2409
|
+
// Sel data
|
|
2410
|
+
Program.prototype.selData = function (a, b) {
|
|
2411
|
+
if (this.has('Ms')) {
|
|
2412
|
+
return this.put.Ms(a, b)
|
|
2413
|
+
}
|
|
2414
|
+
return this._twrite('\x1b]52;' + a + ';' + b + '\x07')
|
|
2415
|
+
}
|
|
2416
|
+
|
|
2417
|
+
/**
|
|
2418
|
+
* CSI
|
|
2419
|
+
*/
|
|
2420
|
+
|
|
2421
|
+
// CSI Ps A
|
|
2422
|
+
// Cursor Up Ps Times (default = 1) (CUU).
|
|
2423
|
+
Program.prototype.cuu =
|
|
2424
|
+
Program.prototype.up =
|
|
2425
|
+
Program.prototype.cursorUp =
|
|
2426
|
+
function (param) {
|
|
2427
|
+
this.y -= param || 1
|
|
2428
|
+
this._ncoords()
|
|
2429
|
+
if (this.tput) {
|
|
2430
|
+
if (!this.tput.strings.parm_up_cursor) {
|
|
2431
|
+
return this._write(this.repeat(this.tput.cuu1(), param))
|
|
2432
|
+
}
|
|
2433
|
+
return this.put.cuu(param)
|
|
2434
|
+
}
|
|
2435
|
+
return this._write('\x1b[' + (param || '') + 'A')
|
|
2436
|
+
}
|
|
2437
|
+
|
|
2438
|
+
// CSI Ps B
|
|
2439
|
+
// Cursor Down Ps Times (default = 1) (CUD).
|
|
2440
|
+
Program.prototype.cud =
|
|
2441
|
+
Program.prototype.down =
|
|
2442
|
+
Program.prototype.cursorDown =
|
|
2443
|
+
function (param) {
|
|
2444
|
+
this.y += param || 1
|
|
2445
|
+
this._ncoords()
|
|
2446
|
+
if (this.tput) {
|
|
2447
|
+
if (!this.tput.strings.parm_down_cursor) {
|
|
2448
|
+
return this._write(this.repeat(this.tput.cud1(), param))
|
|
2449
|
+
}
|
|
2450
|
+
return this.put.cud(param)
|
|
2451
|
+
}
|
|
2452
|
+
return this._write('\x1b[' + (param || '') + 'B')
|
|
2453
|
+
}
|
|
2454
|
+
|
|
2455
|
+
// CSI Ps C
|
|
2456
|
+
// Cursor Forward Ps Times (default = 1) (CUF).
|
|
2457
|
+
Program.prototype.cuf =
|
|
2458
|
+
Program.prototype.right =
|
|
2459
|
+
Program.prototype.forward =
|
|
2460
|
+
Program.prototype.cursorForward =
|
|
2461
|
+
function (param) {
|
|
2462
|
+
this.x += param || 1
|
|
2463
|
+
this._ncoords()
|
|
2464
|
+
if (this.tput) {
|
|
2465
|
+
if (!this.tput.strings.parm_right_cursor) {
|
|
2466
|
+
return this._write(this.repeat(this.tput.cuf1(), param))
|
|
2467
|
+
}
|
|
2468
|
+
return this.put.cuf(param)
|
|
2469
|
+
}
|
|
2470
|
+
return this._write('\x1b[' + (param || '') + 'C')
|
|
2471
|
+
}
|
|
2472
|
+
|
|
2473
|
+
// CSI Ps D
|
|
2474
|
+
// Cursor Backward Ps Times (default = 1) (CUB).
|
|
2475
|
+
Program.prototype.cub =
|
|
2476
|
+
Program.prototype.left =
|
|
2477
|
+
Program.prototype.back =
|
|
2478
|
+
Program.prototype.cursorBackward =
|
|
2479
|
+
function (param) {
|
|
2480
|
+
this.x -= param || 1
|
|
2481
|
+
this._ncoords()
|
|
2482
|
+
if (this.tput) {
|
|
2483
|
+
if (!this.tput.strings.parm_left_cursor) {
|
|
2484
|
+
return this._write(this.repeat(this.tput.cub1(), param))
|
|
2485
|
+
}
|
|
2486
|
+
return this.put.cub(param)
|
|
2487
|
+
}
|
|
2488
|
+
return this._write('\x1b[' + (param || '') + 'D')
|
|
2489
|
+
}
|
|
2490
|
+
|
|
2491
|
+
// CSI Ps ; Ps H
|
|
2492
|
+
// Cursor Position [row;column] (default = [1,1]) (CUP).
|
|
2493
|
+
Program.prototype.cup =
|
|
2494
|
+
Program.prototype.pos =
|
|
2495
|
+
Program.prototype.cursorPos =
|
|
2496
|
+
function (row, col) {
|
|
2497
|
+
if (!this.zero) {
|
|
2498
|
+
row = (row || 1) - 1
|
|
2499
|
+
col = (col || 1) - 1
|
|
2500
|
+
} else {
|
|
2501
|
+
row = row || 0
|
|
2502
|
+
col = col || 0
|
|
2503
|
+
}
|
|
2504
|
+
this.x = col
|
|
2505
|
+
this.y = row
|
|
2506
|
+
this._ncoords()
|
|
2507
|
+
if (this.tput) {
|
|
2508
|
+
return this.put.cup(row, col)
|
|
2509
|
+
}
|
|
2510
|
+
return this._write('\x1b[' + (row + 1) + ';' + (col + 1) + 'H')
|
|
2511
|
+
}
|
|
2512
|
+
|
|
2513
|
+
// CSI Ps J Erase in Display (ED).
|
|
2514
|
+
// Ps = 0 -> Erase Below (default).
|
|
2515
|
+
// Ps = 1 -> Erase Above.
|
|
2516
|
+
// Ps = 2 -> Erase All.
|
|
2517
|
+
// Ps = 3 -> Erase Saved Lines (xterm).
|
|
2518
|
+
// CSI ? Ps J
|
|
2519
|
+
// Erase in Display (DECSED).
|
|
2520
|
+
// Ps = 0 -> Selective Erase Below (default).
|
|
2521
|
+
// Ps = 1 -> Selective Erase Above.
|
|
2522
|
+
// Ps = 2 -> Selective Erase All.
|
|
2523
|
+
Program.prototype.ed = Program.prototype.eraseInDisplay = function (param) {
|
|
2524
|
+
if (this.tput) {
|
|
2525
|
+
switch (param) {
|
|
2526
|
+
case 'above':
|
|
2527
|
+
param = 1
|
|
2528
|
+
break
|
|
2529
|
+
case 'all':
|
|
2530
|
+
param = 2
|
|
2531
|
+
break
|
|
2532
|
+
case 'saved':
|
|
2533
|
+
param = 3
|
|
2534
|
+
break
|
|
2535
|
+
case 'below':
|
|
2536
|
+
default:
|
|
2537
|
+
param = 0
|
|
2538
|
+
break
|
|
2539
|
+
}
|
|
2540
|
+
// extended tput.E3 = ^[[3;J
|
|
2541
|
+
return this.put.ed(param)
|
|
2542
|
+
}
|
|
2543
|
+
switch (param) {
|
|
2544
|
+
case 'above':
|
|
2545
|
+
return this._write('X1b[1J')
|
|
2546
|
+
case 'all':
|
|
2547
|
+
return this._write('\x1b[2J')
|
|
2548
|
+
case 'saved':
|
|
2549
|
+
return this._write('\x1b[3J')
|
|
2550
|
+
case 'below':
|
|
2551
|
+
default:
|
|
2552
|
+
return this._write('\x1b[J')
|
|
2553
|
+
}
|
|
2554
|
+
}
|
|
2555
|
+
|
|
2556
|
+
Program.prototype.clear = function () {
|
|
2557
|
+
this.x = 0
|
|
2558
|
+
this.y = 0
|
|
2559
|
+
if (this.tput) {
|
|
2560
|
+
return this.put.clear()
|
|
2561
|
+
}
|
|
2562
|
+
return this._write('\x1b[H\x1b[J')
|
|
2563
|
+
}
|
|
2564
|
+
|
|
2565
|
+
// CSI Ps K Erase in Line (EL).
|
|
2566
|
+
// Ps = 0 -> Erase to Right (default).
|
|
2567
|
+
// Ps = 1 -> Erase to Left.
|
|
2568
|
+
// Ps = 2 -> Erase All.
|
|
2569
|
+
// CSI ? Ps K
|
|
2570
|
+
// Erase in Line (DECSEL).
|
|
2571
|
+
// Ps = 0 -> Selective Erase to Right (default).
|
|
2572
|
+
// Ps = 1 -> Selective Erase to Left.
|
|
2573
|
+
// Ps = 2 -> Selective Erase All.
|
|
2574
|
+
Program.prototype.el = Program.prototype.eraseInLine = function (param) {
|
|
2575
|
+
if (this.tput) {
|
|
2576
|
+
//if (this.tput.back_color_erase) ...
|
|
2577
|
+
switch (param) {
|
|
2578
|
+
case 'left':
|
|
2579
|
+
param = 1
|
|
2580
|
+
break
|
|
2581
|
+
case 'all':
|
|
2582
|
+
param = 2
|
|
2583
|
+
break
|
|
2584
|
+
case 'right':
|
|
2585
|
+
default:
|
|
2586
|
+
param = 0
|
|
2587
|
+
break
|
|
2588
|
+
}
|
|
2589
|
+
return this.put.el(param)
|
|
2590
|
+
}
|
|
2591
|
+
switch (param) {
|
|
2592
|
+
case 'left':
|
|
2593
|
+
return this._write('\x1b[1K')
|
|
2594
|
+
case 'all':
|
|
2595
|
+
return this._write('\x1b[2K')
|
|
2596
|
+
case 'right':
|
|
2597
|
+
default:
|
|
2598
|
+
return this._write('\x1b[K')
|
|
2599
|
+
}
|
|
2600
|
+
}
|
|
2601
|
+
|
|
2602
|
+
// CSI Pm m Character Attributes (SGR).
|
|
2603
|
+
// Ps = 0 -> Normal (default).
|
|
2604
|
+
// Ps = 1 -> Bold.
|
|
2605
|
+
// Ps = 4 -> Underlined.
|
|
2606
|
+
// Ps = 5 -> Blink (appears as Bold).
|
|
2607
|
+
// Ps = 7 -> Inverse.
|
|
2608
|
+
// Ps = 8 -> Invisible, i.e., hidden (VT300).
|
|
2609
|
+
// Ps = 2 2 -> Normal (neither bold nor faint).
|
|
2610
|
+
// Ps = 2 4 -> Not underlined.
|
|
2611
|
+
// Ps = 2 5 -> Steady (not blinking).
|
|
2612
|
+
// Ps = 2 7 -> Positive (not inverse).
|
|
2613
|
+
// Ps = 2 8 -> Visible, i.e., not hidden (VT300).
|
|
2614
|
+
// Ps = 3 0 -> Set foreground color to Black.
|
|
2615
|
+
// Ps = 3 1 -> Set foreground color to Red.
|
|
2616
|
+
// Ps = 3 2 -> Set foreground color to Green.
|
|
2617
|
+
// Ps = 3 3 -> Set foreground color to Yellow.
|
|
2618
|
+
// Ps = 3 4 -> Set foreground color to Blue.
|
|
2619
|
+
// Ps = 3 5 -> Set foreground color to Magenta.
|
|
2620
|
+
// Ps = 3 6 -> Set foreground color to Cyan.
|
|
2621
|
+
// Ps = 3 7 -> Set foreground color to White.
|
|
2622
|
+
// Ps = 3 9 -> Set foreground color to default (original).
|
|
2623
|
+
// Ps = 4 0 -> Set background color to Black.
|
|
2624
|
+
// Ps = 4 1 -> Set background color to Red.
|
|
2625
|
+
// Ps = 4 2 -> Set background color to Green.
|
|
2626
|
+
// Ps = 4 3 -> Set background color to Yellow.
|
|
2627
|
+
// Ps = 4 4 -> Set background color to Blue.
|
|
2628
|
+
// Ps = 4 5 -> Set background color to Magenta.
|
|
2629
|
+
// Ps = 4 6 -> Set background color to Cyan.
|
|
2630
|
+
// Ps = 4 7 -> Set background color to White.
|
|
2631
|
+
// Ps = 4 9 -> Set background color to default (original).
|
|
2632
|
+
|
|
2633
|
+
// If 16-color support is compiled, the following apply. Assume
|
|
2634
|
+
// that xterm's resources are set so that the ISO color codes are
|
|
2635
|
+
// the first 8 of a set of 16. Then the aixterm colors are the
|
|
2636
|
+
// bright versions of the ISO colors:
|
|
2637
|
+
// Ps = 9 0 -> Set foreground color to Black.
|
|
2638
|
+
// Ps = 9 1 -> Set foreground color to Red.
|
|
2639
|
+
// Ps = 9 2 -> Set foreground color to Green.
|
|
2640
|
+
// Ps = 9 3 -> Set foreground color to Yellow.
|
|
2641
|
+
// Ps = 9 4 -> Set foreground color to Blue.
|
|
2642
|
+
// Ps = 9 5 -> Set foreground color to Magenta.
|
|
2643
|
+
// Ps = 9 6 -> Set foreground color to Cyan.
|
|
2644
|
+
// Ps = 9 7 -> Set foreground color to White.
|
|
2645
|
+
// Ps = 1 0 0 -> Set background color to Black.
|
|
2646
|
+
// Ps = 1 0 1 -> Set background color to Red.
|
|
2647
|
+
// Ps = 1 0 2 -> Set background color to Green.
|
|
2648
|
+
// Ps = 1 0 3 -> Set background color to Yellow.
|
|
2649
|
+
// Ps = 1 0 4 -> Set background color to Blue.
|
|
2650
|
+
// Ps = 1 0 5 -> Set background color to Magenta.
|
|
2651
|
+
// Ps = 1 0 6 -> Set background color to Cyan.
|
|
2652
|
+
// Ps = 1 0 7 -> Set background color to White.
|
|
2653
|
+
|
|
2654
|
+
// If xterm is compiled with the 16-color support disabled, it
|
|
2655
|
+
// supports the following, from rxvt:
|
|
2656
|
+
// Ps = 1 0 0 -> Set foreground and background color to
|
|
2657
|
+
// default.
|
|
2658
|
+
|
|
2659
|
+
// If 88- or 256-color support is compiled, the following apply.
|
|
2660
|
+
// Ps = 3 8 ; 5 ; Ps -> Set foreground color to the second
|
|
2661
|
+
// Ps.
|
|
2662
|
+
// Ps = 4 8 ; 5 ; Ps -> Set background color to the second
|
|
2663
|
+
// Ps.
|
|
2664
|
+
Program.prototype.sgr =
|
|
2665
|
+
Program.prototype.attr =
|
|
2666
|
+
Program.prototype.charAttributes =
|
|
2667
|
+
function (param, val) {
|
|
2668
|
+
return this._write(this._attr(param, val))
|
|
2669
|
+
}
|
|
2670
|
+
|
|
2671
|
+
Program.prototype.text = function (text, attr) {
|
|
2672
|
+
return this._attr(attr, true) + text + this._attr(attr, false)
|
|
2673
|
+
}
|
|
2674
|
+
|
|
2675
|
+
// NOTE: sun-color may not allow multiple params for SGR.
|
|
2676
|
+
Program.prototype._attr = function (param, val) {
|
|
2677
|
+
let self = this,
|
|
2678
|
+
parts,
|
|
2679
|
+
color,
|
|
2680
|
+
m
|
|
2681
|
+
|
|
2682
|
+
if (Array.isArray(param)) {
|
|
2683
|
+
parts = param
|
|
2684
|
+
param = parts[0] || 'normal'
|
|
2685
|
+
} else {
|
|
2686
|
+
param = param || 'normal'
|
|
2687
|
+
parts = param.split(/\s*[,;]\s*/)
|
|
2688
|
+
}
|
|
2689
|
+
|
|
2690
|
+
if (parts.length > 1) {
|
|
2691
|
+
const used = {},
|
|
2692
|
+
out = []
|
|
2693
|
+
|
|
2694
|
+
parts.forEach(function (part) {
|
|
2695
|
+
part = self._attr(part, val).slice(2, -1)
|
|
2696
|
+
if (part === '') {
|
|
2697
|
+
return
|
|
2698
|
+
}
|
|
2699
|
+
if (used[part]) {
|
|
2700
|
+
return
|
|
2701
|
+
}
|
|
2702
|
+
used[part] = true
|
|
2703
|
+
out.push(part)
|
|
2704
|
+
})
|
|
2705
|
+
|
|
2706
|
+
return '\x1b[' + out.join(';') + 'm'
|
|
2707
|
+
}
|
|
2708
|
+
|
|
2709
|
+
if (param.indexOf('no ') === 0) {
|
|
2710
|
+
param = param.substring(3)
|
|
2711
|
+
val = false
|
|
2712
|
+
} else if (param.indexOf('!') === 0) {
|
|
2713
|
+
param = param.substring(1)
|
|
2714
|
+
val = false
|
|
2715
|
+
}
|
|
2716
|
+
|
|
2717
|
+
switch (param) {
|
|
2718
|
+
// attributes
|
|
2719
|
+
case 'normal':
|
|
2720
|
+
case 'default':
|
|
2721
|
+
if (val === false) {
|
|
2722
|
+
return ''
|
|
2723
|
+
}
|
|
2724
|
+
return '\x1b[m'
|
|
2725
|
+
case 'bold':
|
|
2726
|
+
return val === false ? '\x1b[22m' : '\x1b[1m'
|
|
2727
|
+
case 'ul':
|
|
2728
|
+
case 'underline':
|
|
2729
|
+
case 'underlined':
|
|
2730
|
+
return val === false ? '\x1b[24m' : '\x1b[4m'
|
|
2731
|
+
case 'blink':
|
|
2732
|
+
return val === false ? '\x1b[25m' : '\x1b[5m'
|
|
2733
|
+
case 'inverse':
|
|
2734
|
+
return val === false ? '\x1b[27m' : '\x1b[7m'
|
|
2735
|
+
case 'invisible':
|
|
2736
|
+
return val === false ? '\x1b[28m' : '\x1b[8m'
|
|
2737
|
+
|
|
2738
|
+
// 8-color foreground
|
|
2739
|
+
case 'black fg':
|
|
2740
|
+
return val === false ? '\x1b[39m' : '\x1b[30m'
|
|
2741
|
+
case 'red fg':
|
|
2742
|
+
return val === false ? '\x1b[39m' : '\x1b[31m'
|
|
2743
|
+
case 'green fg':
|
|
2744
|
+
return val === false ? '\x1b[39m' : '\x1b[32m'
|
|
2745
|
+
case 'yellow fg':
|
|
2746
|
+
return val === false ? '\x1b[39m' : '\x1b[33m'
|
|
2747
|
+
case 'blue fg':
|
|
2748
|
+
return val === false ? '\x1b[39m' : '\x1b[34m'
|
|
2749
|
+
case 'magenta fg':
|
|
2750
|
+
return val === false ? '\x1b[39m' : '\x1b[35m'
|
|
2751
|
+
case 'cyan fg':
|
|
2752
|
+
return val === false ? '\x1b[39m' : '\x1b[36m'
|
|
2753
|
+
case 'white fg':
|
|
2754
|
+
case 'light grey fg':
|
|
2755
|
+
case 'light gray fg':
|
|
2756
|
+
case 'bright grey fg':
|
|
2757
|
+
case 'bright gray fg':
|
|
2758
|
+
return val === false ? '\x1b[39m' : '\x1b[37m'
|
|
2759
|
+
case 'default fg':
|
|
2760
|
+
if (val === false) {
|
|
2761
|
+
return ''
|
|
2762
|
+
}
|
|
2763
|
+
return '\x1b[39m'
|
|
2764
|
+
|
|
2765
|
+
// 8-color background
|
|
2766
|
+
case 'black bg':
|
|
2767
|
+
return val === false ? '\x1b[49m' : '\x1b[40m'
|
|
2768
|
+
case 'red bg':
|
|
2769
|
+
return val === false ? '\x1b[49m' : '\x1b[41m'
|
|
2770
|
+
case 'green bg':
|
|
2771
|
+
return val === false ? '\x1b[49m' : '\x1b[42m'
|
|
2772
|
+
case 'yellow bg':
|
|
2773
|
+
return val === false ? '\x1b[49m' : '\x1b[43m'
|
|
2774
|
+
case 'blue bg':
|
|
2775
|
+
return val === false ? '\x1b[49m' : '\x1b[44m'
|
|
2776
|
+
case 'magenta bg':
|
|
2777
|
+
return val === false ? '\x1b[49m' : '\x1b[45m'
|
|
2778
|
+
case 'cyan bg':
|
|
2779
|
+
return val === false ? '\x1b[49m' : '\x1b[46m'
|
|
2780
|
+
case 'white bg':
|
|
2781
|
+
case 'light grey bg':
|
|
2782
|
+
case 'light gray bg':
|
|
2783
|
+
case 'bright grey bg':
|
|
2784
|
+
case 'bright gray bg':
|
|
2785
|
+
return val === false ? '\x1b[49m' : '\x1b[47m'
|
|
2786
|
+
case 'default bg':
|
|
2787
|
+
if (val === false) {
|
|
2788
|
+
return ''
|
|
2789
|
+
}
|
|
2790
|
+
return '\x1b[49m'
|
|
2791
|
+
|
|
2792
|
+
// 16-color foreground
|
|
2793
|
+
case 'light black fg':
|
|
2794
|
+
case 'bright black fg':
|
|
2795
|
+
case 'grey fg':
|
|
2796
|
+
case 'gray fg':
|
|
2797
|
+
return val === false ? '\x1b[39m' : '\x1b[90m'
|
|
2798
|
+
case 'light red fg':
|
|
2799
|
+
case 'bright red fg':
|
|
2800
|
+
return val === false ? '\x1b[39m' : '\x1b[91m'
|
|
2801
|
+
case 'light green fg':
|
|
2802
|
+
case 'bright green fg':
|
|
2803
|
+
return val === false ? '\x1b[39m' : '\x1b[92m'
|
|
2804
|
+
case 'light yellow fg':
|
|
2805
|
+
case 'bright yellow fg':
|
|
2806
|
+
return val === false ? '\x1b[39m' : '\x1b[93m'
|
|
2807
|
+
case 'light blue fg':
|
|
2808
|
+
case 'bright blue fg':
|
|
2809
|
+
return val === false ? '\x1b[39m' : '\x1b[94m'
|
|
2810
|
+
case 'light magenta fg':
|
|
2811
|
+
case 'bright magenta fg':
|
|
2812
|
+
return val === false ? '\x1b[39m' : '\x1b[95m'
|
|
2813
|
+
case 'light cyan fg':
|
|
2814
|
+
case 'bright cyan fg':
|
|
2815
|
+
return val === false ? '\x1b[39m' : '\x1b[96m'
|
|
2816
|
+
case 'light white fg':
|
|
2817
|
+
case 'bright white fg':
|
|
2818
|
+
return val === false ? '\x1b[39m' : '\x1b[97m'
|
|
2819
|
+
|
|
2820
|
+
// 16-color background
|
|
2821
|
+
case 'light black bg':
|
|
2822
|
+
case 'bright black bg':
|
|
2823
|
+
case 'grey bg':
|
|
2824
|
+
case 'gray bg':
|
|
2825
|
+
return val === false ? '\x1b[49m' : '\x1b[100m'
|
|
2826
|
+
case 'light red bg':
|
|
2827
|
+
case 'bright red bg':
|
|
2828
|
+
return val === false ? '\x1b[49m' : '\x1b[101m'
|
|
2829
|
+
case 'light green bg':
|
|
2830
|
+
case 'bright green bg':
|
|
2831
|
+
return val === false ? '\x1b[49m' : '\x1b[102m'
|
|
2832
|
+
case 'light yellow bg':
|
|
2833
|
+
case 'bright yellow bg':
|
|
2834
|
+
return val === false ? '\x1b[49m' : '\x1b[103m'
|
|
2835
|
+
case 'light blue bg':
|
|
2836
|
+
case 'bright blue bg':
|
|
2837
|
+
return val === false ? '\x1b[49m' : '\x1b[104m'
|
|
2838
|
+
case 'light magenta bg':
|
|
2839
|
+
case 'bright magenta bg':
|
|
2840
|
+
return val === false ? '\x1b[49m' : '\x1b[105m'
|
|
2841
|
+
case 'light cyan bg':
|
|
2842
|
+
case 'bright cyan bg':
|
|
2843
|
+
return val === false ? '\x1b[49m' : '\x1b[106m'
|
|
2844
|
+
case 'light white bg':
|
|
2845
|
+
case 'bright white bg':
|
|
2846
|
+
return val === false ? '\x1b[49m' : '\x1b[107m'
|
|
2847
|
+
|
|
2848
|
+
// non-16-color rxvt default fg and bg
|
|
2849
|
+
case 'default fg bg':
|
|
2850
|
+
if (val === false) {
|
|
2851
|
+
return ''
|
|
2852
|
+
}
|
|
2853
|
+
return this.term('rxvt') ? '\x1b[100m' : '\x1b[39;49m'
|
|
2854
|
+
|
|
2855
|
+
default:
|
|
2856
|
+
// 256-color fg and bg
|
|
2857
|
+
if (param[0] === '#') {
|
|
2858
|
+
param = param.replace(/#(?:[0-9a-f]{3}){1,2}/i, colors.match)
|
|
2859
|
+
}
|
|
2860
|
+
|
|
2861
|
+
m = /^(-?\d+) (fg|bg)$/.exec(param)
|
|
2862
|
+
if (m) {
|
|
2863
|
+
color = +m[1]
|
|
2864
|
+
|
|
2865
|
+
if (val === false || color === -1) {
|
|
2866
|
+
return this._attr('default ' + m[2])
|
|
2867
|
+
}
|
|
2868
|
+
|
|
2869
|
+
color = colors.reduce(color, this.tput.colors)
|
|
2870
|
+
|
|
2871
|
+
if (color < 16 || (this.tput && this.tput.colors <= 16)) {
|
|
2872
|
+
if (m[2] === 'fg') {
|
|
2873
|
+
if (color < 8) {
|
|
2874
|
+
color += 30
|
|
2875
|
+
} else if (color < 16) {
|
|
2876
|
+
color -= 8
|
|
2877
|
+
color += 90
|
|
2878
|
+
}
|
|
2879
|
+
} else if (m[2] === 'bg') {
|
|
2880
|
+
if (color < 8) {
|
|
2881
|
+
color += 40
|
|
2882
|
+
} else if (color < 16) {
|
|
2883
|
+
color -= 8
|
|
2884
|
+
color += 100
|
|
2885
|
+
}
|
|
2886
|
+
}
|
|
2887
|
+
return '\x1b[' + color + 'm'
|
|
2888
|
+
}
|
|
2889
|
+
|
|
2890
|
+
if (m[2] === 'fg') {
|
|
2891
|
+
return '\x1b[38;5;' + color + 'm'
|
|
2892
|
+
}
|
|
2893
|
+
|
|
2894
|
+
if (m[2] === 'bg') {
|
|
2895
|
+
return '\x1b[48;5;' + color + 'm'
|
|
2896
|
+
}
|
|
2897
|
+
}
|
|
2898
|
+
|
|
2899
|
+
if (/^[\d;]*$/.test(param)) {
|
|
2900
|
+
return '\x1b[' + param + 'm'
|
|
2901
|
+
}
|
|
2902
|
+
|
|
2903
|
+
return null
|
|
2904
|
+
}
|
|
2905
|
+
}
|
|
2906
|
+
|
|
2907
|
+
Program.prototype.fg = Program.prototype.setForeground = function (color, val) {
|
|
2908
|
+
color = color.split(/\s*[,;]\s*/).join(' fg, ') + ' fg'
|
|
2909
|
+
return this.attr(color, val)
|
|
2910
|
+
}
|
|
2911
|
+
|
|
2912
|
+
Program.prototype.bg = Program.prototype.setBackground = function (color, val) {
|
|
2913
|
+
color = color.split(/\s*[,;]\s*/).join(' bg, ') + ' bg'
|
|
2914
|
+
return this.attr(color, val)
|
|
2915
|
+
}
|
|
2916
|
+
|
|
2917
|
+
// CSI Ps n Device Status Report (DSR).
|
|
2918
|
+
// Ps = 5 -> Status Report. Result (``OK'') is
|
|
2919
|
+
// CSI 0 n
|
|
2920
|
+
// Ps = 6 -> Report Cursor Position (CPR) [row;column].
|
|
2921
|
+
// Result is
|
|
2922
|
+
// CSI r ; c R
|
|
2923
|
+
// CSI ? Ps n
|
|
2924
|
+
// Device Status Report (DSR, DEC-specific).
|
|
2925
|
+
// Ps = 6 -> Report Cursor Position (CPR) [row;column] as CSI
|
|
2926
|
+
// ? r ; c R (assumes page is zero).
|
|
2927
|
+
// Ps = 1 5 -> Report Printer status as CSI ? 1 0 n (ready).
|
|
2928
|
+
// or CSI ? 1 1 n (not ready).
|
|
2929
|
+
// Ps = 2 5 -> Report UDK status as CSI ? 2 0 n (unlocked)
|
|
2930
|
+
// or CSI ? 2 1 n (locked).
|
|
2931
|
+
// Ps = 2 6 -> Report Keyboard status as
|
|
2932
|
+
// CSI ? 2 7 ; 1 ; 0 ; 0 n (North American).
|
|
2933
|
+
// The last two parameters apply to VT400 & up, and denote key-
|
|
2934
|
+
// board ready and LK01 respectively.
|
|
2935
|
+
// Ps = 5 3 -> Report Locator status as
|
|
2936
|
+
// CSI ? 5 3 n Locator available, if compiled-in, or
|
|
2937
|
+
// CSI ? 5 0 n No Locator, if not.
|
|
2938
|
+
Program.prototype.dsr = Program.prototype.deviceStatus = function (
|
|
2939
|
+
param,
|
|
2940
|
+
callback,
|
|
2941
|
+
dec,
|
|
2942
|
+
noBypass
|
|
2943
|
+
) {
|
|
2944
|
+
if (dec) {
|
|
2945
|
+
return this.response(
|
|
2946
|
+
'device-status',
|
|
2947
|
+
'\x1b[?' + (param || '0') + 'n',
|
|
2948
|
+
callback,
|
|
2949
|
+
noBypass
|
|
2950
|
+
)
|
|
2951
|
+
}
|
|
2952
|
+
return this.response(
|
|
2953
|
+
'device-status',
|
|
2954
|
+
'\x1b[' + (param || '0') + 'n',
|
|
2955
|
+
callback,
|
|
2956
|
+
noBypass
|
|
2957
|
+
)
|
|
2958
|
+
}
|
|
2959
|
+
|
|
2960
|
+
Program.prototype.getCursor = function (callback) {
|
|
2961
|
+
return this.deviceStatus(6, callback, false, true)
|
|
2962
|
+
}
|
|
2963
|
+
|
|
2964
|
+
Program.prototype.saveReportedCursor = function (callback) {
|
|
2965
|
+
const self = this
|
|
2966
|
+
if (this.tput.strings.user7 === '\x1b[6n' || this.term('screen')) {
|
|
2967
|
+
return this.getCursor(function (err, data) {
|
|
2968
|
+
if (data) {
|
|
2969
|
+
self._rx = data.status.x
|
|
2970
|
+
self._ry = data.status.y
|
|
2971
|
+
}
|
|
2972
|
+
if (!callback) {
|
|
2973
|
+
return
|
|
2974
|
+
}
|
|
2975
|
+
return callback(err)
|
|
2976
|
+
})
|
|
2977
|
+
}
|
|
2978
|
+
if (!callback) {
|
|
2979
|
+
return
|
|
2980
|
+
}
|
|
2981
|
+
return callback()
|
|
2982
|
+
}
|
|
2983
|
+
|
|
2984
|
+
Program.prototype.restoreReportedCursor = function () {
|
|
2985
|
+
if (this._rx == null) {
|
|
2986
|
+
return
|
|
2987
|
+
}
|
|
2988
|
+
return this.cup(this._ry, this._rx)
|
|
2989
|
+
// return this.nel();
|
|
2990
|
+
}
|
|
2991
|
+
|
|
2992
|
+
/**
|
|
2993
|
+
* Additions
|
|
2994
|
+
*/
|
|
2995
|
+
|
|
2996
|
+
// CSI Ps @
|
|
2997
|
+
// Insert Ps (Blank) Character(s) (default = 1) (ICH).
|
|
2998
|
+
Program.prototype.ich = Program.prototype.insertChars = function (param) {
|
|
2999
|
+
this.x += param || 1
|
|
3000
|
+
this._ncoords()
|
|
3001
|
+
if (this.tput) {
|
|
3002
|
+
return this.put.ich(param)
|
|
3003
|
+
}
|
|
3004
|
+
return this._write('\x1b[' + (param || 1) + '@')
|
|
3005
|
+
}
|
|
3006
|
+
|
|
3007
|
+
// CSI Ps E
|
|
3008
|
+
// Cursor Next Line Ps Times (default = 1) (CNL).
|
|
3009
|
+
// same as CSI Ps B ?
|
|
3010
|
+
Program.prototype.cnl = Program.prototype.cursorNextLine = function (param) {
|
|
3011
|
+
this.y += param || 1
|
|
3012
|
+
this._ncoords()
|
|
3013
|
+
return this._write('\x1b[' + (param || '') + 'E')
|
|
3014
|
+
}
|
|
3015
|
+
|
|
3016
|
+
// CSI Ps F
|
|
3017
|
+
// Cursor Preceding Line Ps Times (default = 1) (CNL).
|
|
3018
|
+
// reuse CSI Ps A ?
|
|
3019
|
+
Program.prototype.cpl = Program.prototype.cursorPrecedingLine = function (
|
|
3020
|
+
param
|
|
3021
|
+
) {
|
|
3022
|
+
this.y -= param || 1
|
|
3023
|
+
this._ncoords()
|
|
3024
|
+
return this._write('\x1b[' + (param || '') + 'F')
|
|
3025
|
+
}
|
|
3026
|
+
|
|
3027
|
+
// CSI Ps G
|
|
3028
|
+
// Cursor Character Absolute [column] (default = [row,1]) (CHA).
|
|
3029
|
+
Program.prototype.cha = Program.prototype.cursorCharAbsolute = function (
|
|
3030
|
+
param
|
|
3031
|
+
) {
|
|
3032
|
+
if (!this.zero) {
|
|
3033
|
+
param = (param || 1) - 1
|
|
3034
|
+
} else {
|
|
3035
|
+
param = param || 0
|
|
3036
|
+
}
|
|
3037
|
+
this.x = param
|
|
3038
|
+
this.y = 0
|
|
3039
|
+
this._ncoords()
|
|
3040
|
+
if (this.tput) {
|
|
3041
|
+
return this.put.hpa(param)
|
|
3042
|
+
}
|
|
3043
|
+
return this._write('\x1b[' + (param + 1) + 'G')
|
|
3044
|
+
}
|
|
3045
|
+
|
|
3046
|
+
// CSI Ps L
|
|
3047
|
+
// Insert Ps Line(s) (default = 1) (IL).
|
|
3048
|
+
Program.prototype.il = Program.prototype.insertLines = function (param) {
|
|
3049
|
+
if (this.tput) {
|
|
3050
|
+
return this.put.il(param)
|
|
3051
|
+
}
|
|
3052
|
+
return this._write('\x1b[' + (param || '') + 'L')
|
|
3053
|
+
}
|
|
3054
|
+
|
|
3055
|
+
// CSI Ps M
|
|
3056
|
+
// Delete Ps Line(s) (default = 1) (DL).
|
|
3057
|
+
Program.prototype.dl = Program.prototype.deleteLines = function (param) {
|
|
3058
|
+
if (this.tput) {
|
|
3059
|
+
return this.put.dl(param)
|
|
3060
|
+
}
|
|
3061
|
+
return this._write('\x1b[' + (param || '') + 'M')
|
|
3062
|
+
}
|
|
3063
|
+
|
|
3064
|
+
// CSI Ps P
|
|
3065
|
+
// Delete Ps Character(s) (default = 1) (DCH).
|
|
3066
|
+
Program.prototype.dch = Program.prototype.deleteChars = function (param) {
|
|
3067
|
+
if (this.tput) {
|
|
3068
|
+
return this.put.dch(param)
|
|
3069
|
+
}
|
|
3070
|
+
return this._write('\x1b[' + (param || '') + 'P')
|
|
3071
|
+
}
|
|
3072
|
+
|
|
3073
|
+
// CSI Ps X
|
|
3074
|
+
// Erase Ps Character(s) (default = 1) (ECH).
|
|
3075
|
+
Program.prototype.ech = Program.prototype.eraseChars = function (param) {
|
|
3076
|
+
if (this.tput) {
|
|
3077
|
+
return this.put.ech(param)
|
|
3078
|
+
}
|
|
3079
|
+
return this._write('\x1b[' + (param || '') + 'X')
|
|
3080
|
+
}
|
|
3081
|
+
|
|
3082
|
+
// CSI Pm ` Character Position Absolute
|
|
3083
|
+
// [column] (default = [row,1]) (HPA).
|
|
3084
|
+
Program.prototype.hpa = Program.prototype.charPosAbsolute = function (param) {
|
|
3085
|
+
this.x = param || 0
|
|
3086
|
+
this._ncoords()
|
|
3087
|
+
if (this.tput) {
|
|
3088
|
+
return this.put.hpa.apply(this.put, arguments)
|
|
3089
|
+
}
|
|
3090
|
+
param = slice.call(arguments).join(';')
|
|
3091
|
+
return this._write('\x1b[' + (param || '') + '`')
|
|
3092
|
+
}
|
|
3093
|
+
|
|
3094
|
+
// 141 61 a * HPR -
|
|
3095
|
+
// Horizontal Position Relative
|
|
3096
|
+
// reuse CSI Ps C ?
|
|
3097
|
+
Program.prototype.hpr = Program.prototype.HPositionRelative = function (param) {
|
|
3098
|
+
if (this.tput) {
|
|
3099
|
+
return this.cuf(param)
|
|
3100
|
+
}
|
|
3101
|
+
this.x += param || 1
|
|
3102
|
+
this._ncoords()
|
|
3103
|
+
// Does not exist:
|
|
3104
|
+
// if (this.tput) return this.put.hpr(param);
|
|
3105
|
+
return this._write('\x1b[' + (param || '') + 'a')
|
|
3106
|
+
}
|
|
3107
|
+
|
|
3108
|
+
// CSI Ps c Send Device Attributes (Primary DA).
|
|
3109
|
+
// Ps = 0 or omitted -> request attributes from terminal. The
|
|
3110
|
+
// response depends on the decTerminalID resource setting.
|
|
3111
|
+
// -> CSI ? 1 ; 2 c (``VT100 with Advanced Video Option'')
|
|
3112
|
+
// -> CSI ? 1 ; 0 c (``VT101 with No Options'')
|
|
3113
|
+
// -> CSI ? 6 c (``VT102'')
|
|
3114
|
+
// -> CSI ? 6 0 ; 1 ; 2 ; 6 ; 8 ; 9 ; 1 5 ; c (``VT220'')
|
|
3115
|
+
// The VT100-style response parameters do not mean anything by
|
|
3116
|
+
// themselves. VT220 parameters do, telling the host what fea-
|
|
3117
|
+
// tures the terminal supports:
|
|
3118
|
+
// Ps = 1 -> 132-columns.
|
|
3119
|
+
// Ps = 2 -> Printer.
|
|
3120
|
+
// Ps = 6 -> Selective erase.
|
|
3121
|
+
// Ps = 8 -> User-defined keys.
|
|
3122
|
+
// Ps = 9 -> National replacement character sets.
|
|
3123
|
+
// Ps = 1 5 -> Technical characters.
|
|
3124
|
+
// Ps = 2 2 -> ANSI color, e.g., VT525.
|
|
3125
|
+
// Ps = 2 9 -> ANSI text locator (i.e., DEC Locator mode).
|
|
3126
|
+
// CSI > Ps c
|
|
3127
|
+
// Send Device Attributes (Secondary DA).
|
|
3128
|
+
// Ps = 0 or omitted -> request the terminal's identification
|
|
3129
|
+
// code. The response depends on the decTerminalID resource set-
|
|
3130
|
+
// ting. It should apply only to VT220 and up, but xterm extends
|
|
3131
|
+
// this to VT100.
|
|
3132
|
+
// -> CSI > Pp ; Pv ; Pc c
|
|
3133
|
+
// where Pp denotes the terminal type
|
|
3134
|
+
// Pp = 0 -> ``VT100''.
|
|
3135
|
+
// Pp = 1 -> ``VT220''.
|
|
3136
|
+
// and Pv is the firmware version (for xterm, this was originally
|
|
3137
|
+
// the XFree86 patch number, starting with 95). In a DEC termi-
|
|
3138
|
+
// nal, Pc indicates the ROM cartridge registration number and is
|
|
3139
|
+
// always zero.
|
|
3140
|
+
// More information:
|
|
3141
|
+
// xterm/charproc.c - line 2012, for more information.
|
|
3142
|
+
// vim responds with ^[[?0c or ^[[?1c after the terminal's response (?)
|
|
3143
|
+
Program.prototype.da = Program.prototype.sendDeviceAttributes = function (
|
|
3144
|
+
param,
|
|
3145
|
+
callback
|
|
3146
|
+
) {
|
|
3147
|
+
return this.response(
|
|
3148
|
+
'device-attributes',
|
|
3149
|
+
'\x1b[' + (param || '') + 'c',
|
|
3150
|
+
callback
|
|
3151
|
+
)
|
|
3152
|
+
}
|
|
3153
|
+
|
|
3154
|
+
// CSI Pm d
|
|
3155
|
+
// Line Position Absolute [row] (default = [1,column]) (VPA).
|
|
3156
|
+
// NOTE: Can't find in terminfo, no idea why it has multiple params.
|
|
3157
|
+
Program.prototype.vpa = Program.prototype.linePosAbsolute = function (param) {
|
|
3158
|
+
this.y = param || 1
|
|
3159
|
+
this._ncoords()
|
|
3160
|
+
if (this.tput) {
|
|
3161
|
+
return this.put.vpa.apply(this.put, arguments)
|
|
3162
|
+
}
|
|
3163
|
+
param = slice.call(arguments).join(';')
|
|
3164
|
+
return this._write('\x1b[' + (param || '') + 'd')
|
|
3165
|
+
}
|
|
3166
|
+
|
|
3167
|
+
// 145 65 e * VPR - Vertical Position Relative
|
|
3168
|
+
// reuse CSI Ps B ?
|
|
3169
|
+
Program.prototype.vpr = Program.prototype.VPositionRelative = function (param) {
|
|
3170
|
+
if (this.tput) {
|
|
3171
|
+
return this.cud(param)
|
|
3172
|
+
}
|
|
3173
|
+
this.y += param || 1
|
|
3174
|
+
this._ncoords()
|
|
3175
|
+
// Does not exist:
|
|
3176
|
+
// if (this.tput) return this.put.vpr(param);
|
|
3177
|
+
return this._write('\x1b[' + (param || '') + 'e')
|
|
3178
|
+
}
|
|
3179
|
+
|
|
3180
|
+
// CSI Ps ; Ps f
|
|
3181
|
+
// Horizontal and Vertical Position [row;column] (default =
|
|
3182
|
+
// [1,1]) (HVP).
|
|
3183
|
+
Program.prototype.hvp = Program.prototype.HVPosition = function (row, col) {
|
|
3184
|
+
if (!this.zero) {
|
|
3185
|
+
row = (row || 1) - 1
|
|
3186
|
+
col = (col || 1) - 1
|
|
3187
|
+
} else {
|
|
3188
|
+
row = row || 0
|
|
3189
|
+
col = col || 0
|
|
3190
|
+
}
|
|
3191
|
+
this.y = row
|
|
3192
|
+
this.x = col
|
|
3193
|
+
this._ncoords()
|
|
3194
|
+
// Does not exist (?):
|
|
3195
|
+
// if (this.tput) return this.put.hvp(row, col);
|
|
3196
|
+
if (this.tput) {
|
|
3197
|
+
return this.put.cup(row, col)
|
|
3198
|
+
}
|
|
3199
|
+
return this._write('\x1b[' + (row + 1) + ';' + (col + 1) + 'f')
|
|
3200
|
+
}
|
|
3201
|
+
|
|
3202
|
+
// CSI Pm h Set Mode (SM).
|
|
3203
|
+
// Ps = 2 -> Keyboard Action Mode (AM).
|
|
3204
|
+
// Ps = 4 -> Insert Mode (IRM).
|
|
3205
|
+
// Ps = 1 2 -> Send/receive (SRM).
|
|
3206
|
+
// Ps = 2 0 -> Automatic Newline (LNM).
|
|
3207
|
+
// CSI ? Pm h
|
|
3208
|
+
// DEC Private Mode Set (DECSET).
|
|
3209
|
+
// Ps = 1 -> Application Cursor Keys (DECCKM).
|
|
3210
|
+
// Ps = 2 -> Designate USASCII for character sets G0-G3
|
|
3211
|
+
// (DECANM), and set VT100 mode.
|
|
3212
|
+
// Ps = 3 -> 132 Column Mode (DECCOLM).
|
|
3213
|
+
// Ps = 4 -> Smooth (Slow) Scroll (DECSCLM).
|
|
3214
|
+
// Ps = 5 -> Reverse Video (DECSCNM).
|
|
3215
|
+
// Ps = 6 -> Origin Mode (DECOM).
|
|
3216
|
+
// Ps = 7 -> Wraparound Mode (DECAWM).
|
|
3217
|
+
// Ps = 8 -> Auto-repeat Keys (DECARM).
|
|
3218
|
+
// Ps = 9 -> Send Mouse X & Y on button press. See the sec-
|
|
3219
|
+
// tion Mouse Tracking.
|
|
3220
|
+
// Ps = 1 0 -> Show toolbar (rxvt).
|
|
3221
|
+
// Ps = 1 2 -> Start Blinking Cursor (att610).
|
|
3222
|
+
// Ps = 1 8 -> Print form feed (DECPFF).
|
|
3223
|
+
// Ps = 1 9 -> Set print extent to full screen (DECPEX).
|
|
3224
|
+
// Ps = 2 5 -> Show Cursor (DECTCEM).
|
|
3225
|
+
// Ps = 3 0 -> Show scrollbar (rxvt).
|
|
3226
|
+
// Ps = 3 5 -> Enable font-shifting functions (rxvt).
|
|
3227
|
+
// Ps = 3 8 -> Enter Tektronix Mode (DECTEK).
|
|
3228
|
+
// Ps = 4 0 -> Allow 80 -> 132 Mode.
|
|
3229
|
+
// Ps = 4 1 -> more(1) fix (see curses resource).
|
|
3230
|
+
// Ps = 4 2 -> Enable Nation Replacement Character sets (DECN-
|
|
3231
|
+
// RCM).
|
|
3232
|
+
// Ps = 4 4 -> Turn On Margin Bell.
|
|
3233
|
+
// Ps = 4 5 -> Reverse-wraparound Mode.
|
|
3234
|
+
// Ps = 4 6 -> Start Logging. This is normally disabled by a
|
|
3235
|
+
// compile-time option.
|
|
3236
|
+
// Ps = 4 7 -> Use Alternate Screen Buffer. (This may be dis-
|
|
3237
|
+
// abled by the titeInhibit resource).
|
|
3238
|
+
// Ps = 6 6 -> Application keypad (DECNKM).
|
|
3239
|
+
// Ps = 6 7 -> Backarrow key sends backspace (DECBKM).
|
|
3240
|
+
// Ps = 1 0 0 0 -> Send Mouse X & Y on button press and
|
|
3241
|
+
// release. See the section Mouse Tracking.
|
|
3242
|
+
// Ps = 1 0 0 1 -> Use Hilite Mouse Tracking.
|
|
3243
|
+
// Ps = 1 0 0 2 -> Use Cell Motion Mouse Tracking.
|
|
3244
|
+
// Ps = 1 0 0 3 -> Use All Motion Mouse Tracking.
|
|
3245
|
+
// Ps = 1 0 0 4 -> Send FocusIn/FocusOut events.
|
|
3246
|
+
// Ps = 1 0 0 5 -> Enable Extended Mouse Mode.
|
|
3247
|
+
// Ps = 1 0 1 0 -> Scroll to bottom on tty output (rxvt).
|
|
3248
|
+
// Ps = 1 0 1 1 -> Scroll to bottom on key press (rxvt).
|
|
3249
|
+
// Ps = 1 0 3 4 -> Interpret "meta" key, sets eighth bit.
|
|
3250
|
+
// (enables the eightBitInput resource).
|
|
3251
|
+
// Ps = 1 0 3 5 -> Enable special modifiers for Alt and Num-
|
|
3252
|
+
// Lock keys. (This enables the numLock resource).
|
|
3253
|
+
// Ps = 1 0 3 6 -> Send ESC when Meta modifies a key. (This
|
|
3254
|
+
// enables the metaSendsEscape resource).
|
|
3255
|
+
// Ps = 1 0 3 7 -> Send DEL from the editing-keypad Delete
|
|
3256
|
+
// key.
|
|
3257
|
+
// Ps = 1 0 3 9 -> Send ESC when Alt modifies a key. (This
|
|
3258
|
+
// enables the altSendsEscape resource).
|
|
3259
|
+
// Ps = 1 0 4 0 -> Keep selection even if not highlighted.
|
|
3260
|
+
// (This enables the keepSelection resource).
|
|
3261
|
+
// Ps = 1 0 4 1 -> Use the CLIPBOARD selection. (This enables
|
|
3262
|
+
// the selectToClipboard resource).
|
|
3263
|
+
// Ps = 1 0 4 2 -> Enable Urgency window manager hint when
|
|
3264
|
+
// Control-G is received. (This enables the bellIsUrgent
|
|
3265
|
+
// resource).
|
|
3266
|
+
// Ps = 1 0 4 3 -> Enable raising of the window when Control-G
|
|
3267
|
+
// is received. (enables the popOnBell resource).
|
|
3268
|
+
// Ps = 1 0 4 7 -> Use Alternate Screen Buffer. (This may be
|
|
3269
|
+
// disabled by the titeInhibit resource).
|
|
3270
|
+
// Ps = 1 0 4 8 -> Save cursor as in DECSC. (This may be dis-
|
|
3271
|
+
// abled by the titeInhibit resource).
|
|
3272
|
+
// Ps = 1 0 4 9 -> Save cursor as in DECSC and use Alternate
|
|
3273
|
+
// Screen Buffer, clearing it first. (This may be disabled by
|
|
3274
|
+
// the titeInhibit resource). This combines the effects of the 1
|
|
3275
|
+
// 0 4 7 and 1 0 4 8 modes. Use this with terminfo-based
|
|
3276
|
+
// applications rather than the 4 7 mode.
|
|
3277
|
+
// Ps = 1 0 5 0 -> Set terminfo/termcap function-key mode.
|
|
3278
|
+
// Ps = 1 0 5 1 -> Set Sun function-key mode.
|
|
3279
|
+
// Ps = 1 0 5 2 -> Set HP function-key mode.
|
|
3280
|
+
// Ps = 1 0 5 3 -> Set SCO function-key mode.
|
|
3281
|
+
// Ps = 1 0 6 0 -> Set legacy keyboard emulation (X11R6).
|
|
3282
|
+
// Ps = 1 0 6 1 -> Set VT220 keyboard emulation.
|
|
3283
|
+
// Ps = 2 0 0 4 -> Set bracketed paste mode.
|
|
3284
|
+
// Modes:
|
|
3285
|
+
// http://vt100.net/docs/vt220-rm/chapter4.html
|
|
3286
|
+
Program.prototype.sm = Program.prototype.setMode = function () {
|
|
3287
|
+
const param = slice.call(arguments).join(';')
|
|
3288
|
+
return this._write('\x1b[' + (param || '') + 'h')
|
|
3289
|
+
}
|
|
3290
|
+
|
|
3291
|
+
Program.prototype.decset = function () {
|
|
3292
|
+
const param = slice.call(arguments).join(';')
|
|
3293
|
+
return this.setMode('?' + param)
|
|
3294
|
+
}
|
|
3295
|
+
|
|
3296
|
+
Program.prototype.dectcem =
|
|
3297
|
+
Program.prototype.cnorm =
|
|
3298
|
+
Program.prototype.cvvis =
|
|
3299
|
+
Program.prototype.showCursor =
|
|
3300
|
+
function () {
|
|
3301
|
+
this.cursorHidden = false
|
|
3302
|
+
// NOTE: In xterm terminfo:
|
|
3303
|
+
// cnorm stops blinking cursor
|
|
3304
|
+
// cvvis starts blinking cursor
|
|
3305
|
+
if (this.tput) {
|
|
3306
|
+
return this.put.cnorm()
|
|
3307
|
+
}
|
|
3308
|
+
//if (this.tput) return this.put.cvvis();
|
|
3309
|
+
// return this._write('\x1b[?12l\x1b[?25h'); // cursor_normal
|
|
3310
|
+
// return this._write('\x1b[?12;25h'); // cursor_visible
|
|
3311
|
+
return this.setMode('?25')
|
|
3312
|
+
}
|
|
3313
|
+
|
|
3314
|
+
Program.prototype.alternate =
|
|
3315
|
+
Program.prototype.smcup =
|
|
3316
|
+
Program.prototype.alternateBuffer =
|
|
3317
|
+
function () {
|
|
3318
|
+
this.isAlt = true
|
|
3319
|
+
if (this.tput) {
|
|
3320
|
+
return this.put.smcup()
|
|
3321
|
+
}
|
|
3322
|
+
if (this.term('vt') || this.term('linux')) {
|
|
3323
|
+
return
|
|
3324
|
+
}
|
|
3325
|
+
this.setMode('?47')
|
|
3326
|
+
return this.setMode('?1049')
|
|
3327
|
+
}
|
|
3328
|
+
|
|
3329
|
+
// CSI Pm l Reset Mode (RM).
|
|
3330
|
+
// Ps = 2 -> Keyboard Action Mode (AM).
|
|
3331
|
+
// Ps = 4 -> Replace Mode (IRM).
|
|
3332
|
+
// Ps = 1 2 -> Send/receive (SRM).
|
|
3333
|
+
// Ps = 2 0 -> Normal Linefeed (LNM).
|
|
3334
|
+
// CSI ? Pm l
|
|
3335
|
+
// DEC Private Mode Reset (DECRST).
|
|
3336
|
+
// Ps = 1 -> Normal Cursor Keys (DECCKM).
|
|
3337
|
+
// Ps = 2 -> Designate VT52 mode (DECANM).
|
|
3338
|
+
// Ps = 3 -> 80 Column Mode (DECCOLM).
|
|
3339
|
+
// Ps = 4 -> Jump (Fast) Scroll (DECSCLM).
|
|
3340
|
+
// Ps = 5 -> Normal Video (DECSCNM).
|
|
3341
|
+
// Ps = 6 -> Normal Cursor Mode (DECOM).
|
|
3342
|
+
// Ps = 7 -> No Wraparound Mode (DECAWM).
|
|
3343
|
+
// Ps = 8 -> No Auto-repeat Keys (DECARM).
|
|
3344
|
+
// Ps = 9 -> Don't send Mouse X & Y on button press.
|
|
3345
|
+
// Ps = 1 0 -> Hide toolbar (rxvt).
|
|
3346
|
+
// Ps = 1 2 -> Stop Blinking Cursor (att610).
|
|
3347
|
+
// Ps = 1 8 -> Don't print form feed (DECPFF).
|
|
3348
|
+
// Ps = 1 9 -> Limit print to scrolling region (DECPEX).
|
|
3349
|
+
// Ps = 2 5 -> Hide Cursor (DECTCEM).
|
|
3350
|
+
// Ps = 3 0 -> Don't show scrollbar (rxvt).
|
|
3351
|
+
// Ps = 3 5 -> Disable font-shifting functions (rxvt).
|
|
3352
|
+
// Ps = 4 0 -> Disallow 80 -> 132 Mode.
|
|
3353
|
+
// Ps = 4 1 -> No more(1) fix (see curses resource).
|
|
3354
|
+
// Ps = 4 2 -> Disable Nation Replacement Character sets (DEC-
|
|
3355
|
+
// NRCM).
|
|
3356
|
+
// Ps = 4 4 -> Turn Off Margin Bell.
|
|
3357
|
+
// Ps = 4 5 -> No Reverse-wraparound Mode.
|
|
3358
|
+
// Ps = 4 6 -> Stop Logging. (This is normally disabled by a
|
|
3359
|
+
// compile-time option).
|
|
3360
|
+
// Ps = 4 7 -> Use Normal Screen Buffer.
|
|
3361
|
+
// Ps = 6 6 -> Numeric keypad (DECNKM).
|
|
3362
|
+
// Ps = 6 7 -> Backarrow key sends delete (DECBKM).
|
|
3363
|
+
// Ps = 1 0 0 0 -> Don't send Mouse X & Y on button press and
|
|
3364
|
+
// release. See the section Mouse Tracking.
|
|
3365
|
+
// Ps = 1 0 0 1 -> Don't use Hilite Mouse Tracking.
|
|
3366
|
+
// Ps = 1 0 0 2 -> Don't use Cell Motion Mouse Tracking.
|
|
3367
|
+
// Ps = 1 0 0 3 -> Don't use All Motion Mouse Tracking.
|
|
3368
|
+
// Ps = 1 0 0 4 -> Don't send FocusIn/FocusOut events.
|
|
3369
|
+
// Ps = 1 0 0 5 -> Disable Extended Mouse Mode.
|
|
3370
|
+
// Ps = 1 0 1 0 -> Don't scroll to bottom on tty output
|
|
3371
|
+
// (rxvt).
|
|
3372
|
+
// Ps = 1 0 1 1 -> Don't scroll to bottom on key press (rxvt).
|
|
3373
|
+
// Ps = 1 0 3 4 -> Don't interpret "meta" key. (This disables
|
|
3374
|
+
// the eightBitInput resource).
|
|
3375
|
+
// Ps = 1 0 3 5 -> Disable special modifiers for Alt and Num-
|
|
3376
|
+
// Lock keys. (This disables the numLock resource).
|
|
3377
|
+
// Ps = 1 0 3 6 -> Don't send ESC when Meta modifies a key.
|
|
3378
|
+
// (This disables the metaSendsEscape resource).
|
|
3379
|
+
// Ps = 1 0 3 7 -> Send VT220 Remove from the editing-keypad
|
|
3380
|
+
// Delete key.
|
|
3381
|
+
// Ps = 1 0 3 9 -> Don't send ESC when Alt modifies a key.
|
|
3382
|
+
// (This disables the altSendsEscape resource).
|
|
3383
|
+
// Ps = 1 0 4 0 -> Do not keep selection when not highlighted.
|
|
3384
|
+
// (This disables the keepSelection resource).
|
|
3385
|
+
// Ps = 1 0 4 1 -> Use the PRIMARY selection. (This disables
|
|
3386
|
+
// the selectToClipboard resource).
|
|
3387
|
+
// Ps = 1 0 4 2 -> Disable Urgency window manager hint when
|
|
3388
|
+
// Control-G is received. (This disables the bellIsUrgent
|
|
3389
|
+
// resource).
|
|
3390
|
+
// Ps = 1 0 4 3 -> Disable raising of the window when Control-
|
|
3391
|
+
// G is received. (This disables the popOnBell resource).
|
|
3392
|
+
// Ps = 1 0 4 7 -> Use Normal Screen Buffer, clearing screen
|
|
3393
|
+
// first if in the Alternate Screen. (This may be disabled by
|
|
3394
|
+
// the titeInhibit resource).
|
|
3395
|
+
// Ps = 1 0 4 8 -> Restore cursor as in DECRC. (This may be
|
|
3396
|
+
// disabled by the titeInhibit resource).
|
|
3397
|
+
// Ps = 1 0 4 9 -> Use Normal Screen Buffer and restore cursor
|
|
3398
|
+
// as in DECRC. (This may be disabled by the titeInhibit
|
|
3399
|
+
// resource). This combines the effects of the 1 0 4 7 and 1 0
|
|
3400
|
+
// 4 8 modes. Use this with terminfo-based applications rather
|
|
3401
|
+
// than the 4 7 mode.
|
|
3402
|
+
// Ps = 1 0 5 0 -> Reset terminfo/termcap function-key mode.
|
|
3403
|
+
// Ps = 1 0 5 1 -> Reset Sun function-key mode.
|
|
3404
|
+
// Ps = 1 0 5 2 -> Reset HP function-key mode.
|
|
3405
|
+
// Ps = 1 0 5 3 -> Reset SCO function-key mode.
|
|
3406
|
+
// Ps = 1 0 6 0 -> Reset legacy keyboard emulation (X11R6).
|
|
3407
|
+
// Ps = 1 0 6 1 -> Reset keyboard emulation to Sun/PC style.
|
|
3408
|
+
// Ps = 2 0 0 4 -> Reset bracketed paste mode.
|
|
3409
|
+
Program.prototype.rm = Program.prototype.resetMode = function () {
|
|
3410
|
+
const param = slice.call(arguments).join(';')
|
|
3411
|
+
return this._write('\x1b[' + (param || '') + 'l')
|
|
3412
|
+
}
|
|
3413
|
+
|
|
3414
|
+
Program.prototype.decrst = function () {
|
|
3415
|
+
const param = slice.call(arguments).join(';')
|
|
3416
|
+
return this.resetMode('?' + param)
|
|
3417
|
+
}
|
|
3418
|
+
|
|
3419
|
+
Program.prototype.dectcemh =
|
|
3420
|
+
Program.prototype.cursor_invisible =
|
|
3421
|
+
Program.prototype.vi =
|
|
3422
|
+
Program.prototype.civis =
|
|
3423
|
+
Program.prototype.hideCursor =
|
|
3424
|
+
function () {
|
|
3425
|
+
this.cursorHidden = true
|
|
3426
|
+
if (this.tput) {
|
|
3427
|
+
return this.put.civis()
|
|
3428
|
+
}
|
|
3429
|
+
return this.resetMode('?25')
|
|
3430
|
+
}
|
|
3431
|
+
|
|
3432
|
+
Program.prototype.rmcup = Program.prototype.normalBuffer = function () {
|
|
3433
|
+
this.isAlt = false
|
|
3434
|
+
if (this.tput) {
|
|
3435
|
+
return this.put.rmcup()
|
|
3436
|
+
}
|
|
3437
|
+
this.resetMode('?47')
|
|
3438
|
+
return this.resetMode('?1049')
|
|
3439
|
+
}
|
|
3440
|
+
|
|
3441
|
+
Program.prototype.enableMouse = function () {
|
|
3442
|
+
if (process.env.BLESSED_FORCE_MODES) {
|
|
3443
|
+
const modes = process.env.BLESSED_FORCE_MODES.split(',')
|
|
3444
|
+
const options = {}
|
|
3445
|
+
for (let n = 0; n < modes.length; ++n) {
|
|
3446
|
+
const pair = modes[n].split('=')
|
|
3447
|
+
const v = pair[1] !== '0'
|
|
3448
|
+
switch (pair[0].toUpperCase()) {
|
|
3449
|
+
case 'SGRMOUSE':
|
|
3450
|
+
options.sgrMouse = v
|
|
3451
|
+
break
|
|
3452
|
+
case 'UTFMOUSE':
|
|
3453
|
+
options.utfMouse = v
|
|
3454
|
+
break
|
|
3455
|
+
case 'VT200MOUSE':
|
|
3456
|
+
options.vt200Mouse = v
|
|
3457
|
+
break
|
|
3458
|
+
case 'URXVTMOUSE':
|
|
3459
|
+
options.urxvtMouse = v
|
|
3460
|
+
break
|
|
3461
|
+
case 'X10MOUSE':
|
|
3462
|
+
options.x10Mouse = v
|
|
3463
|
+
break
|
|
3464
|
+
case 'DECMOUSE':
|
|
3465
|
+
options.decMouse = v
|
|
3466
|
+
break
|
|
3467
|
+
case 'PTERMMOUSE':
|
|
3468
|
+
options.ptermMouse = v
|
|
3469
|
+
break
|
|
3470
|
+
case 'JSBTERMMOUSE':
|
|
3471
|
+
options.jsbtermMouse = v
|
|
3472
|
+
break
|
|
3473
|
+
case 'VT200HILITE':
|
|
3474
|
+
options.vt200Hilite = v
|
|
3475
|
+
break
|
|
3476
|
+
case 'GPMMOUSE':
|
|
3477
|
+
options.gpmMouse = v
|
|
3478
|
+
break
|
|
3479
|
+
case 'CELLMOTION':
|
|
3480
|
+
options.cellMotion = v
|
|
3481
|
+
break
|
|
3482
|
+
case 'ALLMOTION':
|
|
3483
|
+
options.allMotion = v
|
|
3484
|
+
break
|
|
3485
|
+
case 'SENDFOCUS':
|
|
3486
|
+
options.sendFocus = v
|
|
3487
|
+
break
|
|
3488
|
+
}
|
|
3489
|
+
}
|
|
3490
|
+
return this.setMouse(options, true)
|
|
3491
|
+
}
|
|
3492
|
+
|
|
3493
|
+
// NOTE:
|
|
3494
|
+
// Cell Motion isn't normally need for anything below here, but we'll
|
|
3495
|
+
// activate it for tmux (whether using it or not) in case our all-motion
|
|
3496
|
+
// passthrough does not work. It can't hurt.
|
|
3497
|
+
|
|
3498
|
+
if (this.term('rxvt-unicode')) {
|
|
3499
|
+
return this.setMouse(
|
|
3500
|
+
{
|
|
3501
|
+
urxvtMouse: true,
|
|
3502
|
+
cellMotion: true,
|
|
3503
|
+
allMotion: true
|
|
3504
|
+
},
|
|
3505
|
+
true
|
|
3506
|
+
)
|
|
3507
|
+
}
|
|
3508
|
+
|
|
3509
|
+
// rxvt does not support the X10 UTF extensions
|
|
3510
|
+
if (this.term('rxvt')) {
|
|
3511
|
+
return this.setMouse(
|
|
3512
|
+
{
|
|
3513
|
+
vt200Mouse: true,
|
|
3514
|
+
x10Mouse: true,
|
|
3515
|
+
cellMotion: true,
|
|
3516
|
+
allMotion: true
|
|
3517
|
+
},
|
|
3518
|
+
true
|
|
3519
|
+
)
|
|
3520
|
+
}
|
|
3521
|
+
|
|
3522
|
+
// libvte is broken. Older versions do not support the
|
|
3523
|
+
// X10 UTF extension. However, later versions do support
|
|
3524
|
+
// SGR/URXVT.
|
|
3525
|
+
if (this.isVTE) {
|
|
3526
|
+
return this.setMouse(
|
|
3527
|
+
{
|
|
3528
|
+
// NOTE: Could also use urxvtMouse here.
|
|
3529
|
+
sgrMouse: true,
|
|
3530
|
+
cellMotion: true,
|
|
3531
|
+
allMotion: true
|
|
3532
|
+
},
|
|
3533
|
+
true
|
|
3534
|
+
)
|
|
3535
|
+
}
|
|
3536
|
+
|
|
3537
|
+
if (this.term('linux')) {
|
|
3538
|
+
return this.setMouse(
|
|
3539
|
+
{
|
|
3540
|
+
vt200Mouse: true,
|
|
3541
|
+
gpmMouse: true
|
|
3542
|
+
},
|
|
3543
|
+
true
|
|
3544
|
+
)
|
|
3545
|
+
}
|
|
3546
|
+
|
|
3547
|
+
if (
|
|
3548
|
+
this.term('xterm') ||
|
|
3549
|
+
this.term('screen') ||
|
|
3550
|
+
(this.tput && this.tput.strings.key_mouse)
|
|
3551
|
+
) {
|
|
3552
|
+
return this.setMouse(
|
|
3553
|
+
{
|
|
3554
|
+
vt200Mouse: true,
|
|
3555
|
+
utfMouse: true,
|
|
3556
|
+
cellMotion: true,
|
|
3557
|
+
allMotion: true
|
|
3558
|
+
},
|
|
3559
|
+
true
|
|
3560
|
+
)
|
|
3561
|
+
}
|
|
3562
|
+
}
|
|
3563
|
+
|
|
3564
|
+
Program.prototype.disableMouse = function () {
|
|
3565
|
+
if (!this._currentMouse) {
|
|
3566
|
+
return
|
|
3567
|
+
}
|
|
3568
|
+
|
|
3569
|
+
const obj = {}
|
|
3570
|
+
|
|
3571
|
+
Object.keys(this._currentMouse).forEach(function (key) {
|
|
3572
|
+
obj[key] = false
|
|
3573
|
+
})
|
|
3574
|
+
|
|
3575
|
+
return this.setMouse(obj, false)
|
|
3576
|
+
}
|
|
3577
|
+
|
|
3578
|
+
// Set Mouse
|
|
3579
|
+
Program.prototype.setMouse = function (opt, enable) {
|
|
3580
|
+
if (opt.normalMouse != null) {
|
|
3581
|
+
opt.vt200Mouse = opt.normalMouse
|
|
3582
|
+
opt.allMotion = opt.normalMouse
|
|
3583
|
+
}
|
|
3584
|
+
|
|
3585
|
+
if (opt.hiliteTracking != null) {
|
|
3586
|
+
opt.vt200Hilite = opt.hiliteTracking
|
|
3587
|
+
}
|
|
3588
|
+
|
|
3589
|
+
if (enable === true) {
|
|
3590
|
+
if (this._currentMouse) {
|
|
3591
|
+
this.setMouse(opt)
|
|
3592
|
+
Object.keys(opt).forEach(function (key) {
|
|
3593
|
+
this._currentMouse[key] = opt[key]
|
|
3594
|
+
}, this)
|
|
3595
|
+
return
|
|
3596
|
+
}
|
|
3597
|
+
this._currentMouse = opt
|
|
3598
|
+
this.mouseEnabled = true
|
|
3599
|
+
} else if (enable === false) {
|
|
3600
|
+
delete this._currentMouse
|
|
3601
|
+
this.mouseEnabled = false
|
|
3602
|
+
}
|
|
3603
|
+
|
|
3604
|
+
// Ps = 9 -> Send Mouse X & Y on button press. See the sec-
|
|
3605
|
+
// tion Mouse Tracking.
|
|
3606
|
+
// Ps = 9 -> Don't send Mouse X & Y on button press.
|
|
3607
|
+
// x10 mouse
|
|
3608
|
+
if (opt.x10Mouse != null) {
|
|
3609
|
+
if (opt.x10Mouse) {
|
|
3610
|
+
this.setMode('?9')
|
|
3611
|
+
} else {
|
|
3612
|
+
this.resetMode('?9')
|
|
3613
|
+
}
|
|
3614
|
+
}
|
|
3615
|
+
|
|
3616
|
+
// Ps = 1 0 0 0 -> Send Mouse X & Y on button press and
|
|
3617
|
+
// release. See the section Mouse Tracking.
|
|
3618
|
+
// Ps = 1 0 0 0 -> Don't send Mouse X & Y on button press and
|
|
3619
|
+
// release. See the section Mouse Tracking.
|
|
3620
|
+
// vt200 mouse
|
|
3621
|
+
if (opt.vt200Mouse != null) {
|
|
3622
|
+
if (opt.vt200Mouse) {
|
|
3623
|
+
this.setMode('?1000')
|
|
3624
|
+
} else {
|
|
3625
|
+
this.resetMode('?1000')
|
|
3626
|
+
}
|
|
3627
|
+
}
|
|
3628
|
+
|
|
3629
|
+
// Ps = 1 0 0 1 -> Use Hilite Mouse Tracking.
|
|
3630
|
+
// Ps = 1 0 0 1 -> Don't use Hilite Mouse Tracking.
|
|
3631
|
+
if (opt.vt200Hilite != null) {
|
|
3632
|
+
if (opt.vt200Hilite) {
|
|
3633
|
+
this.setMode('?1001')
|
|
3634
|
+
} else {
|
|
3635
|
+
this.resetMode('?1001')
|
|
3636
|
+
}
|
|
3637
|
+
}
|
|
3638
|
+
|
|
3639
|
+
// Ps = 1 0 0 2 -> Use Cell Motion Mouse Tracking.
|
|
3640
|
+
// Ps = 1 0 0 2 -> Don't use Cell Motion Mouse Tracking.
|
|
3641
|
+
// button event mouse
|
|
3642
|
+
if (opt.cellMotion != null) {
|
|
3643
|
+
if (opt.cellMotion) {
|
|
3644
|
+
this.setMode('?1002')
|
|
3645
|
+
} else {
|
|
3646
|
+
this.resetMode('?1002')
|
|
3647
|
+
}
|
|
3648
|
+
}
|
|
3649
|
+
|
|
3650
|
+
// Ps = 1 0 0 3 -> Use All Motion Mouse Tracking.
|
|
3651
|
+
// Ps = 1 0 0 3 -> Don't use All Motion Mouse Tracking.
|
|
3652
|
+
// any event mouse
|
|
3653
|
+
if (opt.allMotion != null) {
|
|
3654
|
+
// NOTE: Latest versions of tmux seem to only support cellMotion (not
|
|
3655
|
+
// allMotion). We pass all motion through to the terminal.
|
|
3656
|
+
if (this.tmux && this.tmuxVersion >= 2) {
|
|
3657
|
+
if (opt.allMotion) {
|
|
3658
|
+
this._twrite('\x1b[?1003h')
|
|
3659
|
+
} else {
|
|
3660
|
+
this._twrite('\x1b[?1003l')
|
|
3661
|
+
}
|
|
3662
|
+
} else {
|
|
3663
|
+
if (opt.allMotion) {
|
|
3664
|
+
this.setMode('?1003')
|
|
3665
|
+
} else {
|
|
3666
|
+
this.resetMode('?1003')
|
|
3667
|
+
}
|
|
3668
|
+
}
|
|
3669
|
+
}
|
|
3670
|
+
|
|
3671
|
+
// Ps = 1 0 0 4 -> Send FocusIn/FocusOut events.
|
|
3672
|
+
// Ps = 1 0 0 4 -> Don't send FocusIn/FocusOut events.
|
|
3673
|
+
if (opt.sendFocus != null) {
|
|
3674
|
+
if (opt.sendFocus) {
|
|
3675
|
+
this.setMode('?1004')
|
|
3676
|
+
} else {
|
|
3677
|
+
this.resetMode('?1004')
|
|
3678
|
+
}
|
|
3679
|
+
}
|
|
3680
|
+
|
|
3681
|
+
// Ps = 1 0 0 5 -> Enable Extended Mouse Mode.
|
|
3682
|
+
// Ps = 1 0 0 5 -> Disable Extended Mouse Mode.
|
|
3683
|
+
if (opt.utfMouse != null) {
|
|
3684
|
+
if (opt.utfMouse) {
|
|
3685
|
+
this.setMode('?1005')
|
|
3686
|
+
} else {
|
|
3687
|
+
this.resetMode('?1005')
|
|
3688
|
+
}
|
|
3689
|
+
}
|
|
3690
|
+
|
|
3691
|
+
// sgr mouse
|
|
3692
|
+
if (opt.sgrMouse != null) {
|
|
3693
|
+
if (opt.sgrMouse) {
|
|
3694
|
+
this.setMode('?1006')
|
|
3695
|
+
} else {
|
|
3696
|
+
this.resetMode('?1006')
|
|
3697
|
+
}
|
|
3698
|
+
}
|
|
3699
|
+
|
|
3700
|
+
// urxvt mouse
|
|
3701
|
+
if (opt.urxvtMouse != null) {
|
|
3702
|
+
if (opt.urxvtMouse) {
|
|
3703
|
+
this.setMode('?1015')
|
|
3704
|
+
} else {
|
|
3705
|
+
this.resetMode('?1015')
|
|
3706
|
+
}
|
|
3707
|
+
}
|
|
3708
|
+
|
|
3709
|
+
// dec mouse
|
|
3710
|
+
if (opt.decMouse != null) {
|
|
3711
|
+
if (opt.decMouse) {
|
|
3712
|
+
this._write("\x1b[1;2'z\x1b[1;3'{")
|
|
3713
|
+
} else {
|
|
3714
|
+
this._write("\x1b['z")
|
|
3715
|
+
}
|
|
3716
|
+
}
|
|
3717
|
+
|
|
3718
|
+
// pterm mouse
|
|
3719
|
+
if (opt.ptermMouse != null) {
|
|
3720
|
+
if (opt.ptermMouse) {
|
|
3721
|
+
this._write('\x1b[>1h\x1b[>6h\x1b[>7h\x1b[>1h\x1b[>9l')
|
|
3722
|
+
} else {
|
|
3723
|
+
this._write('\x1b[>1l\x1b[>6l\x1b[>7l\x1b[>1l\x1b[>9h')
|
|
3724
|
+
}
|
|
3725
|
+
}
|
|
3726
|
+
|
|
3727
|
+
// jsbterm mouse
|
|
3728
|
+
if (opt.jsbtermMouse != null) {
|
|
3729
|
+
// + = advanced mode
|
|
3730
|
+
if (opt.jsbtermMouse) {
|
|
3731
|
+
this._write('\x1b[0~ZwLMRK+1Q\x1b\\')
|
|
3732
|
+
} else {
|
|
3733
|
+
this._write('\x1b[0~ZwQ\x1b\\')
|
|
3734
|
+
}
|
|
3735
|
+
}
|
|
3736
|
+
|
|
3737
|
+
// gpm mouse
|
|
3738
|
+
if (opt.gpmMouse != null) {
|
|
3739
|
+
if (opt.gpmMouse) {
|
|
3740
|
+
this.enableGpm()
|
|
3741
|
+
} else {
|
|
3742
|
+
this.disableGpm()
|
|
3743
|
+
}
|
|
3744
|
+
}
|
|
3745
|
+
}
|
|
3746
|
+
|
|
3747
|
+
// CSI Ps ; Ps r
|
|
3748
|
+
// Set Scrolling Region [top;bottom] (default = full size of win-
|
|
3749
|
+
// dow) (DECSTBM).
|
|
3750
|
+
// CSI ? Pm r
|
|
3751
|
+
Program.prototype.decstbm =
|
|
3752
|
+
Program.prototype.csr =
|
|
3753
|
+
Program.prototype.setScrollRegion =
|
|
3754
|
+
function (top, bottom) {
|
|
3755
|
+
if (!this.zero) {
|
|
3756
|
+
top = (top || 1) - 1
|
|
3757
|
+
bottom = (bottom || this.rows) - 1
|
|
3758
|
+
} else {
|
|
3759
|
+
top = top || 0
|
|
3760
|
+
bottom = bottom || this.rows - 1
|
|
3761
|
+
}
|
|
3762
|
+
this.scrollTop = top
|
|
3763
|
+
this.scrollBottom = bottom
|
|
3764
|
+
this.x = 0
|
|
3765
|
+
this.y = 0
|
|
3766
|
+
this._ncoords()
|
|
3767
|
+
if (this.tput) {
|
|
3768
|
+
return this.put.csr(top, bottom)
|
|
3769
|
+
}
|
|
3770
|
+
return this._write('\x1b[' + (top + 1) + ';' + (bottom + 1) + 'r')
|
|
3771
|
+
}
|
|
3772
|
+
|
|
3773
|
+
// CSI s
|
|
3774
|
+
// Save cursor (ANSI.SYS).
|
|
3775
|
+
Program.prototype.scA = Program.prototype.saveCursorA = function () {
|
|
3776
|
+
this.savedX = this.x
|
|
3777
|
+
this.savedY = this.y
|
|
3778
|
+
if (this.tput) {
|
|
3779
|
+
return this.put.sc()
|
|
3780
|
+
}
|
|
3781
|
+
return this._write('\x1b[s')
|
|
3782
|
+
}
|
|
3783
|
+
|
|
3784
|
+
// CSI u
|
|
3785
|
+
// Restore cursor (ANSI.SYS).
|
|
3786
|
+
Program.prototype.rcA = Program.prototype.restoreCursorA = function () {
|
|
3787
|
+
this.x = this.savedX || 0
|
|
3788
|
+
this.y = this.savedY || 0
|
|
3789
|
+
if (this.tput) {
|
|
3790
|
+
return this.put.rc()
|
|
3791
|
+
}
|
|
3792
|
+
return this._write('\x1b[u')
|
|
3793
|
+
}
|
|
3794
|
+
|
|
3795
|
+
/**
|
|
3796
|
+
* Lesser Used
|
|
3797
|
+
*/
|
|
3798
|
+
|
|
3799
|
+
// CSI Ps I
|
|
3800
|
+
// Cursor Forward Tabulation Ps tab stops (default = 1) (CHT).
|
|
3801
|
+
Program.prototype.cht = Program.prototype.cursorForwardTab = function (param) {
|
|
3802
|
+
this.x += 8
|
|
3803
|
+
this._ncoords()
|
|
3804
|
+
if (this.tput) {
|
|
3805
|
+
return this.put.tab(param)
|
|
3806
|
+
}
|
|
3807
|
+
return this._write('\x1b[' + (param || 1) + 'I')
|
|
3808
|
+
}
|
|
3809
|
+
|
|
3810
|
+
// CSI Ps S Scroll up Ps lines (default = 1) (SU).
|
|
3811
|
+
Program.prototype.su = Program.prototype.scrollUp = function (param) {
|
|
3812
|
+
this.y -= param || 1
|
|
3813
|
+
this._ncoords()
|
|
3814
|
+
if (this.tput) {
|
|
3815
|
+
return this.put.parm_index(param)
|
|
3816
|
+
}
|
|
3817
|
+
return this._write('\x1b[' + (param || 1) + 'S')
|
|
3818
|
+
}
|
|
3819
|
+
|
|
3820
|
+
// CSI Ps T Scroll down Ps lines (default = 1) (SD).
|
|
3821
|
+
Program.prototype.sd = Program.prototype.scrollDown = function (param) {
|
|
3822
|
+
this.y += param || 1
|
|
3823
|
+
this._ncoords()
|
|
3824
|
+
if (this.tput) {
|
|
3825
|
+
return this.put.parm_rindex(param)
|
|
3826
|
+
}
|
|
3827
|
+
return this._write('\x1b[' + (param || 1) + 'T')
|
|
3828
|
+
}
|
|
3829
|
+
|
|
3830
|
+
// CSI Ps ; Ps ; Ps ; Ps ; Ps T
|
|
3831
|
+
// Initiate highlight mouse tracking. Parameters are
|
|
3832
|
+
// [func;startx;starty;firstrow;lastrow]. See the section Mouse
|
|
3833
|
+
// Tracking.
|
|
3834
|
+
Program.prototype.initMouseTracking = function () {
|
|
3835
|
+
return this._write('\x1b[' + slice.call(arguments).join(';') + 'T')
|
|
3836
|
+
}
|
|
3837
|
+
|
|
3838
|
+
// CSI > Ps; Ps T
|
|
3839
|
+
// Reset one or more features of the title modes to the default
|
|
3840
|
+
// value. Normally, "reset" disables the feature. It is possi-
|
|
3841
|
+
// ble to disable the ability to reset features by compiling a
|
|
3842
|
+
// different default for the title modes into xterm.
|
|
3843
|
+
// Ps = 0 -> Do not set window/icon labels using hexadecimal.
|
|
3844
|
+
// Ps = 1 -> Do not query window/icon labels using hexadeci-
|
|
3845
|
+
// mal.
|
|
3846
|
+
// Ps = 2 -> Do not set window/icon labels using UTF-8.
|
|
3847
|
+
// Ps = 3 -> Do not query window/icon labels using UTF-8.
|
|
3848
|
+
// (See discussion of "Title Modes").
|
|
3849
|
+
Program.prototype.resetTitleModes = function () {
|
|
3850
|
+
return this._write('\x1b[>' + slice.call(arguments).join(';') + 'T')
|
|
3851
|
+
}
|
|
3852
|
+
|
|
3853
|
+
// CSI Ps Z Cursor Backward Tabulation Ps tab stops (default = 1) (CBT).
|
|
3854
|
+
Program.prototype.cbt = Program.prototype.cursorBackwardTab = function (param) {
|
|
3855
|
+
this.x -= 8
|
|
3856
|
+
this._ncoords()
|
|
3857
|
+
if (this.tput) {
|
|
3858
|
+
return this.put.cbt(param)
|
|
3859
|
+
}
|
|
3860
|
+
return this._write('\x1b[' + (param || 1) + 'Z')
|
|
3861
|
+
}
|
|
3862
|
+
|
|
3863
|
+
// CSI Ps b Repeat the preceding graphic character Ps times (REP).
|
|
3864
|
+
Program.prototype.rep = Program.prototype.repeatPrecedingCharacter = function (
|
|
3865
|
+
param
|
|
3866
|
+
) {
|
|
3867
|
+
this.x += param || 1
|
|
3868
|
+
this._ncoords()
|
|
3869
|
+
if (this.tput) {
|
|
3870
|
+
return this.put.rep(param)
|
|
3871
|
+
}
|
|
3872
|
+
return this._write('\x1b[' + (param || 1) + 'b')
|
|
3873
|
+
}
|
|
3874
|
+
|
|
3875
|
+
// CSI Ps g Tab Clear (TBC).
|
|
3876
|
+
// Ps = 0 -> Clear Current Column (default).
|
|
3877
|
+
// Ps = 3 -> Clear All.
|
|
3878
|
+
// Potentially:
|
|
3879
|
+
// Ps = 2 -> Clear Stops on Line.
|
|
3880
|
+
// http://vt100.net/annarbor/aaa-ug/section6.html
|
|
3881
|
+
Program.prototype.tbc = Program.prototype.tabClear = function (param) {
|
|
3882
|
+
if (this.tput) {
|
|
3883
|
+
return this.put.tbc(param)
|
|
3884
|
+
}
|
|
3885
|
+
return this._write('\x1b[' + (param || 0) + 'g')
|
|
3886
|
+
}
|
|
3887
|
+
|
|
3888
|
+
// CSI Pm i Media Copy (MC).
|
|
3889
|
+
// Ps = 0 -> Print screen (default).
|
|
3890
|
+
// Ps = 4 -> Turn off printer controller mode.
|
|
3891
|
+
// Ps = 5 -> Turn on printer controller mode.
|
|
3892
|
+
// CSI ? Pm i
|
|
3893
|
+
// Media Copy (MC, DEC-specific).
|
|
3894
|
+
// Ps = 1 -> Print line containing cursor.
|
|
3895
|
+
// Ps = 4 -> Turn off autoprint mode.
|
|
3896
|
+
// Ps = 5 -> Turn on autoprint mode.
|
|
3897
|
+
// Ps = 1 0 -> Print composed display, ignores DECPEX.
|
|
3898
|
+
// Ps = 1 1 -> Print all pages.
|
|
3899
|
+
Program.prototype.mc = Program.prototype.mediaCopy = function () {
|
|
3900
|
+
return this._write('\x1b[' + slice.call(arguments).join(';') + 'i')
|
|
3901
|
+
}
|
|
3902
|
+
|
|
3903
|
+
Program.prototype.print_screen =
|
|
3904
|
+
Program.prototype.ps =
|
|
3905
|
+
Program.prototype.mc0 =
|
|
3906
|
+
function () {
|
|
3907
|
+
if (this.tput) {
|
|
3908
|
+
return this.put.mc0()
|
|
3909
|
+
}
|
|
3910
|
+
return this.mc('0')
|
|
3911
|
+
}
|
|
3912
|
+
|
|
3913
|
+
Program.prototype.prtr_on =
|
|
3914
|
+
Program.prototype.po =
|
|
3915
|
+
Program.prototype.mc5 =
|
|
3916
|
+
function () {
|
|
3917
|
+
if (this.tput) {
|
|
3918
|
+
return this.put.mc5()
|
|
3919
|
+
}
|
|
3920
|
+
return this.mc('5')
|
|
3921
|
+
}
|
|
3922
|
+
|
|
3923
|
+
Program.prototype.prtr_off =
|
|
3924
|
+
Program.prototype.pf =
|
|
3925
|
+
Program.prototype.mc4 =
|
|
3926
|
+
function () {
|
|
3927
|
+
if (this.tput) {
|
|
3928
|
+
return this.put.mc4()
|
|
3929
|
+
}
|
|
3930
|
+
return this.mc('4')
|
|
3931
|
+
}
|
|
3932
|
+
|
|
3933
|
+
Program.prototype.prtr_non =
|
|
3934
|
+
Program.prototype.pO =
|
|
3935
|
+
Program.prototype.mc5p =
|
|
3936
|
+
function () {
|
|
3937
|
+
if (this.tput) {
|
|
3938
|
+
return this.put.mc5p()
|
|
3939
|
+
}
|
|
3940
|
+
return this.mc('?5')
|
|
3941
|
+
}
|
|
3942
|
+
|
|
3943
|
+
// CSI > Ps; Ps m
|
|
3944
|
+
// Set or reset resource-values used by xterm to decide whether
|
|
3945
|
+
// to construct escape sequences holding information about the
|
|
3946
|
+
// modifiers pressed with a given key. The first parameter iden-
|
|
3947
|
+
// tifies the resource to set/reset. The second parameter is the
|
|
3948
|
+
// value to assign to the resource. If the second parameter is
|
|
3949
|
+
// omitted, the resource is reset to its initial value.
|
|
3950
|
+
// Ps = 1 -> modifyCursorKeys.
|
|
3951
|
+
// Ps = 2 -> modifyFunctionKeys.
|
|
3952
|
+
// Ps = 4 -> modifyOtherKeys.
|
|
3953
|
+
// If no parameters are given, all resources are reset to their
|
|
3954
|
+
// initial values.
|
|
3955
|
+
Program.prototype.setResources = function () {
|
|
3956
|
+
return this._write('\x1b[>' + slice.call(arguments).join(';') + 'm')
|
|
3957
|
+
}
|
|
3958
|
+
|
|
3959
|
+
// CSI > Ps n
|
|
3960
|
+
// Disable modifiers which may be enabled via the CSI > Ps; Ps m
|
|
3961
|
+
// sequence. This corresponds to a resource value of "-1", which
|
|
3962
|
+
// cannot be set with the other sequence. The parameter identi-
|
|
3963
|
+
// fies the resource to be disabled:
|
|
3964
|
+
// Ps = 1 -> modifyCursorKeys.
|
|
3965
|
+
// Ps = 2 -> modifyFunctionKeys.
|
|
3966
|
+
// Ps = 4 -> modifyOtherKeys.
|
|
3967
|
+
// If the parameter is omitted, modifyFunctionKeys is disabled.
|
|
3968
|
+
// When modifyFunctionKeys is disabled, xterm uses the modifier
|
|
3969
|
+
// keys to make an extended sequence of functions rather than
|
|
3970
|
+
// adding a parameter to each function key to denote the modi-
|
|
3971
|
+
// fiers.
|
|
3972
|
+
Program.prototype.disableModifiers = function (param) {
|
|
3973
|
+
return this._write('\x1b[>' + (param || '') + 'n')
|
|
3974
|
+
}
|
|
3975
|
+
|
|
3976
|
+
// CSI > Ps p
|
|
3977
|
+
// Set resource value pointerMode. This is used by xterm to
|
|
3978
|
+
// decide whether to hide the pointer cursor as the user types.
|
|
3979
|
+
// Valid values for the parameter:
|
|
3980
|
+
// Ps = 0 -> never hide the pointer.
|
|
3981
|
+
// Ps = 1 -> hide if the mouse tracking mode is not enabled.
|
|
3982
|
+
// Ps = 2 -> always hide the pointer. If no parameter is
|
|
3983
|
+
// given, xterm uses the default, which is 1 .
|
|
3984
|
+
Program.prototype.setPointerMode = function (param) {
|
|
3985
|
+
return this._write('\x1b[>' + (param || '') + 'p')
|
|
3986
|
+
}
|
|
3987
|
+
|
|
3988
|
+
// CSI ! p Soft terminal reset (DECSTR).
|
|
3989
|
+
// http://vt100.net/docs/vt220-rm/table4-10.html
|
|
3990
|
+
Program.prototype.decstr =
|
|
3991
|
+
Program.prototype.rs2 =
|
|
3992
|
+
Program.prototype.softReset =
|
|
3993
|
+
function () {
|
|
3994
|
+
//if (this.tput) return this.put.init_2string();
|
|
3995
|
+
//if (this.tput) return this.put.reset_2string();
|
|
3996
|
+
if (this.tput) {
|
|
3997
|
+
return this.put.rs2()
|
|
3998
|
+
}
|
|
3999
|
+
//return this._write('\x1b[!p');
|
|
4000
|
+
//return this._write('\x1b[!p\x1b[?3;4l\x1b[4l\x1b>'); // init
|
|
4001
|
+
return this._write('\x1b[!p\x1b[?3;4l\x1b[4l\x1b>') // reset
|
|
4002
|
+
}
|
|
4003
|
+
|
|
4004
|
+
// CSI Ps$ p
|
|
4005
|
+
// Request ANSI mode (DECRQM). For VT300 and up, reply is
|
|
4006
|
+
// CSI Ps; Pm$ y
|
|
4007
|
+
// where Ps is the mode number as in RM, and Pm is the mode
|
|
4008
|
+
// value:
|
|
4009
|
+
// 0 - not recognized
|
|
4010
|
+
// 1 - set
|
|
4011
|
+
// 2 - reset
|
|
4012
|
+
// 3 - permanently set
|
|
4013
|
+
// 4 - permanently reset
|
|
4014
|
+
Program.prototype.decrqm = Program.prototype.requestAnsiMode = function (
|
|
4015
|
+
param
|
|
4016
|
+
) {
|
|
4017
|
+
return this._write('\x1b[' + (param || '') + '$p')
|
|
4018
|
+
}
|
|
4019
|
+
|
|
4020
|
+
// CSI ? Ps$ p
|
|
4021
|
+
// Request DEC private mode (DECRQM). For VT300 and up, reply is
|
|
4022
|
+
// CSI ? Ps; Pm$ p
|
|
4023
|
+
// where Ps is the mode number as in DECSET, Pm is the mode value
|
|
4024
|
+
// as in the ANSI DECRQM.
|
|
4025
|
+
Program.prototype.decrqmp = Program.prototype.requestPrivateMode = function (
|
|
4026
|
+
param
|
|
4027
|
+
) {
|
|
4028
|
+
return this._write('\x1b[?' + (param || '') + '$p')
|
|
4029
|
+
}
|
|
4030
|
+
|
|
4031
|
+
// CSI Ps ; Ps " p
|
|
4032
|
+
// Set conformance level (DECSCL). Valid values for the first
|
|
4033
|
+
// parameter:
|
|
4034
|
+
// Ps = 6 1 -> VT100.
|
|
4035
|
+
// Ps = 6 2 -> VT200.
|
|
4036
|
+
// Ps = 6 3 -> VT300.
|
|
4037
|
+
// Valid values for the second parameter:
|
|
4038
|
+
// Ps = 0 -> 8-bit controls.
|
|
4039
|
+
// Ps = 1 -> 7-bit controls (always set for VT100).
|
|
4040
|
+
// Ps = 2 -> 8-bit controls.
|
|
4041
|
+
Program.prototype.decscl = Program.prototype.setConformanceLevel = function () {
|
|
4042
|
+
return this._write('\x1b[' + slice.call(arguments).join(';') + '"p')
|
|
4043
|
+
}
|
|
4044
|
+
|
|
4045
|
+
// CSI Ps q Load LEDs (DECLL).
|
|
4046
|
+
// Ps = 0 -> Clear all LEDS (default).
|
|
4047
|
+
// Ps = 1 -> Light Num Lock.
|
|
4048
|
+
// Ps = 2 -> Light Caps Lock.
|
|
4049
|
+
// Ps = 3 -> Light Scroll Lock.
|
|
4050
|
+
// Ps = 2 1 -> Extinguish Num Lock.
|
|
4051
|
+
// Ps = 2 2 -> Extinguish Caps Lock.
|
|
4052
|
+
// Ps = 2 3 -> Extinguish Scroll Lock.
|
|
4053
|
+
Program.prototype.decll = Program.prototype.loadLEDs = function (param) {
|
|
4054
|
+
return this._write('\x1b[' + (param || '') + 'q')
|
|
4055
|
+
}
|
|
4056
|
+
|
|
4057
|
+
// CSI Ps SP q
|
|
4058
|
+
// Set cursor style (DECSCUSR, VT520).
|
|
4059
|
+
// Ps = 0 -> blinking block.
|
|
4060
|
+
// Ps = 1 -> blinking block (default).
|
|
4061
|
+
// Ps = 2 -> steady block.
|
|
4062
|
+
// Ps = 3 -> blinking underline.
|
|
4063
|
+
// Ps = 4 -> steady underline.
|
|
4064
|
+
Program.prototype.decscusr = Program.prototype.setCursorStyle = function (
|
|
4065
|
+
param
|
|
4066
|
+
) {
|
|
4067
|
+
switch (param) {
|
|
4068
|
+
case 'blinking block':
|
|
4069
|
+
param = 1
|
|
4070
|
+
break
|
|
4071
|
+
case 'block':
|
|
4072
|
+
case 'steady block':
|
|
4073
|
+
param = 2
|
|
4074
|
+
break
|
|
4075
|
+
case 'blinking underline':
|
|
4076
|
+
param = 3
|
|
4077
|
+
break
|
|
4078
|
+
case 'underline':
|
|
4079
|
+
case 'steady underline':
|
|
4080
|
+
param = 4
|
|
4081
|
+
break
|
|
4082
|
+
case 'blinking bar':
|
|
4083
|
+
param = 5
|
|
4084
|
+
break
|
|
4085
|
+
case 'bar':
|
|
4086
|
+
case 'steady bar':
|
|
4087
|
+
param = 6
|
|
4088
|
+
break
|
|
4089
|
+
}
|
|
4090
|
+
if (param === 2 && this.has('Se')) {
|
|
4091
|
+
return this.put.Se()
|
|
4092
|
+
}
|
|
4093
|
+
if (this.has('Ss')) {
|
|
4094
|
+
return this.put.Ss(param)
|
|
4095
|
+
}
|
|
4096
|
+
return this._write('\x1b[' + (param || 1) + ' q')
|
|
4097
|
+
}
|
|
4098
|
+
|
|
4099
|
+
// CSI Ps " q
|
|
4100
|
+
// Select character protection attribute (DECSCA). Valid values
|
|
4101
|
+
// for the parameter:
|
|
4102
|
+
// Ps = 0 -> DECSED and DECSEL can erase (default).
|
|
4103
|
+
// Ps = 1 -> DECSED and DECSEL cannot erase.
|
|
4104
|
+
// Ps = 2 -> DECSED and DECSEL can erase.
|
|
4105
|
+
Program.prototype.decsca = Program.prototype.setCharProtectionAttr = function (
|
|
4106
|
+
param
|
|
4107
|
+
) {
|
|
4108
|
+
return this._write('\x1b[' + (param || 0) + '"q')
|
|
4109
|
+
}
|
|
4110
|
+
|
|
4111
|
+
// CSI ? Pm r
|
|
4112
|
+
// Restore DEC Private Mode Values. The value of Ps previously
|
|
4113
|
+
// saved is restored. Ps values are the same as for DECSET.
|
|
4114
|
+
Program.prototype.restorePrivateValues = function () {
|
|
4115
|
+
return this._write('\x1b[?' + slice.call(arguments).join(';') + 'r')
|
|
4116
|
+
}
|
|
4117
|
+
|
|
4118
|
+
// CSI Pt; Pl; Pb; Pr; Ps$ r
|
|
4119
|
+
// Change Attributes in Rectangular Area (DECCARA), VT400 and up.
|
|
4120
|
+
// Pt; Pl; Pb; Pr denotes the rectangle.
|
|
4121
|
+
// Ps denotes the SGR attributes to change: 0, 1, 4, 5, 7.
|
|
4122
|
+
// NOTE: xterm doesn't enable this code by default.
|
|
4123
|
+
Program.prototype.deccara = Program.prototype.setAttrInRectangle = function () {
|
|
4124
|
+
return this._write('\x1b[' + slice.call(arguments).join(';') + '$r')
|
|
4125
|
+
}
|
|
4126
|
+
|
|
4127
|
+
// CSI ? Pm s
|
|
4128
|
+
// Save DEC Private Mode Values. Ps values are the same as for
|
|
4129
|
+
// DECSET.
|
|
4130
|
+
Program.prototype.savePrivateValues = function () {
|
|
4131
|
+
return this._write('\x1b[?' + slice.call(arguments).join(';') + 's')
|
|
4132
|
+
}
|
|
4133
|
+
|
|
4134
|
+
// CSI Ps ; Ps ; Ps t
|
|
4135
|
+
// Window manipulation (from dtterm, as well as extensions).
|
|
4136
|
+
// These controls may be disabled using the allowWindowOps
|
|
4137
|
+
// resource. Valid values for the first (and any additional
|
|
4138
|
+
// parameters) are:
|
|
4139
|
+
// Ps = 1 -> De-iconify window.
|
|
4140
|
+
// Ps = 2 -> Iconify window.
|
|
4141
|
+
// Ps = 3 ; x ; y -> Move window to [x, y].
|
|
4142
|
+
// Ps = 4 ; height ; width -> Resize the xterm window to
|
|
4143
|
+
// height and width in pixels.
|
|
4144
|
+
// Ps = 5 -> Raise the xterm window to the front of the stack-
|
|
4145
|
+
// ing order.
|
|
4146
|
+
// Ps = 6 -> Lower the xterm window to the bottom of the
|
|
4147
|
+
// stacking order.
|
|
4148
|
+
// Ps = 7 -> Refresh the xterm window.
|
|
4149
|
+
// Ps = 8 ; height ; width -> Resize the text area to
|
|
4150
|
+
// [height;width] in characters.
|
|
4151
|
+
// Ps = 9 ; 0 -> Restore maximized window.
|
|
4152
|
+
// Ps = 9 ; 1 -> Maximize window (i.e., resize to screen
|
|
4153
|
+
// size).
|
|
4154
|
+
// Ps = 1 0 ; 0 -> Undo full-screen mode.
|
|
4155
|
+
// Ps = 1 0 ; 1 -> Change to full-screen.
|
|
4156
|
+
// Ps = 1 1 -> Report xterm window state. If the xterm window
|
|
4157
|
+
// is open (non-iconified), it returns CSI 1 t . If the xterm
|
|
4158
|
+
// window is iconified, it returns CSI 2 t .
|
|
4159
|
+
// Ps = 1 3 -> Report xterm window position. Result is CSI 3
|
|
4160
|
+
// ; x ; y t
|
|
4161
|
+
// Ps = 1 4 -> Report xterm window in pixels. Result is CSI
|
|
4162
|
+
// 4 ; height ; width t
|
|
4163
|
+
// Ps = 1 8 -> Report the size of the text area in characters.
|
|
4164
|
+
// Result is CSI 8 ; height ; width t
|
|
4165
|
+
// Ps = 1 9 -> Report the size of the screen in characters.
|
|
4166
|
+
// Result is CSI 9 ; height ; width t
|
|
4167
|
+
// Ps = 2 0 -> Report xterm window's icon label. Result is
|
|
4168
|
+
// OSC L label ST
|
|
4169
|
+
// Ps = 2 1 -> Report xterm window's title. Result is OSC l
|
|
4170
|
+
// label ST
|
|
4171
|
+
// Ps = 2 2 ; 0 -> Save xterm icon and window title on
|
|
4172
|
+
// stack.
|
|
4173
|
+
// Ps = 2 2 ; 1 -> Save xterm icon title on stack.
|
|
4174
|
+
// Ps = 2 2 ; 2 -> Save xterm window title on stack.
|
|
4175
|
+
// Ps = 2 3 ; 0 -> Restore xterm icon and window title from
|
|
4176
|
+
// stack.
|
|
4177
|
+
// Ps = 2 3 ; 1 -> Restore xterm icon title from stack.
|
|
4178
|
+
// Ps = 2 3 ; 2 -> Restore xterm window title from stack.
|
|
4179
|
+
// Ps >= 2 4 -> Resize to Ps lines (DECSLPP).
|
|
4180
|
+
Program.prototype.manipulateWindow = function () {
|
|
4181
|
+
const args = slice.call(arguments)
|
|
4182
|
+
|
|
4183
|
+
const callback =
|
|
4184
|
+
typeof args[args.length - 1] === 'function' ? args.pop() : function () {}
|
|
4185
|
+
|
|
4186
|
+
return this.response(
|
|
4187
|
+
'window-manipulation',
|
|
4188
|
+
'\x1b[' + args.join(';') + 't',
|
|
4189
|
+
callback
|
|
4190
|
+
)
|
|
4191
|
+
}
|
|
4192
|
+
|
|
4193
|
+
Program.prototype.getWindowSize = function (callback) {
|
|
4194
|
+
return this.manipulateWindow(18, callback)
|
|
4195
|
+
}
|
|
4196
|
+
|
|
4197
|
+
// CSI Pt; Pl; Pb; Pr; Ps$ t
|
|
4198
|
+
// Reverse Attributes in Rectangular Area (DECRARA), VT400 and
|
|
4199
|
+
// up.
|
|
4200
|
+
// Pt; Pl; Pb; Pr denotes the rectangle.
|
|
4201
|
+
// Ps denotes the attributes to reverse, i.e., 1, 4, 5, 7.
|
|
4202
|
+
// NOTE: xterm doesn't enable this code by default.
|
|
4203
|
+
Program.prototype.decrara = Program.prototype.reverseAttrInRectangle =
|
|
4204
|
+
function () {
|
|
4205
|
+
return this._write('\x1b[' + slice.call(arguments).join(';') + '$t')
|
|
4206
|
+
}
|
|
4207
|
+
|
|
4208
|
+
// CSI > Ps; Ps t
|
|
4209
|
+
// Set one or more features of the title modes. Each parameter
|
|
4210
|
+
// enables a single feature.
|
|
4211
|
+
// Ps = 0 -> Set window/icon labels using hexadecimal.
|
|
4212
|
+
// Ps = 1 -> Query window/icon labels using hexadecimal.
|
|
4213
|
+
// Ps = 2 -> Set window/icon labels using UTF-8.
|
|
4214
|
+
// Ps = 3 -> Query window/icon labels using UTF-8. (See dis-
|
|
4215
|
+
// cussion of "Title Modes")
|
|
4216
|
+
// XXX VTE bizarelly echos this:
|
|
4217
|
+
Program.prototype.setTitleModeFeature = function () {
|
|
4218
|
+
return this._twrite('\x1b[>' + slice.call(arguments).join(';') + 't')
|
|
4219
|
+
}
|
|
4220
|
+
|
|
4221
|
+
// CSI Ps SP t
|
|
4222
|
+
// Set warning-bell volume (DECSWBV, VT520).
|
|
4223
|
+
// Ps = 0 or 1 -> off.
|
|
4224
|
+
// Ps = 2 , 3 or 4 -> low.
|
|
4225
|
+
// Ps = 5 , 6 , 7 , or 8 -> high.
|
|
4226
|
+
Program.prototype.decswbv = Program.prototype.setWarningBellVolume = function (
|
|
4227
|
+
param
|
|
4228
|
+
) {
|
|
4229
|
+
return this._write('\x1b[' + (param || '') + ' t')
|
|
4230
|
+
}
|
|
4231
|
+
|
|
4232
|
+
// CSI Ps SP u
|
|
4233
|
+
// Set margin-bell volume (DECSMBV, VT520).
|
|
4234
|
+
// Ps = 1 -> off.
|
|
4235
|
+
// Ps = 2 , 3 or 4 -> low.
|
|
4236
|
+
// Ps = 0 , 5 , 6 , 7 , or 8 -> high.
|
|
4237
|
+
Program.prototype.decsmbv = Program.prototype.setMarginBellVolume = function (
|
|
4238
|
+
param
|
|
4239
|
+
) {
|
|
4240
|
+
return this._write('\x1b[' + (param || '') + ' u')
|
|
4241
|
+
}
|
|
4242
|
+
|
|
4243
|
+
// CSI Pt; Pl; Pb; Pr; Pp; Pt; Pl; Pp$ v
|
|
4244
|
+
// Copy Rectangular Area (DECCRA, VT400 and up).
|
|
4245
|
+
// Pt; Pl; Pb; Pr denotes the rectangle.
|
|
4246
|
+
// Pp denotes the source page.
|
|
4247
|
+
// Pt; Pl denotes the target location.
|
|
4248
|
+
// Pp denotes the target page.
|
|
4249
|
+
// NOTE: xterm doesn't enable this code by default.
|
|
4250
|
+
Program.prototype.deccra = Program.prototype.copyRectangle = function () {
|
|
4251
|
+
return this._write('\x1b[' + slice.call(arguments).join(';') + '$v')
|
|
4252
|
+
}
|
|
4253
|
+
|
|
4254
|
+
// CSI Pt ; Pl ; Pb ; Pr ' w
|
|
4255
|
+
// Enable Filter Rectangle (DECEFR), VT420 and up.
|
|
4256
|
+
// Parameters are [top;left;bottom;right].
|
|
4257
|
+
// Defines the coordinates of a filter rectangle and activates
|
|
4258
|
+
// it. Anytime the locator is detected outside of the filter
|
|
4259
|
+
// rectangle, an outside rectangle event is generated and the
|
|
4260
|
+
// rectangle is disabled. Filter rectangles are always treated
|
|
4261
|
+
// as "one-shot" events. Any parameters that are omitted default
|
|
4262
|
+
// to the current locator position. If all parameters are omit-
|
|
4263
|
+
// ted, any locator motion will be reported. DECELR always can-
|
|
4264
|
+
// cels any prevous rectangle definition.
|
|
4265
|
+
Program.prototype.decefr = Program.prototype.enableFilterRectangle =
|
|
4266
|
+
function () {
|
|
4267
|
+
return this._write('\x1b[' + slice.call(arguments).join(';') + "'w")
|
|
4268
|
+
}
|
|
4269
|
+
|
|
4270
|
+
// CSI Ps x Request Terminal Parameters (DECREQTPARM).
|
|
4271
|
+
// if Ps is a "0" (default) or "1", and xterm is emulating VT100,
|
|
4272
|
+
// the control sequence elicits a response of the same form whose
|
|
4273
|
+
// parameters describe the terminal:
|
|
4274
|
+
// Ps -> the given Ps incremented by 2.
|
|
4275
|
+
// Pn = 1 <- no parity.
|
|
4276
|
+
// Pn = 1 <- eight bits.
|
|
4277
|
+
// Pn = 1 <- 2 8 transmit 38.4k baud.
|
|
4278
|
+
// Pn = 1 <- 2 8 receive 38.4k baud.
|
|
4279
|
+
// Pn = 1 <- clock multiplier.
|
|
4280
|
+
// Pn = 0 <- STP flags.
|
|
4281
|
+
Program.prototype.decreqtparm = Program.prototype.requestParameters = function (
|
|
4282
|
+
param
|
|
4283
|
+
) {
|
|
4284
|
+
return this._write('\x1b[' + (param || 0) + 'x')
|
|
4285
|
+
}
|
|
4286
|
+
|
|
4287
|
+
// CSI Ps x Select Attribute Change Extent (DECSACE).
|
|
4288
|
+
// Ps = 0 -> from start to end position, wrapped.
|
|
4289
|
+
// Ps = 1 -> from start to end position, wrapped.
|
|
4290
|
+
// Ps = 2 -> rectangle (exact).
|
|
4291
|
+
Program.prototype.decsace = Program.prototype.selectChangeExtent = function (
|
|
4292
|
+
param
|
|
4293
|
+
) {
|
|
4294
|
+
return this._write('\x1b[' + (param || 0) + 'x')
|
|
4295
|
+
}
|
|
4296
|
+
|
|
4297
|
+
// CSI Pc; Pt; Pl; Pb; Pr$ x
|
|
4298
|
+
// Fill Rectangular Area (DECFRA), VT420 and up.
|
|
4299
|
+
// Pc is the character to use.
|
|
4300
|
+
// Pt; Pl; Pb; Pr denotes the rectangle.
|
|
4301
|
+
// NOTE: xterm doesn't enable this code by default.
|
|
4302
|
+
Program.prototype.decfra = Program.prototype.fillRectangle = function () {
|
|
4303
|
+
return this._write('\x1b[' + slice.call(arguments).join(';') + '$x')
|
|
4304
|
+
}
|
|
4305
|
+
|
|
4306
|
+
// CSI Ps ; Pu ' z
|
|
4307
|
+
// Enable Locator Reporting (DECELR).
|
|
4308
|
+
// Valid values for the first parameter:
|
|
4309
|
+
// Ps = 0 -> Locator disabled (default).
|
|
4310
|
+
// Ps = 1 -> Locator enabled.
|
|
4311
|
+
// Ps = 2 -> Locator enabled for one report, then disabled.
|
|
4312
|
+
// The second parameter specifies the coordinate unit for locator
|
|
4313
|
+
// reports.
|
|
4314
|
+
// Valid values for the second parameter:
|
|
4315
|
+
// Pu = 0 <- or omitted -> default to character cells.
|
|
4316
|
+
// Pu = 1 <- device physical pixels.
|
|
4317
|
+
// Pu = 2 <- character cells.
|
|
4318
|
+
Program.prototype.decelr = Program.prototype.enableLocatorReporting =
|
|
4319
|
+
function () {
|
|
4320
|
+
return this._write('\x1b[' + slice.call(arguments).join(';') + "'z")
|
|
4321
|
+
}
|
|
4322
|
+
|
|
4323
|
+
// CSI Pt; Pl; Pb; Pr$ z
|
|
4324
|
+
// Erase Rectangular Area (DECERA), VT400 and up.
|
|
4325
|
+
// Pt; Pl; Pb; Pr denotes the rectangle.
|
|
4326
|
+
// NOTE: xterm doesn't enable this code by default.
|
|
4327
|
+
Program.prototype.decera = Program.prototype.eraseRectangle = function () {
|
|
4328
|
+
return this._write('\x1b[' + slice.call(arguments).join(';') + '$z')
|
|
4329
|
+
}
|
|
4330
|
+
|
|
4331
|
+
// CSI Pm ' {
|
|
4332
|
+
// Select Locator Events (DECSLE).
|
|
4333
|
+
// Valid values for the first (and any additional parameters)
|
|
4334
|
+
// are:
|
|
4335
|
+
// Ps = 0 -> only respond to explicit host requests (DECRQLP).
|
|
4336
|
+
// (This is default). It also cancels any filter
|
|
4337
|
+
// rectangle.
|
|
4338
|
+
// Ps = 1 -> report button down transitions.
|
|
4339
|
+
// Ps = 2 -> do not report button down transitions.
|
|
4340
|
+
// Ps = 3 -> report button up transitions.
|
|
4341
|
+
// Ps = 4 -> do not report button up transitions.
|
|
4342
|
+
Program.prototype.decsle = Program.prototype.setLocatorEvents = function () {
|
|
4343
|
+
return this._write('\x1b[' + slice.call(arguments).join(';') + "'{")
|
|
4344
|
+
}
|
|
4345
|
+
|
|
4346
|
+
// CSI Pt; Pl; Pb; Pr$ {
|
|
4347
|
+
// Selective Erase Rectangular Area (DECSERA), VT400 and up.
|
|
4348
|
+
// Pt; Pl; Pb; Pr denotes the rectangle.
|
|
4349
|
+
Program.prototype.decsera = Program.prototype.selectiveEraseRectangle =
|
|
4350
|
+
function () {
|
|
4351
|
+
return this._write('\x1b[' + slice.call(arguments).join(';') + '${')
|
|
4352
|
+
}
|
|
4353
|
+
|
|
4354
|
+
// CSI Ps ' |
|
|
4355
|
+
// Request Locator Position (DECRQLP).
|
|
4356
|
+
// Valid values for the parameter are:
|
|
4357
|
+
// Ps = 0 , 1 or omitted -> transmit a single DECLRP locator
|
|
4358
|
+
// report.
|
|
4359
|
+
|
|
4360
|
+
// If Locator Reporting has been enabled by a DECELR, xterm will
|
|
4361
|
+
// respond with a DECLRP Locator Report. This report is also
|
|
4362
|
+
// generated on button up and down events if they have been
|
|
4363
|
+
// enabled with a DECSLE, or when the locator is detected outside
|
|
4364
|
+
// of a filter rectangle, if filter rectangles have been enabled
|
|
4365
|
+
// with a DECEFR.
|
|
4366
|
+
|
|
4367
|
+
// -> CSI Pe ; Pb ; Pr ; Pc ; Pp & w
|
|
4368
|
+
|
|
4369
|
+
// Parameters are [event;button;row;column;page].
|
|
4370
|
+
// Valid values for the event:
|
|
4371
|
+
// Pe = 0 -> locator unavailable - no other parameters sent.
|
|
4372
|
+
// Pe = 1 -> request - xterm received a DECRQLP.
|
|
4373
|
+
// Pe = 2 -> left button down.
|
|
4374
|
+
// Pe = 3 -> left button up.
|
|
4375
|
+
// Pe = 4 -> middle button down.
|
|
4376
|
+
// Pe = 5 -> middle button up.
|
|
4377
|
+
// Pe = 6 -> right button down.
|
|
4378
|
+
// Pe = 7 -> right button up.
|
|
4379
|
+
// Pe = 8 -> M4 button down.
|
|
4380
|
+
// Pe = 9 -> M4 button up.
|
|
4381
|
+
// Pe = 1 0 -> locator outside filter rectangle.
|
|
4382
|
+
// ``button'' parameter is a bitmask indicating which buttons are
|
|
4383
|
+
// pressed:
|
|
4384
|
+
// Pb = 0 <- no buttons down.
|
|
4385
|
+
// Pb & 1 <- right button down.
|
|
4386
|
+
// Pb & 2 <- middle button down.
|
|
4387
|
+
// Pb & 4 <- left button down.
|
|
4388
|
+
// Pb & 8 <- M4 button down.
|
|
4389
|
+
// ``row'' and ``column'' parameters are the coordinates of the
|
|
4390
|
+
// locator position in the xterm window, encoded as ASCII deci-
|
|
4391
|
+
// mal.
|
|
4392
|
+
// The ``page'' parameter is not used by xterm, and will be omit-
|
|
4393
|
+
// ted.
|
|
4394
|
+
Program.prototype.decrqlp =
|
|
4395
|
+
Program.prototype.req_mouse_pos =
|
|
4396
|
+
Program.prototype.reqmp =
|
|
4397
|
+
Program.prototype.requestLocatorPosition =
|
|
4398
|
+
function (param, callback) {
|
|
4399
|
+
// See also:
|
|
4400
|
+
// get_mouse / getm / Gm
|
|
4401
|
+
// mouse_info / minfo / Mi
|
|
4402
|
+
// Correct for tput?
|
|
4403
|
+
if (this.has('req_mouse_pos')) {
|
|
4404
|
+
const code = this.tput.req_mouse_pos(param)
|
|
4405
|
+
return this.response('locator-position', code, callback)
|
|
4406
|
+
}
|
|
4407
|
+
return this.response(
|
|
4408
|
+
'locator-position',
|
|
4409
|
+
'\x1b[' + (param || '') + "'|",
|
|
4410
|
+
callback
|
|
4411
|
+
)
|
|
4412
|
+
}
|
|
4413
|
+
|
|
4414
|
+
// CSI P m SP }
|
|
4415
|
+
// Insert P s Column(s) (default = 1) (DECIC), VT420 and up.
|
|
4416
|
+
// NOTE: xterm doesn't enable this code by default.
|
|
4417
|
+
Program.prototype.decic = Program.prototype.insertColumns = function () {
|
|
4418
|
+
return this._write('\x1b[' + slice.call(arguments).join(';') + ' }')
|
|
4419
|
+
}
|
|
4420
|
+
|
|
4421
|
+
// CSI P m SP ~
|
|
4422
|
+
// Delete P s Column(s) (default = 1) (DECDC), VT420 and up
|
|
4423
|
+
// NOTE: xterm doesn't enable this code by default.
|
|
4424
|
+
Program.prototype.decdc = Program.prototype.deleteColumns = function () {
|
|
4425
|
+
return this._write('\x1b[' + slice.call(arguments).join(';') + ' ~')
|
|
4426
|
+
}
|
|
4427
|
+
|
|
4428
|
+
Program.prototype.out = function (name) {
|
|
4429
|
+
const args = Array.prototype.slice.call(arguments, 1)
|
|
4430
|
+
this.ret = true
|
|
4431
|
+
const out = this[name].apply(this, args)
|
|
4432
|
+
this.ret = false
|
|
4433
|
+
return out
|
|
4434
|
+
}
|
|
4435
|
+
|
|
4436
|
+
Program.prototype.sigtstp = function (callback) {
|
|
4437
|
+
const resume = this.pause()
|
|
4438
|
+
|
|
4439
|
+
process.once('SIGCONT', function () {
|
|
4440
|
+
resume()
|
|
4441
|
+
if (callback) {
|
|
4442
|
+
callback()
|
|
4443
|
+
}
|
|
4444
|
+
})
|
|
4445
|
+
|
|
4446
|
+
process.kill(process.pid, 'SIGTSTP')
|
|
4447
|
+
}
|
|
4448
|
+
|
|
4449
|
+
Program.prototype.pause = function (callback) {
|
|
4450
|
+
const self = this,
|
|
4451
|
+
isAlt = this.isAlt,
|
|
4452
|
+
mouseEnabled = this.mouseEnabled
|
|
4453
|
+
|
|
4454
|
+
this.lsaveCursor('pause')
|
|
4455
|
+
//this.csr(0, screen.height - 1);
|
|
4456
|
+
if (isAlt) {
|
|
4457
|
+
this.normalBuffer()
|
|
4458
|
+
}
|
|
4459
|
+
this.showCursor()
|
|
4460
|
+
if (mouseEnabled) {
|
|
4461
|
+
this.disableMouse()
|
|
4462
|
+
}
|
|
4463
|
+
|
|
4464
|
+
const write = this.output.write
|
|
4465
|
+
this.output.write = function () {}
|
|
4466
|
+
if (this.input.setRawMode) {
|
|
4467
|
+
this.input.setRawMode(false)
|
|
4468
|
+
}
|
|
4469
|
+
this.input.pause()
|
|
4470
|
+
|
|
4471
|
+
return (this._resume = function () {
|
|
4472
|
+
delete self._resume
|
|
4473
|
+
|
|
4474
|
+
if (self.input.setRawMode) {
|
|
4475
|
+
self.input.setRawMode(true)
|
|
4476
|
+
}
|
|
4477
|
+
self.input.resume()
|
|
4478
|
+
self.output.write = write
|
|
4479
|
+
|
|
4480
|
+
if (isAlt) {
|
|
4481
|
+
self.alternateBuffer()
|
|
4482
|
+
}
|
|
4483
|
+
//self.csr(0, screen.height - 1);
|
|
4484
|
+
if (mouseEnabled) {
|
|
4485
|
+
self.enableMouse()
|
|
4486
|
+
}
|
|
4487
|
+
self.lrestoreCursor('pause', true)
|
|
4488
|
+
|
|
4489
|
+
if (callback) {
|
|
4490
|
+
callback()
|
|
4491
|
+
}
|
|
4492
|
+
})
|
|
4493
|
+
}
|
|
4494
|
+
|
|
4495
|
+
Program.prototype.resume = function () {
|
|
4496
|
+
if (this._resume) {
|
|
4497
|
+
return this._resume()
|
|
4498
|
+
}
|
|
4499
|
+
}
|
|
4500
|
+
|
|
4501
|
+
/**
|
|
4502
|
+
* Helpers
|
|
4503
|
+
*/
|
|
4504
|
+
|
|
4505
|
+
// We could do this easier by just manipulating the _events object, or for
|
|
4506
|
+
// older versions of node, manipulating the array returned by listeners(), but
|
|
4507
|
+
// neither of these methods are guaranteed to work in future versions of node.
|
|
4508
|
+
function unshiftEvent(obj, event, listener) {
|
|
4509
|
+
const listeners = obj.listeners(event)
|
|
4510
|
+
obj.removeAllListeners(event)
|
|
4511
|
+
obj.on(event, listener)
|
|
4512
|
+
listeners.forEach(function (listener) {
|
|
4513
|
+
obj.on(event, listener)
|
|
4514
|
+
})
|
|
4515
|
+
}
|
|
4516
|
+
|
|
4517
|
+
function merge(out) {
|
|
4518
|
+
slice.call(arguments, 1).forEach(function (obj) {
|
|
4519
|
+
Object.keys(obj).forEach(function (key) {
|
|
4520
|
+
out[key] = obj[key]
|
|
4521
|
+
})
|
|
4522
|
+
})
|
|
4523
|
+
return out
|
|
4524
|
+
}
|
|
4525
|
+
|
|
4526
|
+
/**
|
|
4527
|
+
* Expose
|
|
4528
|
+
*/
|
|
4529
|
+
|
|
4530
|
+
module.exports = Program
|