@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.
Files changed (109) hide show
  1. package/dist/blessed/LICENSE +20 -0
  2. package/dist/blessed/lib/alias.js +519 -0
  3. package/dist/blessed/lib/blessed.js +32 -0
  4. package/dist/blessed/lib/colors.js +490 -0
  5. package/dist/blessed/lib/events.js +195 -0
  6. package/dist/blessed/lib/gpmclient.js +245 -0
  7. package/dist/blessed/lib/helpers.js +170 -0
  8. package/dist/blessed/lib/keys.js +512 -0
  9. package/dist/blessed/lib/program.js +4530 -0
  10. package/dist/blessed/lib/tput.js +3111 -0
  11. package/dist/blessed/lib/unicode.js +912 -0
  12. package/dist/blessed/lib/widget.js +60 -0
  13. package/dist/blessed/lib/widgets/ansiimage.js +173 -0
  14. package/dist/blessed/lib/widgets/bigtext.js +170 -0
  15. package/dist/blessed/lib/widgets/box.js +34 -0
  16. package/dist/blessed/lib/widgets/button.js +62 -0
  17. package/dist/blessed/lib/widgets/checkbox.js +95 -0
  18. package/dist/blessed/lib/widgets/element.js +2871 -0
  19. package/dist/blessed/lib/widgets/filemanager.js +223 -0
  20. package/dist/blessed/lib/widgets/form.js +301 -0
  21. package/dist/blessed/lib/widgets/image.js +71 -0
  22. package/dist/blessed/lib/widgets/input.js +34 -0
  23. package/dist/blessed/lib/widgets/layout.js +249 -0
  24. package/dist/blessed/lib/widgets/line.js +59 -0
  25. package/dist/blessed/lib/widgets/list.js +652 -0
  26. package/dist/blessed/lib/widgets/listbar.js +452 -0
  27. package/dist/blessed/lib/widgets/listtable.js +265 -0
  28. package/dist/blessed/lib/widgets/loading.js +88 -0
  29. package/dist/blessed/lib/widgets/log.js +82 -0
  30. package/dist/blessed/lib/widgets/message.js +145 -0
  31. package/dist/blessed/lib/widgets/node.js +314 -0
  32. package/dist/blessed/lib/widgets/overlayimage.js +794 -0
  33. package/dist/blessed/lib/widgets/progressbar.js +166 -0
  34. package/dist/blessed/lib/widgets/prompt.js +127 -0
  35. package/dist/blessed/lib/widgets/question.js +129 -0
  36. package/dist/blessed/lib/widgets/radiobutton.js +62 -0
  37. package/dist/blessed/lib/widgets/radioset.js +36 -0
  38. package/dist/blessed/lib/widgets/screen.js +2485 -0
  39. package/dist/blessed/lib/widgets/scrollablebox.js +415 -0
  40. package/dist/blessed/lib/widgets/scrollabletext.js +35 -0
  41. package/dist/blessed/lib/widgets/table.js +383 -0
  42. package/dist/blessed/lib/widgets/terminal.js +452 -0
  43. package/dist/blessed/lib/widgets/text.js +35 -0
  44. package/dist/blessed/lib/widgets/textarea.js +376 -0
  45. package/dist/blessed/lib/widgets/textbox.js +79 -0
  46. package/dist/blessed/lib/widgets/video.js +130 -0
  47. package/dist/blessed/usr/fonts/AUTHORS +1 -0
  48. package/dist/blessed/usr/fonts/LICENSE +94 -0
  49. package/dist/blessed/usr/fonts/README +340 -0
  50. package/dist/blessed/usr/fonts/ter-u14b.json +17826 -0
  51. package/dist/blessed/usr/fonts/ter-u14n.json +17826 -0
  52. package/dist/blessed/usr/linux +0 -0
  53. package/dist/blessed/usr/windows-ansi +0 -0
  54. package/dist/blessed/usr/xterm +0 -0
  55. package/dist/blessed/usr/xterm-256color +0 -0
  56. package/dist/blessed/usr/xterm.termcap +243 -0
  57. package/dist/blessed/usr/xterm.terminfo +1977 -0
  58. package/dist/blessed/vendor/tng.js +1876 -0
  59. package/dist/blessed-contrib/LICENSE.md +21 -0
  60. package/dist/blessed-contrib/lib/layout/carousel.js +82 -0
  61. package/dist/blessed-contrib/lib/layout/grid.js +46 -0
  62. package/dist/blessed-contrib/lib/server-utils.js +83 -0
  63. package/dist/blessed-contrib/lib/utils.js +73 -0
  64. package/dist/blessed-contrib/lib/widget/canvas.js +52 -0
  65. package/dist/blessed-contrib/lib/widget/charts/bar.js +99 -0
  66. package/dist/blessed-contrib/lib/widget/charts/line.js +311 -0
  67. package/dist/blessed-contrib/lib/widget/charts/stacked-bar.js +245 -0
  68. package/dist/blessed-contrib/lib/widget/donut.js +183 -0
  69. package/dist/blessed-contrib/lib/widget/gauge-list.js +111 -0
  70. package/dist/blessed-contrib/lib/widget/gauge.js +127 -0
  71. package/dist/blessed-contrib/lib/widget/lcd.js +497 -0
  72. package/dist/blessed-contrib/lib/widget/log.js +32 -0
  73. package/dist/blessed-contrib/lib/widget/map.js +97 -0
  74. package/dist/blessed-contrib/lib/widget/markdown.js +68 -0
  75. package/dist/blessed-contrib/lib/widget/picture.js +61 -0
  76. package/dist/blessed-contrib/lib/widget/sparkline.js +66 -0
  77. package/dist/blessed-contrib/lib/widget/table.js +141 -0
  78. package/dist/blessed-contrib/lib/widget/tree.js +179 -0
  79. package/dist/blessed-contrib/node_modules/ansi-regex/index.js +6 -0
  80. package/dist/blessed-contrib/node_modules/ansi-regex/license +21 -0
  81. package/dist/blessed-contrib/node_modules/ansi-regex/package.json +64 -0
  82. package/dist/blessed-contrib/node_modules/ansi-regex/readme.md +39 -0
  83. package/dist/blessed-contrib/node_modules/ansi-styles/index.js +67 -0
  84. package/dist/blessed-contrib/node_modules/ansi-styles/license +21 -0
  85. package/dist/blessed-contrib/node_modules/ansi-styles/package.json +50 -0
  86. package/dist/blessed-contrib/node_modules/ansi-styles/readme.md +86 -0
  87. package/dist/blessed-contrib/node_modules/chalk/index.js +118 -0
  88. package/dist/blessed-contrib/node_modules/chalk/license +21 -0
  89. package/dist/blessed-contrib/node_modules/chalk/package.json +70 -0
  90. package/dist/blessed-contrib/node_modules/chalk/readme.md +213 -0
  91. package/dist/blessed-contrib/node_modules/escape-string-regexp/index.js +13 -0
  92. package/dist/blessed-contrib/node_modules/escape-string-regexp/license +21 -0
  93. package/dist/blessed-contrib/node_modules/escape-string-regexp/package.json +41 -0
  94. package/dist/blessed-contrib/node_modules/escape-string-regexp/readme.md +27 -0
  95. package/dist/blessed-contrib/node_modules/strip-ansi/index.js +8 -0
  96. package/dist/blessed-contrib/node_modules/strip-ansi/license +21 -0
  97. package/dist/blessed-contrib/node_modules/strip-ansi/package.json +57 -0
  98. package/dist/blessed-contrib/node_modules/strip-ansi/readme.md +33 -0
  99. package/dist/blessed-contrib/node_modules/supports-color/index.js +52 -0
  100. package/dist/blessed-contrib/node_modules/supports-color/license +21 -0
  101. package/dist/blessed-contrib/node_modules/supports-color/package.json +49 -0
  102. package/dist/blessed-contrib/node_modules/supports-color/readme.md +36 -0
  103. package/dist/cli.js +9 -8
  104. package/dist/cli.js.map +1 -1
  105. package/dist/instrument-with-sentry.js +2 -2
  106. package/dist/instrument-with-sentry.js.map +1 -1
  107. package/dist/shadow-npm-inject.js +2 -2
  108. package/dist/shadow-npm-inject.js.map +1 -1
  109. 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