@socketsecurity/cli-with-sentry 0.14.93 → 0.14.95

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 (84) hide show
  1. package/dist/constants.js +3 -3
  2. package/dist/constants.js.map +1 -1
  3. package/dist/instrument-with-sentry.js +2 -2
  4. package/dist/instrument-with-sentry.js.map +1 -1
  5. package/dist/module-sync/cli.js +177 -157
  6. package/dist/module-sync/cli.js.map +1 -1
  7. package/dist/module-sync/shadow-bin.js +3 -14
  8. package/dist/module-sync/shadow-bin.js.map +1 -1
  9. package/dist/module-sync/shadow-npm-inject.js +68 -59
  10. package/dist/module-sync/shadow-npm-inject.js.map +1 -1
  11. package/dist/module-sync/shadow-npm-paths.js +16 -29
  12. package/dist/module-sync/shadow-npm-paths.js.map +1 -1
  13. package/dist/module-sync/vendor.d.ts +0 -0
  14. package/dist/module-sync/vendor.js +85829 -12598
  15. package/dist/module-sync/vendor.js.map +1 -1
  16. package/dist/require/cli.js +159 -138
  17. package/dist/require/cli.js.map +1 -1
  18. package/dist/require/shadow-bin.d.ts +5 -0
  19. package/dist/require/shadow-bin.js +108 -1
  20. package/dist/require/shadow-bin.js.map +1 -0
  21. package/dist/require/shadow-npm-inject.d.ts +1 -0
  22. package/dist/require/shadow-npm-inject.js +2335 -1
  23. package/dist/require/shadow-npm-inject.js.map +1 -0
  24. package/dist/require/shadow-npm-paths.d.ts +29 -0
  25. package/dist/require/shadow-npm-paths.js +454 -1
  26. package/dist/require/shadow-npm-paths.js.map +1 -0
  27. package/package.json +29 -29
  28. package/dist/blessed/lib/alias.js +0 -521
  29. package/dist/blessed/lib/blessed.js +0 -34
  30. package/dist/blessed/lib/colors.js +0 -492
  31. package/dist/blessed/lib/events.js +0 -197
  32. package/dist/blessed/lib/gpmclient.js +0 -247
  33. package/dist/blessed/lib/helpers.js +0 -172
  34. package/dist/blessed/lib/keys.js +0 -514
  35. package/dist/blessed/lib/program.js +0 -4532
  36. package/dist/blessed/lib/tput.js +0 -3113
  37. package/dist/blessed/lib/unicode.js +0 -914
  38. package/dist/blessed/lib/widget.js +0 -62
  39. package/dist/blessed/lib/widgets/ansiimage.js +0 -175
  40. package/dist/blessed/lib/widgets/bigtext.js +0 -172
  41. package/dist/blessed/lib/widgets/box.js +0 -36
  42. package/dist/blessed/lib/widgets/button.js +0 -64
  43. package/dist/blessed/lib/widgets/checkbox.js +0 -97
  44. package/dist/blessed/lib/widgets/element.js +0 -2873
  45. package/dist/blessed/lib/widgets/filemanager.js +0 -225
  46. package/dist/blessed/lib/widgets/form.js +0 -303
  47. package/dist/blessed/lib/widgets/image.js +0 -73
  48. package/dist/blessed/lib/widgets/input.js +0 -36
  49. package/dist/blessed/lib/widgets/layout.js +0 -251
  50. package/dist/blessed/lib/widgets/line.js +0 -61
  51. package/dist/blessed/lib/widgets/list.js +0 -654
  52. package/dist/blessed/lib/widgets/listbar.js +0 -454
  53. package/dist/blessed/lib/widgets/listtable.js +0 -267
  54. package/dist/blessed/lib/widgets/loading.js +0 -90
  55. package/dist/blessed/lib/widgets/log.js +0 -84
  56. package/dist/blessed/lib/widgets/message.js +0 -147
  57. package/dist/blessed/lib/widgets/node.js +0 -315
  58. package/dist/blessed/lib/widgets/overlayimage.js +0 -796
  59. package/dist/blessed/lib/widgets/progressbar.js +0 -168
  60. package/dist/blessed/lib/widgets/prompt.js +0 -129
  61. package/dist/blessed/lib/widgets/question.js +0 -131
  62. package/dist/blessed/lib/widgets/radiobutton.js +0 -64
  63. package/dist/blessed/lib/widgets/radioset.js +0 -38
  64. package/dist/blessed/lib/widgets/screen.js +0 -2487
  65. package/dist/blessed/lib/widgets/scrollablebox.js +0 -417
  66. package/dist/blessed/lib/widgets/scrollabletext.js +0 -37
  67. package/dist/blessed/lib/widgets/table.js +0 -385
  68. package/dist/blessed/lib/widgets/terminal.js +0 -454
  69. package/dist/blessed/lib/widgets/text.js +0 -37
  70. package/dist/blessed/lib/widgets/textarea.js +0 -378
  71. package/dist/blessed/lib/widgets/textbox.js +0 -81
  72. package/dist/blessed/lib/widgets/video.js +0 -132
  73. package/dist/blessed/usr/fonts/AUTHORS +0 -1
  74. package/dist/blessed/usr/fonts/LICENSE +0 -94
  75. package/dist/blessed/usr/fonts/README +0 -340
  76. package/dist/blessed/usr/fonts/ter-u14b.json +0 -17826
  77. package/dist/blessed/usr/fonts/ter-u14n.json +0 -17826
  78. package/dist/blessed/usr/linux +0 -0
  79. package/dist/blessed/usr/windows-ansi +0 -0
  80. package/dist/blessed/usr/xterm +0 -0
  81. package/dist/blessed/usr/xterm-256color +0 -0
  82. package/dist/blessed/usr/xterm.termcap +0 -243
  83. package/dist/blessed/usr/xterm.terminfo +0 -1977
  84. package/dist/blessed/vendor/tng.js +0 -1878
@@ -1,2487 +0,0 @@
1
- 'use strict'
2
-
3
- /**
4
- * screen.js - screen node for blessed
5
- * Copyright (c) 2013-2015, Christopher Jeffrey and contributors (MIT License).
6
- * https://github.com/chjj/blessed
7
- */
8
-
9
- /**
10
- * Modules
11
- */
12
-
13
- const path = require('node:path'),
14
- fs = require('node:fs'),
15
- cp = require('node:child_process')
16
-
17
- const colors = require('../colors'),
18
- program = require('../program'),
19
- unicode = require('../unicode')
20
-
21
- const nextTick = global.setImmediate || process.nextTick.bind(process)
22
-
23
- const Node = require('./node')
24
-
25
- /**
26
- * Screen
27
- */
28
-
29
- function Screen(options) {
30
- const self = this
31
- if (!(this instanceof Node)) {
32
- return new Screen(options)
33
- }
34
-
35
- Screen.bind(this)
36
-
37
- options = options || {}
38
- if (options.rsety && options.listen) {
39
- options = { program: options }
40
- }
41
-
42
- this.program = options.program
43
-
44
- if (!this.program) {
45
- this.program = program({
46
- input: options.input,
47
- output: options.output,
48
- log: options.log,
49
- debug: options.debug,
50
- dump: options.dump,
51
- terminal: options.terminal || options.term,
52
- resizeTimeout: options.resizeTimeout,
53
- forceUnicode: options.forceUnicode,
54
- tput: true,
55
- buffer: true,
56
- zero: true
57
- })
58
- } else {
59
- this.program.setupTput()
60
- this.program.useBuffer = true
61
- this.program.zero = true
62
- this.program.options.resizeTimeout = options.resizeTimeout
63
- if (options.forceUnicode != null) {
64
- this.program.tput.features.unicode = options.forceUnicode
65
- this.program.tput.unicode = options.forceUnicode
66
- }
67
- }
68
-
69
- this.tput = this.program.tput
70
-
71
- Node.call(this, options)
72
-
73
- this.autoPadding = options.autoPadding !== false
74
- this.tabc = Array((options.tabSize || 4) + 1).join(' ')
75
- this.dockBorders = options.dockBorders
76
-
77
- this.ignoreLocked = options.ignoreLocked || []
78
-
79
- this._unicode = this.tput.unicode || this.tput.numbers.U8 === 1
80
- this.fullUnicode = this.options.fullUnicode && this._unicode
81
-
82
- this.dattr = (0 << 18) | (0x1ff << 9) | 0x1ff
83
-
84
- this.renders = 0
85
- this.position = {
86
- left: (this.left = this.aleft = this.rleft = 0),
87
- right: (this.right = this.aright = this.rright = 0),
88
- top: (this.top = this.atop = this.rtop = 0),
89
- bottom: (this.bottom = this.abottom = this.rbottom = 0),
90
- get height() {
91
- return self.height
92
- },
93
- get width() {
94
- return self.width
95
- }
96
- }
97
-
98
- this.ileft = 0
99
- this.itop = 0
100
- this.iright = 0
101
- this.ibottom = 0
102
- this.iheight = 0
103
- this.iwidth = 0
104
-
105
- this.padding = {
106
- left: 0,
107
- top: 0,
108
- right: 0,
109
- bottom: 0
110
- }
111
-
112
- this.hover = null
113
- this.history = []
114
- this.clickable = []
115
- this.keyable = []
116
- this.grabKeys = false
117
- this.lockKeys = false
118
- this.focused
119
- this._buf = ''
120
-
121
- this._ci = -1
122
-
123
- if (options.title) {
124
- this.title = options.title
125
- }
126
-
127
- options.cursor = options.cursor || {
128
- artificial: options.artificialCursor,
129
- shape: options.cursorShape,
130
- blink: options.cursorBlink,
131
- color: options.cursorColor
132
- }
133
-
134
- this.cursor = {
135
- artificial: options.cursor.artificial || false,
136
- shape: options.cursor.shape || 'block',
137
- blink: options.cursor.blink || false,
138
- color: options.cursor.color || null,
139
- _set: false,
140
- _state: 1,
141
- _hidden: true
142
- }
143
-
144
- this.program.on('resize', function () {
145
- self.alloc()
146
- self.render()
147
- ;(function emit(el) {
148
- el.emit('resize')
149
- el.children.forEach(emit)
150
- })(self)
151
- })
152
-
153
- this.program.on('focus', function () {
154
- self.emit('focus')
155
- })
156
-
157
- this.program.on('blur', function () {
158
- self.emit('blur')
159
- })
160
-
161
- this.program.on('warning', function (text) {
162
- self.emit('warning', text)
163
- })
164
-
165
- this.on('newListener', function fn(type) {
166
- if (type === 'keypress' || type.indexOf('key ') === 0 || type === 'mouse') {
167
- if (type === 'keypress' || type.indexOf('key ') === 0) {
168
- self._listenKeys()
169
- }
170
- if (type === 'mouse') {
171
- self._listenMouse()
172
- }
173
- }
174
- if (
175
- type === 'mouse' ||
176
- type === 'click' ||
177
- type === 'mouseover' ||
178
- type === 'mouseout' ||
179
- type === 'mousedown' ||
180
- type === 'mouseup' ||
181
- type === 'mousewheel' ||
182
- type === 'wheeldown' ||
183
- type === 'wheelup' ||
184
- type === 'mousemove'
185
- ) {
186
- self._listenMouse()
187
- }
188
- })
189
-
190
- this.setMaxListeners(Infinity)
191
-
192
- this.enter()
193
-
194
- this.postEnter()
195
- }
196
-
197
- Screen.global = null
198
-
199
- Screen.total = 0
200
-
201
- Screen.instances = []
202
-
203
- Screen.bind = function (screen) {
204
- if (!Screen.global) {
205
- Screen.global = screen
206
- }
207
-
208
- if (!~Screen.instances.indexOf(screen)) {
209
- Screen.instances.push(screen)
210
- screen.index = Screen.total
211
- Screen.total++
212
- }
213
-
214
- if (Screen._bound) {
215
- return
216
- }
217
- Screen._bound = true
218
-
219
- process.on(
220
- 'uncaughtException',
221
- (Screen._exceptionHandler = function (err) {
222
- if (process.listeners('uncaughtException').length > 1) {
223
- return
224
- }
225
- Screen.instances.slice().forEach(function (screen) {
226
- screen.destroy()
227
- })
228
- err = err || new Error('Uncaught Exception.')
229
- console.error(err.stack ? err.stack + '' : err + '')
230
- nextTick(function () {
231
- process.exit(1)
232
- })
233
- })
234
- )
235
-
236
- ;['SIGTERM', 'SIGINT', 'SIGQUIT'].forEach(function (signal) {
237
- const name = '_' + signal.toLowerCase() + 'Handler'
238
- process.on(
239
- signal,
240
- (Screen[name] = function () {
241
- if (process.listeners(signal).length > 1) {
242
- return
243
- }
244
- nextTick(function () {
245
- process.exit(0)
246
- })
247
- })
248
- )
249
- })
250
-
251
- process.on(
252
- 'exit',
253
- (Screen._exitHandler = function () {
254
- Screen.instances.slice().forEach(function (screen) {
255
- screen.destroy()
256
- })
257
- })
258
- )
259
- }
260
-
261
- Object.setPrototypeOf(Screen.prototype, Node.prototype)
262
-
263
- Screen.prototype.type = 'screen'
264
-
265
- Screen.prototype.__defineGetter__('title', function () {
266
- return this.program.title
267
- })
268
-
269
- Screen.prototype.__defineSetter__('title', function (title) {
270
- return (this.program.title = title)
271
- })
272
-
273
- Screen.prototype.__defineGetter__('terminal', function () {
274
- return this.program.terminal
275
- })
276
-
277
- Screen.prototype.__defineSetter__('terminal', function (terminal) {
278
- this.setTerminal(terminal)
279
- return this.program.terminal
280
- })
281
-
282
- Screen.prototype.setTerminal = function (terminal) {
283
- const entered = !!this.program.isAlt
284
- if (entered) {
285
- this._buf = ''
286
- this.program._buf = ''
287
- this.leave()
288
- }
289
- this.program.setTerminal(terminal)
290
- this.tput = this.program.tput
291
- if (entered) {
292
- this.enter()
293
- }
294
- }
295
-
296
- Screen.prototype.enter = function () {
297
- if (this.program.isAlt) {
298
- return
299
- }
300
- if (!this.cursor._set) {
301
- if (this.options.cursor.shape) {
302
- this.cursorShape(this.cursor.shape, this.cursor.blink)
303
- }
304
- if (this.options.cursor.color) {
305
- this.cursorColor(this.cursor.color)
306
- }
307
- }
308
- if (process.platform === 'win32') {
309
- try {
310
- cp.execSync('cls', { stdio: 'ignore', timeout: 1000 })
311
- } catch (e) {}
312
- }
313
- this.program.alternateBuffer()
314
- this.program.put.keypad_xmit()
315
- this.program.csr(0, this.height - 1)
316
- this.program.hideCursor()
317
- this.program.cup(0, 0)
318
- // We need this for tmux now:
319
- if (this.tput.strings.ena_acs) {
320
- this.program._write(this.tput.enacs())
321
- }
322
- this.alloc()
323
- }
324
-
325
- Screen.prototype.leave = function () {
326
- if (!this.program.isAlt) {
327
- return
328
- }
329
- this.program.put.keypad_local()
330
- if (
331
- this.program.scrollTop !== 0 ||
332
- this.program.scrollBottom !== this.rows - 1
333
- ) {
334
- this.program.csr(0, this.height - 1)
335
- }
336
- // XXX For some reason if alloc/clear() is before this
337
- // line, it doesn't work on linux console.
338
- this.program.showCursor()
339
- this.alloc()
340
- if (this._listenedMouse) {
341
- this.program.disableMouse()
342
- }
343
- this.program.normalBuffer()
344
- if (this.cursor._set) {
345
- this.cursorReset()
346
- }
347
- this.program.flush()
348
- if (process.platform === 'win32') {
349
- try {
350
- cp.execSync('cls', { stdio: 'ignore', timeout: 1000 })
351
- } catch (e) {}
352
- }
353
- }
354
-
355
- Screen.prototype.postEnter = function () {
356
- const self = this
357
- if (this.options.debug) {
358
- const Log = require('./log')
359
- this.debugLog = new Log({
360
- screen: this,
361
- parent: this,
362
- hidden: true,
363
- draggable: true,
364
- left: 'center',
365
- top: 'center',
366
- width: '30%',
367
- height: '30%',
368
- border: 'line',
369
- label: ' {bold}Debug Log{/bold} ',
370
- tags: true,
371
- keys: true,
372
- vi: true,
373
- mouse: true,
374
- scrollbar: {
375
- ch: ' ',
376
- track: {
377
- bg: 'yellow'
378
- },
379
- style: {
380
- inverse: true
381
- }
382
- }
383
- })
384
-
385
- this.debugLog.toggle = function () {
386
- if (self.debugLog.hidden) {
387
- self.saveFocus()
388
- self.debugLog.show()
389
- self.debugLog.setFront()
390
- self.debugLog.focus()
391
- } else {
392
- self.debugLog.hide()
393
- self.restoreFocus()
394
- }
395
- self.render()
396
- }
397
-
398
- this.debugLog.key(['q', 'escape'], self.debugLog.toggle)
399
- this.key('f12', self.debugLog.toggle)
400
- }
401
-
402
- if (this.options.warnings) {
403
- this.on('warning', function (text) {
404
- const Box = require('./box')
405
- const warning = new Box({
406
- screen: self,
407
- parent: self,
408
- left: 'center',
409
- top: 'center',
410
- width: 'shrink',
411
- padding: 1,
412
- height: 'shrink',
413
- align: 'center',
414
- valign: 'middle',
415
- border: 'line',
416
- label: ' {red-fg}{bold}WARNING{/} ',
417
- content: '{bold}' + text + '{/bold}',
418
- tags: true
419
- })
420
- self.render()
421
- const timeout = setTimeout(function () {
422
- warning.destroy()
423
- self.render()
424
- }, 1500)
425
- if (timeout.unref) {
426
- timeout.unref()
427
- }
428
- })
429
- }
430
- }
431
-
432
- Screen.prototype._destroy = Screen.prototype.destroy
433
- Screen.prototype.destroy = function () {
434
- this.leave()
435
-
436
- const index = Screen.instances.indexOf(this)
437
- if (~index) {
438
- Screen.instances.splice(index, 1)
439
- Screen.total--
440
-
441
- Screen.global = Screen.instances[0]
442
-
443
- if (Screen.total === 0) {
444
- Screen.global = null
445
-
446
- process.removeListener('uncaughtException', Screen._exceptionHandler)
447
- process.removeListener('SIGTERM', Screen._sigtermHandler)
448
- process.removeListener('SIGINT', Screen._sigintHandler)
449
- process.removeListener('SIGQUIT', Screen._sigquitHandler)
450
- process.removeListener('exit', Screen._exitHandler)
451
- delete Screen._exceptionHandler
452
- delete Screen._sigtermHandler
453
- delete Screen._sigintHandler
454
- delete Screen._sigquitHandler
455
- delete Screen._exitHandler
456
-
457
- delete Screen._bound
458
- }
459
-
460
- this.destroyed = true
461
- this.emit('destroy')
462
- this._destroy()
463
- }
464
-
465
- this.program.destroy()
466
- }
467
-
468
- Screen.prototype.log = function () {
469
- return this.program.log.apply(this.program, arguments)
470
- }
471
-
472
- Screen.prototype.debug = function () {
473
- if (this.debugLog) {
474
- this.debugLog.log.apply(this.debugLog, arguments)
475
- }
476
- return this.program.debug.apply(this.program, arguments)
477
- }
478
-
479
- Screen.prototype._listenMouse = function (el) {
480
- const self = this
481
-
482
- if (el && !~this.clickable.indexOf(el)) {
483
- el.clickable = true
484
- this.clickable.push(el)
485
- }
486
-
487
- if (this._listenedMouse) {
488
- return
489
- }
490
- this._listenedMouse = true
491
-
492
- this.program.enableMouse()
493
- if (this.options.sendFocus) {
494
- this.program.setMouse({ sendFocus: true }, true)
495
- }
496
-
497
- this.on('render', function () {
498
- self._needsClickableSort = true
499
- })
500
-
501
- this.program.on('mouse', function (data) {
502
- if (self.lockKeys) {
503
- return
504
- }
505
-
506
- if (self._needsClickableSort) {
507
- const helpers = require('../helpers')
508
- self.clickable = helpers.hsort(self.clickable)
509
- self._needsClickableSort = false
510
- }
511
-
512
- let i = 0,
513
- el,
514
- set,
515
- pos
516
-
517
- for (; i < self.clickable.length; i++) {
518
- el = self.clickable[i]
519
-
520
- if (el.detached || !el.visible) {
521
- continue
522
- }
523
-
524
- // if (self.grabMouse && self.focused !== el
525
- // && !el.hasAncestor(self.focused)) continue;
526
-
527
- pos = el.lpos
528
- if (!pos) {
529
- continue
530
- }
531
-
532
- if (
533
- data.x >= pos.xi &&
534
- data.x < pos.xl &&
535
- data.y >= pos.yi &&
536
- data.y < pos.yl
537
- ) {
538
- el.emit('mouse', data)
539
- if (data.action === 'mousedown') {
540
- self.mouseDown = el
541
- } else if (data.action === 'mouseup') {
542
- ;(self.mouseDown || el).emit('click', data)
543
- self.mouseDown = null
544
- } else if (data.action === 'mousemove') {
545
- if (self.hover && el.index > self.hover.index) {
546
- set = false
547
- }
548
- if (self.hover !== el && !set) {
549
- if (self.hover) {
550
- self.hover.emit('mouseout', data)
551
- }
552
- el.emit('mouseover', data)
553
- self.hover = el
554
- }
555
- set = true
556
- }
557
- el.emit(data.action, data)
558
- break
559
- }
560
- }
561
-
562
- // Just mouseover?
563
- if (
564
- (data.action === 'mousemove' ||
565
- data.action === 'mousedown' ||
566
- data.action === 'mouseup') &&
567
- self.hover &&
568
- !set
569
- ) {
570
- self.hover.emit('mouseout', data)
571
- self.hover = null
572
- }
573
-
574
- self.emit('mouse', data)
575
- self.emit(data.action, data)
576
- })
577
-
578
- // Autofocus highest element.
579
- // this.on('element click', function(el, data) {
580
- // var target;
581
- // do {
582
- // if (el.clickable === true && el.options.autoFocus !== false) {
583
- // target = el;
584
- // }
585
- // } while (el = el.parent);
586
- // if (target) target.focus();
587
- // });
588
-
589
- // Autofocus elements with the appropriate option.
590
- this.on('element click', function (el) {
591
- if (el.clickable === true && el.options.autoFocus !== false) {
592
- el.focus()
593
- }
594
- })
595
- }
596
-
597
- Screen.prototype.enableMouse = function (el) {
598
- this._listenMouse(el)
599
- }
600
-
601
- Screen.prototype._listenKeys = function (el) {
602
- const self = this
603
-
604
- if (el && !~this.keyable.indexOf(el)) {
605
- el.keyable = true
606
- this.keyable.push(el)
607
- }
608
-
609
- if (this._listenedKeys) {
610
- return
611
- }
612
- this._listenedKeys = true
613
-
614
- // NOTE: The event emissions used to be reversed:
615
- // element + screen
616
- // They are now:
617
- // screen + element
618
- // After the first keypress emitted, the handler
619
- // checks to make sure grabKeys, lockKeys, and focused
620
- // weren't changed, and handles those situations appropriately.
621
- this.program.on('keypress', function (ch, key) {
622
- if (self.lockKeys && !~self.ignoreLocked.indexOf(key.full)) {
623
- return
624
- }
625
-
626
- const focused = self.focused,
627
- grabKeys = self.grabKeys
628
-
629
- if (!grabKeys || ~self.ignoreLocked.indexOf(key.full)) {
630
- self.emit('keypress', ch, key)
631
- self.emit('key ' + key.full, ch, key)
632
- }
633
-
634
- // If something changed from the screen key handler, stop.
635
- if (self.grabKeys !== grabKeys || self.lockKeys) {
636
- return
637
- }
638
-
639
- if (focused && focused.keyable) {
640
- focused.emit('keypress', ch, key)
641
- focused.emit('key ' + key.full, ch, key)
642
- }
643
- })
644
- }
645
-
646
- Screen.prototype.enableKeys = function (el) {
647
- this._listenKeys(el)
648
- }
649
-
650
- Screen.prototype.enableInput = function (el) {
651
- this._listenMouse(el)
652
- this._listenKeys(el)
653
- }
654
-
655
- Screen.prototype._initHover = function () {
656
- const self = this
657
-
658
- if (this._hoverText) {
659
- return
660
- }
661
- const Box = require('./box')
662
- this._hoverText = new Box({
663
- screen: this,
664
- left: 0,
665
- top: 0,
666
- tags: false,
667
- height: 'shrink',
668
- width: 'shrink',
669
- border: 'line',
670
- style: {
671
- border: {
672
- fg: 'default'
673
- },
674
- bg: 'default',
675
- fg: 'default'
676
- }
677
- })
678
-
679
- this.on('mousemove', function (data) {
680
- if (self._hoverText.detached) {
681
- return
682
- }
683
- self._hoverText.rleft = data.x + 1
684
- self._hoverText.rtop = data.y
685
- self.render()
686
- })
687
-
688
- this.on('element mouseover', function (el, data) {
689
- if (!el._hoverOptions) {
690
- return
691
- }
692
- self._hoverText.parseTags = el.parseTags
693
- self._hoverText.setContent(el._hoverOptions.text)
694
- self.append(self._hoverText)
695
- self._hoverText.rleft = data.x + 1
696
- self._hoverText.rtop = data.y
697
- self.render()
698
- })
699
-
700
- this.on('element mouseout', function () {
701
- if (self._hoverText.detached) {
702
- return
703
- }
704
- self._hoverText.detach()
705
- self.render()
706
- })
707
-
708
- // XXX This can cause problems if the
709
- // terminal does not support allMotion.
710
- // Workaround: check to see if content is set.
711
- this.on('element mouseup', function (el) {
712
- if (!self._hoverText.getContent()) {
713
- return
714
- }
715
- if (!el._hoverOptions) {
716
- return
717
- }
718
- self.append(self._hoverText)
719
- self.render()
720
- })
721
- }
722
-
723
- Screen.prototype.__defineGetter__('cols', function () {
724
- return this.program.cols
725
- })
726
-
727
- Screen.prototype.__defineGetter__('rows', function () {
728
- return this.program.rows
729
- })
730
-
731
- Screen.prototype.__defineGetter__('width', function () {
732
- return this.program.cols
733
- })
734
-
735
- Screen.prototype.__defineGetter__('height', function () {
736
- return this.program.rows
737
- })
738
-
739
- Screen.prototype.alloc = function (dirty) {
740
- let x, y
741
-
742
- this.lines = []
743
- for (y = 0; y < this.rows; y++) {
744
- this.lines[y] = []
745
- for (x = 0; x < this.cols; x++) {
746
- this.lines[y][x] = [this.dattr, ' ']
747
- }
748
- this.lines[y].dirty = !!dirty
749
- }
750
-
751
- this.olines = []
752
- for (y = 0; y < this.rows; y++) {
753
- this.olines[y] = []
754
- for (x = 0; x < this.cols; x++) {
755
- this.olines[y][x] = [this.dattr, ' ']
756
- }
757
- }
758
-
759
- this.program.clear()
760
- }
761
-
762
- Screen.prototype.realloc = function () {
763
- return this.alloc(true)
764
- }
765
-
766
- Screen.prototype.render = function () {
767
- const self = this
768
-
769
- if (this.destroyed) {
770
- return
771
- }
772
-
773
- this.emit('prerender')
774
-
775
- this._borderStops = {}
776
-
777
- // TODO: Possibly get rid of .dirty altogether.
778
- // TODO: Could possibly drop .dirty and just clear the `lines` buffer every
779
- // time before a screen.render. This way clearRegion doesn't have to be
780
- // called in arbitrary places for the sake of clearing a spot where an
781
- // element used to be (e.g. when an element moves or is hidden). There could
782
- // be some overhead though.
783
- // this.screen.clearRegion(0, this.cols, 0, this.rows);
784
- this._ci = 0
785
- this.children.forEach(function (el) {
786
- el.index = self._ci++
787
- //el._rendering = true;
788
- el.render()
789
- //el._rendering = false;
790
- })
791
- this._ci = -1
792
-
793
- if (this.screen.dockBorders) {
794
- this._dockBorders()
795
- }
796
-
797
- this.draw(0, this.lines.length - 1)
798
-
799
- // XXX Workaround to deal with cursor pos before the screen has rendered and
800
- // lpos is not reliable (stale).
801
- if (this.focused && this.focused._updateCursor) {
802
- this.focused._updateCursor(true)
803
- }
804
-
805
- this.renders++
806
-
807
- this.emit('render')
808
- }
809
-
810
- Screen.prototype.blankLine = function (ch, dirty) {
811
- const out = []
812
- for (let x = 0; x < this.cols; x++) {
813
- out[x] = [this.dattr, ch || ' ']
814
- }
815
- out.dirty = dirty
816
- return out
817
- }
818
-
819
- Screen.prototype.insertLine = function (n, y, top, bottom) {
820
- // if (y === top) return this.insertLineNC(n, y, top, bottom);
821
-
822
- if (
823
- !this.tput.strings.change_scroll_region ||
824
- !this.tput.strings.delete_line ||
825
- !this.tput.strings.insert_line
826
- ) {
827
- return
828
- }
829
-
830
- this._buf += this.tput.csr(top, bottom)
831
- this._buf += this.tput.cup(y, 0)
832
- this._buf += this.tput.il(n)
833
- this._buf += this.tput.csr(0, this.height - 1)
834
-
835
- const j = bottom + 1
836
-
837
- while (n--) {
838
- this.lines.splice(y, 0, this.blankLine())
839
- this.lines.splice(j, 1)
840
- this.olines.splice(y, 0, this.blankLine())
841
- this.olines.splice(j, 1)
842
- }
843
- }
844
-
845
- Screen.prototype.deleteLine = function (n, y, top, bottom) {
846
- // if (y === top) return this.deleteLineNC(n, y, top, bottom);
847
-
848
- if (
849
- !this.tput.strings.change_scroll_region ||
850
- !this.tput.strings.delete_line ||
851
- !this.tput.strings.insert_line
852
- ) {
853
- return
854
- }
855
-
856
- this._buf += this.tput.csr(top, bottom)
857
- this._buf += this.tput.cup(y, 0)
858
- this._buf += this.tput.dl(n)
859
- this._buf += this.tput.csr(0, this.height - 1)
860
-
861
- const j = bottom + 1
862
-
863
- while (n--) {
864
- this.lines.splice(j, 0, this.blankLine())
865
- this.lines.splice(y, 1)
866
- this.olines.splice(j, 0, this.blankLine())
867
- this.olines.splice(y, 1)
868
- }
869
- }
870
-
871
- // This is how ncurses does it.
872
- // Scroll down (up cursor-wise).
873
- // This will only work for top line deletion as opposed to arbitrary lines.
874
- Screen.prototype.insertLineNC = function (n, y, top, bottom) {
875
- if (
876
- !this.tput.strings.change_scroll_region ||
877
- !this.tput.strings.delete_line
878
- ) {
879
- return
880
- }
881
-
882
- this._buf += this.tput.csr(top, bottom)
883
- this._buf += this.tput.cup(top, 0)
884
- this._buf += this.tput.dl(n)
885
- this._buf += this.tput.csr(0, this.height - 1)
886
-
887
- const j = bottom + 1
888
-
889
- while (n--) {
890
- this.lines.splice(j, 0, this.blankLine())
891
- this.lines.splice(y, 1)
892
- this.olines.splice(j, 0, this.blankLine())
893
- this.olines.splice(y, 1)
894
- }
895
- }
896
-
897
- // This is how ncurses does it.
898
- // Scroll up (down cursor-wise).
899
- // This will only work for bottom line deletion as opposed to arbitrary lines.
900
- Screen.prototype.deleteLineNC = function (n, y, top, bottom) {
901
- if (
902
- !this.tput.strings.change_scroll_region ||
903
- !this.tput.strings.delete_line
904
- ) {
905
- return
906
- }
907
-
908
- this._buf += this.tput.csr(top, bottom)
909
- this._buf += this.tput.cup(bottom, 0)
910
- this._buf += Array(n + 1).join('\n')
911
- this._buf += this.tput.csr(0, this.height - 1)
912
-
913
- const j = bottom + 1
914
-
915
- while (n--) {
916
- this.lines.splice(j, 0, this.blankLine())
917
- this.lines.splice(y, 1)
918
- this.olines.splice(j, 0, this.blankLine())
919
- this.olines.splice(y, 1)
920
- }
921
- }
922
-
923
- Screen.prototype.insertBottom = function (top, bottom) {
924
- return this.deleteLine(1, top, top, bottom)
925
- }
926
-
927
- Screen.prototype.insertTop = function (top, bottom) {
928
- return this.insertLine(1, top, top, bottom)
929
- }
930
-
931
- Screen.prototype.deleteBottom = function (top, bottom) {
932
- return this.clearRegion(0, this.width, bottom, bottom)
933
- }
934
-
935
- Screen.prototype.deleteTop = function (top, bottom) {
936
- // Same as: return this.insertBottom(top, bottom);
937
- return this.deleteLine(1, top, top, bottom)
938
- }
939
-
940
- // Parse the sides of an element to determine
941
- // whether an element has uniform cells on
942
- // both sides. If it does, we can use CSR to
943
- // optimize scrolling on a scrollable element.
944
- // Not exactly sure how worthwile this is.
945
- // This will cause a performance/cpu-usage hit,
946
- // but will it be less or greater than the
947
- // performance hit of slow-rendering scrollable
948
- // boxes with clean sides?
949
- Screen.prototype.cleanSides = function (el) {
950
- const pos = el.lpos
951
-
952
- if (!pos) {
953
- return false
954
- }
955
-
956
- if (pos._cleanSides != null) {
957
- return pos._cleanSides
958
- }
959
-
960
- if (pos.xi <= 0 && pos.xl >= this.width) {
961
- return (pos._cleanSides = true)
962
- }
963
-
964
- if (this.options.fastCSR) {
965
- // Maybe just do this instead of parsing.
966
- if (pos.yi < 0) {
967
- return (pos._cleanSides = false)
968
- }
969
- if (pos.yl > this.height) {
970
- return (pos._cleanSides = false)
971
- }
972
- if (this.width - (pos.xl - pos.xi) < 40) {
973
- return (pos._cleanSides = true)
974
- }
975
- return (pos._cleanSides = false)
976
- }
977
-
978
- if (!this.options.smartCSR) {
979
- return false
980
- }
981
-
982
- // The scrollbar can't update properly, and there's also a
983
- // chance that the scrollbar may get moved around senselessly.
984
- // NOTE: In pratice, this doesn't seem to be the case.
985
- // if (this.scrollbar) {
986
- // return pos._cleanSides = false;
987
- // }
988
-
989
- // Doesn't matter if we're only a height of 1.
990
- // if ((pos.yl - el.ibottom) - (pos.yi + el.itop) <= 1) {
991
- // return pos._cleanSides = false;
992
- // }
993
-
994
- let yi = pos.yi + el.itop,
995
- yl = pos.yl - el.ibottom,
996
- first,
997
- ch,
998
- x,
999
- y
1000
-
1001
- if (pos.yi < 0) {
1002
- return (pos._cleanSides = false)
1003
- }
1004
- if (pos.yl > this.height) {
1005
- return (pos._cleanSides = false)
1006
- }
1007
- if (pos.xi - 1 < 0) {
1008
- return (pos._cleanSides = true)
1009
- }
1010
- if (pos.xl > this.width) {
1011
- return (pos._cleanSides = true)
1012
- }
1013
-
1014
- for (x = pos.xi - 1; x >= 0; x--) {
1015
- if (!this.olines[yi]) {
1016
- break
1017
- }
1018
- first = this.olines[yi][x]
1019
- for (y = yi; y < yl; y++) {
1020
- if (!this.olines[y] || !this.olines[y][x]) {
1021
- break
1022
- }
1023
- ch = this.olines[y][x]
1024
- if (ch[0] !== first[0] || ch[1] !== first[1]) {
1025
- return (pos._cleanSides = false)
1026
- }
1027
- }
1028
- }
1029
-
1030
- for (x = pos.xl; x < this.width; x++) {
1031
- if (!this.olines[yi]) {
1032
- break
1033
- }
1034
- first = this.olines[yi][x]
1035
- for (y = yi; y < yl; y++) {
1036
- if (!this.olines[y] || !this.olines[y][x]) {
1037
- break
1038
- }
1039
- ch = this.olines[y][x]
1040
- if (ch[0] !== first[0] || ch[1] !== first[1]) {
1041
- return (pos._cleanSides = false)
1042
- }
1043
- }
1044
- }
1045
-
1046
- return (pos._cleanSides = true)
1047
- }
1048
-
1049
- Screen.prototype._dockBorders = function () {
1050
- let lines = this.lines,
1051
- stops = this._borderStops,
1052
- i,
1053
- y,
1054
- x,
1055
- ch
1056
-
1057
- // var keys, stop;
1058
- //
1059
- // keys = Object.keys(this._borderStops)
1060
- // .map(function(k) { return +k; })
1061
- // .sort(function(a, b) { return a - b; });
1062
- //
1063
- // for (i = 0; i < keys.length; i++) {
1064
- // y = keys[i];
1065
- // if (!lines[y]) continue;
1066
- // stop = this._borderStops[y];
1067
- // for (x = stop.xi; x < stop.xl; x++) {
1068
-
1069
- stops = Object.keys(stops)
1070
- .map(function (k) {
1071
- return +k
1072
- })
1073
- .sort(function (a, b) {
1074
- return a - b
1075
- })
1076
-
1077
- for (i = 0; i < stops.length; i++) {
1078
- y = stops[i]
1079
- if (!lines[y]) {
1080
- continue
1081
- }
1082
- for (x = 0; x < this.width; x++) {
1083
- ch = lines[y][x][1]
1084
- if (angles[ch]) {
1085
- lines[y][x][1] = this._getAngle(lines, x, y)
1086
- lines[y].dirty = true
1087
- }
1088
- }
1089
- }
1090
- }
1091
-
1092
- Screen.prototype._getAngle = function (lines, x, y) {
1093
- let angle = 0,
1094
- attr = lines[y][x][0],
1095
- ch = lines[y][x][1]
1096
-
1097
- if (lines[y][x - 1] && langles[lines[y][x - 1][1]]) {
1098
- if (!this.options.ignoreDockContrast) {
1099
- if (lines[y][x - 1][0] !== attr) {
1100
- return ch
1101
- }
1102
- }
1103
- angle |= 1 << 3
1104
- }
1105
-
1106
- if (lines[y - 1] && uangles[lines[y - 1][x][1]]) {
1107
- if (!this.options.ignoreDockContrast) {
1108
- if (lines[y - 1][x][0] !== attr) {
1109
- return ch
1110
- }
1111
- }
1112
- angle |= 1 << 2
1113
- }
1114
-
1115
- if (lines[y][x + 1] && rangles[lines[y][x + 1][1]]) {
1116
- if (!this.options.ignoreDockContrast) {
1117
- if (lines[y][x + 1][0] !== attr) {
1118
- return ch
1119
- }
1120
- }
1121
- angle |= 1 << 1
1122
- }
1123
-
1124
- if (lines[y + 1] && dangles[lines[y + 1][x][1]]) {
1125
- if (!this.options.ignoreDockContrast) {
1126
- if (lines[y + 1][x][0] !== attr) {
1127
- return ch
1128
- }
1129
- }
1130
- angle |= 1 << 0
1131
- }
1132
-
1133
- // Experimental: fixes this situation:
1134
- // +----------+
1135
- // | <-- empty space here, should be a T angle
1136
- // +-------+ |
1137
- // | | |
1138
- // +-------+ |
1139
- // | |
1140
- // +----------+
1141
- // if (uangles[lines[y][x][1]]) {
1142
- // if (lines[y + 1] && cdangles[lines[y + 1][x][1]]) {
1143
- // if (!this.options.ignoreDockContrast) {
1144
- // if (lines[y + 1][x][0] !== attr) return ch;
1145
- // }
1146
- // angle |= 1 << 0;
1147
- // }
1148
- // }
1149
-
1150
- return angleTable[angle] || ch
1151
- }
1152
-
1153
- Screen.prototype.draw = function (start, end) {
1154
- // this.emit('predraw');
1155
-
1156
- let x, y, line, out, ch, data, attr, fg, bg, flags
1157
-
1158
- let main = '',
1159
- pre,
1160
- post
1161
-
1162
- let clr, neq, xx
1163
-
1164
- let lx = -1,
1165
- ly = -1,
1166
- o
1167
-
1168
- let acs
1169
-
1170
- if (this._buf) {
1171
- main += this._buf
1172
- this._buf = ''
1173
- }
1174
-
1175
- for (y = start; y <= end; y++) {
1176
- line = this.lines[y]
1177
- o = this.olines[y]
1178
-
1179
- if (!line.dirty && !(this.cursor.artificial && y === this.program.y)) {
1180
- continue
1181
- }
1182
- line.dirty = false
1183
-
1184
- out = ''
1185
- attr = this.dattr
1186
-
1187
- for (x = 0; x < line.length; x++) {
1188
- data = line[x][0]
1189
- ch = line[x][1]
1190
-
1191
- // Render the artificial cursor.
1192
- if (
1193
- this.cursor.artificial &&
1194
- !this.cursor._hidden &&
1195
- this.cursor._state &&
1196
- x === this.program.x &&
1197
- y === this.program.y
1198
- ) {
1199
- const cattr = this._cursorAttr(this.cursor, data)
1200
- if (cattr.ch) {
1201
- ch = cattr.ch
1202
- }
1203
- data = cattr.attr
1204
- }
1205
-
1206
- // Take advantage of xterm's back_color_erase feature by using a
1207
- // lookahead. Stop spitting out so many damn spaces. NOTE: Is checking
1208
- // the bg for non BCE terminals worth the overhead?
1209
- if (
1210
- this.options.useBCE &&
1211
- ch === ' ' &&
1212
- (this.tput.bools.back_color_erase ||
1213
- (data & 0x1ff) === (this.dattr & 0x1ff)) &&
1214
- ((data >> 18) & 8) === ((this.dattr >> 18) & 8)
1215
- ) {
1216
- clr = true
1217
- neq = false
1218
-
1219
- for (xx = x; xx < line.length; xx++) {
1220
- if (line[xx][0] !== data || line[xx][1] !== ' ') {
1221
- clr = false
1222
- break
1223
- }
1224
- if (line[xx][0] !== o[xx][0] || line[xx][1] !== o[xx][1]) {
1225
- neq = true
1226
- }
1227
- }
1228
-
1229
- if (clr && neq) {
1230
- ;(lx = -1), (ly = -1)
1231
- if (data !== attr) {
1232
- out += this.codeAttr(data)
1233
- attr = data
1234
- }
1235
- out += this.tput.cup(y, x)
1236
- out += this.tput.el()
1237
- for (xx = x; xx < line.length; xx++) {
1238
- o[xx][0] = data
1239
- o[xx][1] = ' '
1240
- }
1241
- break
1242
- }
1243
-
1244
- // If there's more than 10 spaces, use EL regardless
1245
- // and start over drawing the rest of line. Might
1246
- // not be worth it. Try to use ECH if the terminal
1247
- // supports it. Maybe only try to use ECH here.
1248
- // //if (this.tput.strings.erase_chars)
1249
- // if (!clr && neq && (xx - x) > 10) {
1250
- // lx = -1, ly = -1;
1251
- // if (data !== attr) {
1252
- // out += this.codeAttr(data);
1253
- // attr = data;
1254
- // }
1255
- // out += this.tput.cup(y, x);
1256
- // if (this.tput.strings.erase_chars) {
1257
- // // Use erase_chars to avoid erasing the whole line.
1258
- // out += this.tput.ech(xx - x);
1259
- // } else {
1260
- // out += this.tput.el();
1261
- // }
1262
- // if (this.tput.strings.parm_right_cursor) {
1263
- // out += this.tput.cuf(xx - x);
1264
- // } else {
1265
- // out += this.tput.cup(y, xx);
1266
- // }
1267
- // this.fillRegion(data, ' ',
1268
- // x, this.tput.strings.erase_chars ? xx : line.length,
1269
- // y, y + 1);
1270
- // x = xx - 1;
1271
- // continue;
1272
- // }
1273
-
1274
- // Skip to the next line if the
1275
- // rest of the line is already drawn.
1276
- // if (!neq) {
1277
- // for (; xx < line.length; xx++) {
1278
- // if (line[xx][0] !== o[xx][0] || line[xx][1] !== o[xx][1]) {
1279
- // neq = true;
1280
- // break;
1281
- // }
1282
- // }
1283
- // if (!neq) {
1284
- // attr = data;
1285
- // break;
1286
- // }
1287
- // }
1288
- }
1289
-
1290
- // Optimize by comparing the real output
1291
- // buffer to the pending output buffer.
1292
- if (data === o[x][0] && ch === o[x][1]) {
1293
- if (lx === -1) {
1294
- lx = x
1295
- ly = y
1296
- }
1297
- continue
1298
- } else if (lx !== -1) {
1299
- if (this.tput.strings.parm_right_cursor) {
1300
- out += y === ly ? this.tput.cuf(x - lx) : this.tput.cup(y, x)
1301
- } else {
1302
- out += this.tput.cup(y, x)
1303
- }
1304
- ;(lx = -1), (ly = -1)
1305
- }
1306
- o[x][0] = data
1307
- o[x][1] = ch
1308
-
1309
- if (data !== attr) {
1310
- if (attr !== this.dattr) {
1311
- out += '\x1b[m'
1312
- }
1313
- if (data !== this.dattr) {
1314
- out += '\x1b['
1315
-
1316
- bg = data & 0x1ff
1317
- fg = (data >> 9) & 0x1ff
1318
- flags = data >> 18
1319
-
1320
- // bold
1321
- if (flags & 1) {
1322
- out += '1;'
1323
- }
1324
-
1325
- // underline
1326
- if (flags & 2) {
1327
- out += '4;'
1328
- }
1329
-
1330
- // blink
1331
- if (flags & 4) {
1332
- out += '5;'
1333
- }
1334
-
1335
- // inverse
1336
- if (flags & 8) {
1337
- out += '7;'
1338
- }
1339
-
1340
- // invisible
1341
- if (flags & 16) {
1342
- out += '8;'
1343
- }
1344
-
1345
- if (bg !== 0x1ff) {
1346
- bg = this._reduceColor(bg)
1347
- if (bg < 16) {
1348
- if (bg < 8) {
1349
- bg += 40
1350
- } else if (bg < 16) {
1351
- bg -= 8
1352
- bg += 100
1353
- }
1354
- out += bg + ';'
1355
- } else {
1356
- out += '48;5;' + bg + ';'
1357
- }
1358
- }
1359
-
1360
- if (fg !== 0x1ff) {
1361
- fg = this._reduceColor(fg)
1362
- if (fg < 16) {
1363
- if (fg < 8) {
1364
- fg += 30
1365
- } else if (fg < 16) {
1366
- fg -= 8
1367
- fg += 90
1368
- }
1369
- out += fg + ';'
1370
- } else {
1371
- out += '38;5;' + fg + ';'
1372
- }
1373
- }
1374
-
1375
- if (out[out.length - 1] === ';') {
1376
- out = out.slice(0, -1)
1377
- }
1378
-
1379
- out += 'm'
1380
- }
1381
- }
1382
-
1383
- // If we find a double-width char, eat the next character which should be
1384
- // a space due to parseContent's behavior.
1385
- if (this.fullUnicode) {
1386
- // If this is a surrogate pair double-width char, we can ignore it
1387
- // because parseContent already counted it as length=2.
1388
- if (unicode.charWidth(line[x][1]) === 2) {
1389
- // NOTE: At cols=44, the bug that is avoided
1390
- // by the angles check occurs in widget-unicode:
1391
- // Might also need: `line[x + 1][0] !== line[x][0]`
1392
- // for borderless boxes?
1393
- if (x === line.length - 1 || angles[line[x + 1][1]]) {
1394
- // If we're at the end, we don't have enough space for a
1395
- // double-width. Overwrite it with a space and ignore.
1396
- ch = ' '
1397
- o[x][1] = '\0'
1398
- } else {
1399
- // ALWAYS refresh double-width chars because this special cursor
1400
- // behavior is needed. There may be a more efficient way of doing
1401
- // this. See above.
1402
- o[x][1] = '\0'
1403
- // Eat the next character by moving forward and marking as a
1404
- // space (which it is).
1405
- o[++x][1] = '\0'
1406
- }
1407
- }
1408
- }
1409
-
1410
- // Attempt to use ACS for supported characters.
1411
- // This is not ideal, but it's how ncurses works.
1412
- // There are a lot of terminals that support ACS
1413
- // *and UTF8, but do not declare U8. So ACS ends
1414
- // up being used (slower than utf8). Terminals
1415
- // that do not support ACS and do not explicitly
1416
- // support UTF8 get their unicode characters
1417
- // replaced with really ugly ascii characters.
1418
- // It is possible there is a terminal out there
1419
- // somewhere that does not support ACS, but
1420
- // supports UTF8, but I imagine it's unlikely.
1421
- // Maybe remove !this.tput.unicode check, however,
1422
- // this seems to be the way ncurses does it.
1423
- if (
1424
- this.tput.strings.enter_alt_charset_mode &&
1425
- !this.tput.brokenACS &&
1426
- (this.tput.acscr[ch] || acs)
1427
- ) {
1428
- // Fun fact: even if this.tput.brokenACS wasn't checked here,
1429
- // the linux console would still work fine because the acs
1430
- // table would fail the check of: this.tput.acscr[ch]
1431
- if (this.tput.acscr[ch]) {
1432
- if (acs) {
1433
- ch = this.tput.acscr[ch]
1434
- } else {
1435
- ch = this.tput.smacs() + this.tput.acscr[ch]
1436
- acs = true
1437
- }
1438
- } else if (acs) {
1439
- ch = this.tput.rmacs() + ch
1440
- acs = false
1441
- }
1442
- } else {
1443
- // U8 is not consistently correct. Some terminfo's
1444
- // terminals that do not declare it may actually
1445
- // support utf8 (e.g. urxvt), but if the terminal
1446
- // does not declare support for ACS (and U8), chances
1447
- // are it does not support UTF8. This is probably
1448
- // the "safest" way to do this. Should fix things
1449
- // like sun-color.
1450
- // NOTE: It could be the case that the $LANG
1451
- // is all that matters in some cases:
1452
- // if (!this.tput.unicode && ch > '~') {
1453
- if (!this.tput.unicode && this.tput.numbers.U8 !== 1 && ch > '~') {
1454
- ch = this.tput.utoa[ch] || '?'
1455
- }
1456
- }
1457
-
1458
- out += ch
1459
- attr = data
1460
- }
1461
-
1462
- if (attr !== this.dattr) {
1463
- out += '\x1b[m'
1464
- }
1465
-
1466
- if (out) {
1467
- main += this.tput.cup(y, 0) + out
1468
- }
1469
- }
1470
-
1471
- if (acs) {
1472
- main += this.tput.rmacs()
1473
- acs = false
1474
- }
1475
-
1476
- if (main) {
1477
- pre = ''
1478
- post = ''
1479
-
1480
- pre += this.tput.sc()
1481
- post += this.tput.rc()
1482
-
1483
- if (!this.program.cursorHidden) {
1484
- pre += this.tput.civis()
1485
- post += this.tput.cnorm()
1486
- }
1487
-
1488
- // this.program.flush();
1489
- // this.program._owrite(pre + main + post);
1490
- this.program._write(pre + main + post)
1491
- }
1492
-
1493
- // this.emit('draw');
1494
- }
1495
-
1496
- Screen.prototype._reduceColor = function (color) {
1497
- return colors.reduce(color, this.tput.colors)
1498
- }
1499
-
1500
- // Convert an SGR string to our own attribute format.
1501
- Screen.prototype.attrCode = function (code, cur, def) {
1502
- let flags = (cur >> 18) & 0x1ff,
1503
- fg = (cur >> 9) & 0x1ff,
1504
- bg = cur & 0x1ff,
1505
- c,
1506
- i
1507
-
1508
- code = code.slice(2, -1).split(';')
1509
- if (!code[0]) {
1510
- code[0] = '0'
1511
- }
1512
-
1513
- for (i = 0; i < code.length; i++) {
1514
- c = +code[i] || 0
1515
- switch (c) {
1516
- case 0: // normal
1517
- bg = def & 0x1ff
1518
- fg = (def >> 9) & 0x1ff
1519
- flags = (def >> 18) & 0x1ff
1520
- break
1521
- case 1: // bold
1522
- flags |= 1
1523
- break
1524
- case 22:
1525
- flags = (def >> 18) & 0x1ff
1526
- break
1527
- case 4: // underline
1528
- flags |= 2
1529
- break
1530
- case 24:
1531
- flags = (def >> 18) & 0x1ff
1532
- break
1533
- case 5: // blink
1534
- flags |= 4
1535
- break
1536
- case 25:
1537
- flags = (def >> 18) & 0x1ff
1538
- break
1539
- case 7: // inverse
1540
- flags |= 8
1541
- break
1542
- case 27:
1543
- flags = (def >> 18) & 0x1ff
1544
- break
1545
- case 8: // invisible
1546
- flags |= 16
1547
- break
1548
- case 28:
1549
- flags = (def >> 18) & 0x1ff
1550
- break
1551
- case 39: // default fg
1552
- fg = (def >> 9) & 0x1ff
1553
- break
1554
- case 49: // default bg
1555
- bg = def & 0x1ff
1556
- break
1557
- case 100: // default fg/bg
1558
- fg = (def >> 9) & 0x1ff
1559
- bg = def & 0x1ff
1560
- break
1561
- default: // color
1562
- if (c === 48 && +code[i + 1] === 5) {
1563
- i += 2
1564
- bg = +code[i]
1565
- break
1566
- } else if (c === 48 && +code[i + 1] === 2) {
1567
- i += 2
1568
- bg = colors.match(+code[i], +code[i + 1], +code[i + 2])
1569
- if (bg === -1) {
1570
- bg = def & 0x1ff
1571
- }
1572
- i += 2
1573
- break
1574
- } else if (c === 38 && +code[i + 1] === 5) {
1575
- i += 2
1576
- fg = +code[i]
1577
- break
1578
- } else if (c === 38 && +code[i + 1] === 2) {
1579
- i += 2
1580
- fg = colors.match(+code[i], +code[i + 1], +code[i + 2])
1581
- if (fg === -1) {
1582
- fg = (def >> 9) & 0x1ff
1583
- }
1584
- i += 2
1585
- break
1586
- }
1587
- if (c >= 40 && c <= 47) {
1588
- bg = c - 40
1589
- } else if (c >= 100 && c <= 107) {
1590
- bg = c - 100
1591
- bg += 8
1592
- } else if (c === 49) {
1593
- bg = def & 0x1ff
1594
- } else if (c >= 30 && c <= 37) {
1595
- fg = c - 30
1596
- } else if (c >= 90 && c <= 97) {
1597
- fg = c - 90
1598
- fg += 8
1599
- } else if (c === 39) {
1600
- fg = (def >> 9) & 0x1ff
1601
- } else if (c === 100) {
1602
- fg = (def >> 9) & 0x1ff
1603
- bg = def & 0x1ff
1604
- }
1605
- break
1606
- }
1607
- }
1608
-
1609
- return (flags << 18) | (fg << 9) | bg
1610
- }
1611
-
1612
- // Convert our own attribute format to an SGR string.
1613
- Screen.prototype.codeAttr = function (code) {
1614
- let flags = (code >> 18) & 0x1ff,
1615
- fg = (code >> 9) & 0x1ff,
1616
- bg = code & 0x1ff,
1617
- out = ''
1618
-
1619
- // bold
1620
- if (flags & 1) {
1621
- out += '1;'
1622
- }
1623
-
1624
- // underline
1625
- if (flags & 2) {
1626
- out += '4;'
1627
- }
1628
-
1629
- // blink
1630
- if (flags & 4) {
1631
- out += '5;'
1632
- }
1633
-
1634
- // inverse
1635
- if (flags & 8) {
1636
- out += '7;'
1637
- }
1638
-
1639
- // invisible
1640
- if (flags & 16) {
1641
- out += '8;'
1642
- }
1643
-
1644
- if (bg !== 0x1ff) {
1645
- bg = this._reduceColor(bg)
1646
- if (bg < 16) {
1647
- if (bg < 8) {
1648
- bg += 40
1649
- } else if (bg < 16) {
1650
- bg -= 8
1651
- bg += 100
1652
- }
1653
- out += bg + ';'
1654
- } else {
1655
- out += '48;5;' + bg + ';'
1656
- }
1657
- }
1658
-
1659
- if (fg !== 0x1ff) {
1660
- fg = this._reduceColor(fg)
1661
- if (fg < 16) {
1662
- if (fg < 8) {
1663
- fg += 30
1664
- } else if (fg < 16) {
1665
- fg -= 8
1666
- fg += 90
1667
- }
1668
- out += fg + ';'
1669
- } else {
1670
- out += '38;5;' + fg + ';'
1671
- }
1672
- }
1673
-
1674
- if (out[out.length - 1] === ';') {
1675
- out = out.slice(0, -1)
1676
- }
1677
-
1678
- return '\x1b[' + out + 'm'
1679
- }
1680
-
1681
- Screen.prototype.focusOffset = function (offset) {
1682
- const shown = this.keyable.filter(function (el) {
1683
- return !el.detached && el.visible
1684
- }).length
1685
-
1686
- if (!shown || !offset) {
1687
- return
1688
- }
1689
-
1690
- let i = this.keyable.indexOf(this.focused)
1691
- if (!~i) {
1692
- return
1693
- }
1694
-
1695
- if (offset > 0) {
1696
- while (offset--) {
1697
- if (++i > this.keyable.length - 1) {
1698
- i = 0
1699
- }
1700
- if (this.keyable[i].detached || !this.keyable[i].visible) {
1701
- offset++
1702
- }
1703
- }
1704
- } else {
1705
- offset = -offset
1706
- while (offset--) {
1707
- if (--i < 0) {
1708
- i = this.keyable.length - 1
1709
- }
1710
- if (this.keyable[i].detached || !this.keyable[i].visible) {
1711
- offset++
1712
- }
1713
- }
1714
- }
1715
-
1716
- return this.keyable[i].focus()
1717
- }
1718
-
1719
- Screen.prototype.focusPrev = Screen.prototype.focusPrevious = function () {
1720
- return this.focusOffset(-1)
1721
- }
1722
-
1723
- Screen.prototype.focusNext = function () {
1724
- return this.focusOffset(1)
1725
- }
1726
-
1727
- Screen.prototype.focusPush = function (el) {
1728
- if (!el) {
1729
- return
1730
- }
1731
- const old = this.history[this.history.length - 1]
1732
- if (this.history.length === 10) {
1733
- this.history.shift()
1734
- }
1735
- this.history.push(el)
1736
- this._focus(el, old)
1737
- }
1738
-
1739
- Screen.prototype.focusPop = function () {
1740
- const old = this.history.pop()
1741
- if (this.history.length) {
1742
- this._focus(this.history[this.history.length - 1], old)
1743
- }
1744
- return old
1745
- }
1746
-
1747
- Screen.prototype.saveFocus = function () {
1748
- return (this._savedFocus = this.focused)
1749
- }
1750
-
1751
- Screen.prototype.restoreFocus = function () {
1752
- if (!this._savedFocus) {
1753
- return
1754
- }
1755
- this._savedFocus.focus()
1756
- delete this._savedFocus
1757
- return this.focused
1758
- }
1759
-
1760
- Screen.prototype.rewindFocus = function () {
1761
- let old = this.history.pop(),
1762
- el
1763
-
1764
- while (this.history.length) {
1765
- el = this.history.pop()
1766
- if (!el.detached && el.visible) {
1767
- this.history.push(el)
1768
- this._focus(el, old)
1769
- return el
1770
- }
1771
- }
1772
-
1773
- if (old) {
1774
- old.emit('blur')
1775
- }
1776
- }
1777
-
1778
- Screen.prototype._focus = function (self, old) {
1779
- // Find a scrollable ancestor if we have one.
1780
- let el = self
1781
- while ((el = el.parent)) {
1782
- if (el.scrollable) {
1783
- break
1784
- }
1785
- }
1786
-
1787
- // If we're in a scrollable element,
1788
- // automatically scroll to the focused element.
1789
- if (el && !el.detached) {
1790
- // NOTE: This is different from the other "visible" values - it needs the
1791
- // visible height of the scrolling element itself, not the element within
1792
- // it.
1793
- const visible =
1794
- self.screen.height - el.atop - el.itop - el.abottom - el.ibottom
1795
- if (self.rtop < el.childBase) {
1796
- el.scrollTo(self.rtop)
1797
- self.screen.render()
1798
- } else if (
1799
- self.rtop + self.height - self.ibottom >
1800
- el.childBase + visible
1801
- ) {
1802
- // Explanation for el.itop here: takes into account scrollable elements
1803
- // with borders otherwise the element gets covered by the bottom border:
1804
- el.scrollTo(self.rtop - (el.height - self.height) + el.itop, true)
1805
- self.screen.render()
1806
- }
1807
- }
1808
-
1809
- if (old) {
1810
- old.emit('blur', self)
1811
- }
1812
-
1813
- self.emit('focus', old)
1814
- }
1815
-
1816
- Screen.prototype.__defineGetter__('focused', function () {
1817
- return this.history[this.history.length - 1]
1818
- })
1819
-
1820
- Screen.prototype.__defineSetter__('focused', function (el) {
1821
- return this.focusPush(el)
1822
- })
1823
-
1824
- Screen.prototype.clearRegion = function (xi, xl, yi, yl, override) {
1825
- return this.fillRegion(this.dattr, ' ', xi, xl, yi, yl, override)
1826
- }
1827
-
1828
- Screen.prototype.fillRegion = function (attr, ch, xi, xl, yi, yl, override) {
1829
- let lines = this.lines,
1830
- cell,
1831
- xx
1832
-
1833
- if (xi < 0) {
1834
- xi = 0
1835
- }
1836
- if (yi < 0) {
1837
- yi = 0
1838
- }
1839
-
1840
- for (; yi < yl; yi++) {
1841
- if (!lines[yi]) {
1842
- break
1843
- }
1844
- for (xx = xi; xx < xl; xx++) {
1845
- cell = lines[yi][xx]
1846
- if (!cell) {
1847
- break
1848
- }
1849
- if (override || attr !== cell[0] || ch !== cell[1]) {
1850
- lines[yi][xx][0] = attr
1851
- lines[yi][xx][1] = ch
1852
- lines[yi].dirty = true
1853
- }
1854
- }
1855
- }
1856
- }
1857
-
1858
- Screen.prototype.key = function () {
1859
- return this.program.key.apply(this, arguments)
1860
- }
1861
-
1862
- Screen.prototype.onceKey = function () {
1863
- return this.program.onceKey.apply(this, arguments)
1864
- }
1865
-
1866
- Screen.prototype.unkey = Screen.prototype.removeKey = function () {
1867
- return this.program.unkey.apply(this, arguments)
1868
- }
1869
-
1870
- Screen.prototype.spawn = function (file, args, options) {
1871
- if (!Array.isArray(args)) {
1872
- options = args
1873
- args = []
1874
- }
1875
-
1876
- let screen = this,
1877
- program = screen.program,
1878
- spawn = require('node:child_process').spawn,
1879
- mouse = program.mouseEnabled,
1880
- ps
1881
-
1882
- options = options || {}
1883
-
1884
- options.stdio = options.stdio || 'inherit'
1885
-
1886
- program.lsaveCursor('spawn')
1887
- // program.csr(0, program.rows - 1);
1888
- program.normalBuffer()
1889
- program.showCursor()
1890
- if (mouse) {
1891
- program.disableMouse()
1892
- }
1893
-
1894
- const write = program.output.write
1895
- program.output.write = function () {}
1896
- program.input.pause()
1897
- if (program.input.setRawMode) {
1898
- program.input.setRawMode(false)
1899
- }
1900
-
1901
- const resume = function () {
1902
- if (resume.done) {
1903
- return
1904
- }
1905
- resume.done = true
1906
-
1907
- if (program.input.setRawMode) {
1908
- program.input.setRawMode(true)
1909
- }
1910
- program.input.resume()
1911
- program.output.write = write
1912
-
1913
- program.alternateBuffer()
1914
- // program.csr(0, program.rows - 1);
1915
- if (mouse) {
1916
- program.enableMouse()
1917
- if (screen.options.sendFocus) {
1918
- screen.program.setMouse({ sendFocus: true }, true)
1919
- }
1920
- }
1921
-
1922
- screen.alloc()
1923
- screen.render()
1924
-
1925
- screen.program.lrestoreCursor('spawn', true)
1926
- }
1927
-
1928
- ps = spawn(file, args, options)
1929
-
1930
- ps.on('error', resume)
1931
-
1932
- ps.on('exit', resume)
1933
-
1934
- return ps
1935
- }
1936
-
1937
- Screen.prototype.exec = function (file, args, options, callback) {
1938
- const ps = this.spawn(file, args, options)
1939
-
1940
- ps.on('error', function (err) {
1941
- if (!callback) {
1942
- return
1943
- }
1944
- return callback(err, false)
1945
- })
1946
-
1947
- ps.on('exit', function (code) {
1948
- if (!callback) {
1949
- return
1950
- }
1951
- return callback(null, code === 0)
1952
- })
1953
-
1954
- return ps
1955
- }
1956
-
1957
- Screen.prototype.readEditor = function (options, callback) {
1958
- if (typeof options === 'string') {
1959
- options = { editor: options }
1960
- }
1961
-
1962
- if (!callback) {
1963
- callback = options
1964
- options = null
1965
- }
1966
-
1967
- if (!callback) {
1968
- callback = function () {}
1969
- }
1970
-
1971
- options = options || {}
1972
-
1973
- let self = this,
1974
- editor = options.editor || process.env.EDITOR || 'vi',
1975
- name = options.name || process.title || 'blessed',
1976
- rnd = Math.random().toString(36).split('.').pop(),
1977
- file = '/tmp/' + name + '.' + rnd,
1978
- args = [file],
1979
- opt
1980
-
1981
- opt = {
1982
- stdio: 'inherit',
1983
- env: process.env,
1984
- cwd: process.env.HOME
1985
- }
1986
-
1987
- function writeFile(callback) {
1988
- if (!options.value) {
1989
- return callback()
1990
- }
1991
- return fs.writeFile(file, options.value, callback)
1992
- }
1993
-
1994
- return writeFile(function (err) {
1995
- if (err) {
1996
- return callback(err)
1997
- }
1998
- return self.exec(editor, args, opt, function (err, success) {
1999
- if (err) {
2000
- return callback(err)
2001
- }
2002
- return fs.readFile(file, 'utf8', function (err, data) {
2003
- return fs.unlink(file, function () {
2004
- if (!success) {
2005
- return callback(new Error('Unsuccessful.'))
2006
- }
2007
- if (err) {
2008
- return callback(err)
2009
- }
2010
- return callback(null, data)
2011
- })
2012
- })
2013
- })
2014
- })
2015
- }
2016
-
2017
- Screen.prototype.displayImage = function (file, callback) {
2018
- if (!file) {
2019
- if (!callback) {
2020
- return
2021
- }
2022
- return callback(new Error('No image.'))
2023
- }
2024
-
2025
- file = path.resolve(process.cwd(), file)
2026
-
2027
- if (!~file.indexOf('://')) {
2028
- file = 'file://' + file
2029
- }
2030
-
2031
- const args = ['w3m', '-T', 'text/html']
2032
-
2033
- const input =
2034
- '<title>press q to exit</title>' + '<img align="center" src="' + file + '">'
2035
-
2036
- const opt = {
2037
- stdio: ['pipe', 1, 2],
2038
- env: process.env,
2039
- cwd: process.env.HOME
2040
- }
2041
-
2042
- const ps = this.spawn(args[0], args.slice(1), opt)
2043
-
2044
- ps.on('error', function (err) {
2045
- if (!callback) {
2046
- return
2047
- }
2048
- return callback(err)
2049
- })
2050
-
2051
- ps.on('exit', function (code) {
2052
- if (!callback) {
2053
- return
2054
- }
2055
- if (code !== 0) {
2056
- return callback(new Error('Exit Code: ' + code))
2057
- }
2058
- return callback(null, code === 0)
2059
- })
2060
-
2061
- ps.stdin.write(input + '\n')
2062
- ps.stdin.end()
2063
- }
2064
-
2065
- Screen.prototype.setEffects = function (el, fel, over, out, effects, temp) {
2066
- if (!effects) {
2067
- return
2068
- }
2069
-
2070
- const tmp = {}
2071
- if (temp) {
2072
- el[temp] = tmp
2073
- }
2074
-
2075
- if (typeof el !== 'function') {
2076
- const _el = el
2077
- el = function () {
2078
- return _el
2079
- }
2080
- }
2081
-
2082
- fel.on(over, function () {
2083
- const element = el()
2084
- Object.keys(effects).forEach(function (key) {
2085
- const val = effects[key]
2086
- if (val !== null && typeof val === 'object') {
2087
- tmp[key] = tmp[key] || {}
2088
- // element.style[key] = element.style[key] || {};
2089
- Object.keys(val).forEach(function (k) {
2090
- const v = val[k]
2091
- tmp[key][k] = element.style[key][k]
2092
- element.style[key][k] = v
2093
- })
2094
- return
2095
- }
2096
- tmp[key] = element.style[key]
2097
- element.style[key] = val
2098
- })
2099
- element.screen.render()
2100
- })
2101
-
2102
- fel.on(out, function () {
2103
- const element = el()
2104
- Object.keys(effects).forEach(function (key) {
2105
- const val = effects[key]
2106
- if (val !== null && typeof val === 'object') {
2107
- tmp[key] = tmp[key] || {}
2108
- // element.style[key] = element.style[key] || {};
2109
- Object.keys(val).forEach(function (k) {
2110
- if (tmp[key].hasOwnProperty(k)) {
2111
- element.style[key][k] = tmp[key][k]
2112
- }
2113
- })
2114
- return
2115
- }
2116
- if (tmp.hasOwnProperty(key)) {
2117
- element.style[key] = tmp[key]
2118
- }
2119
- })
2120
- element.screen.render()
2121
- })
2122
- }
2123
-
2124
- Screen.prototype.sigtstp = function (callback) {
2125
- const self = this
2126
- this.program.sigtstp(function () {
2127
- self.alloc()
2128
- self.render()
2129
- self.program.lrestoreCursor('pause', true)
2130
- if (callback) {
2131
- callback()
2132
- }
2133
- })
2134
- }
2135
-
2136
- Screen.prototype.copyToClipboard = function (text) {
2137
- return this.program.copyToClipboard(text)
2138
- }
2139
-
2140
- Screen.prototype.cursorShape = function (shape, blink) {
2141
- const self = this
2142
-
2143
- this.cursor.shape = shape || 'block'
2144
- this.cursor.blink = blink || false
2145
- this.cursor._set = true
2146
-
2147
- if (this.cursor.artificial) {
2148
- if (!this.program.hideCursor_old) {
2149
- const hideCursor = this.program.hideCursor
2150
- this.program.hideCursor_old = this.program.hideCursor
2151
- this.program.hideCursor = function () {
2152
- hideCursor.call(self.program)
2153
- self.cursor._hidden = true
2154
- if (self.renders) {
2155
- self.render()
2156
- }
2157
- }
2158
- }
2159
- if (!this.program.showCursor_old) {
2160
- const showCursor = this.program.showCursor
2161
- this.program.showCursor_old = this.program.showCursor
2162
- this.program.showCursor = function () {
2163
- self.cursor._hidden = false
2164
- if (self.program._exiting) {
2165
- showCursor.call(self.program)
2166
- }
2167
- if (self.renders) {
2168
- self.render()
2169
- }
2170
- }
2171
- }
2172
- if (!this._cursorBlink) {
2173
- this._cursorBlink = setInterval(function () {
2174
- if (!self.cursor.blink) {
2175
- return
2176
- }
2177
- self.cursor._state ^= 1
2178
- if (self.renders) {
2179
- self.render()
2180
- }
2181
- }, 500)
2182
- if (this._cursorBlink.unref) {
2183
- this._cursorBlink.unref()
2184
- }
2185
- }
2186
- return true
2187
- }
2188
-
2189
- return this.program.cursorShape(this.cursor.shape, this.cursor.blink)
2190
- }
2191
-
2192
- Screen.prototype.cursorColor = function (color) {
2193
- this.cursor.color = color != null ? colors.convert(color) : null
2194
- this.cursor._set = true
2195
-
2196
- if (this.cursor.artificial) {
2197
- return true
2198
- }
2199
-
2200
- return this.program.cursorColor(colors.ncolors[this.cursor.color])
2201
- }
2202
-
2203
- Screen.prototype.cursorReset = Screen.prototype.resetCursor = function () {
2204
- this.cursor.shape = 'block'
2205
- this.cursor.blink = false
2206
- this.cursor.color = null
2207
- this.cursor._set = false
2208
-
2209
- if (this.cursor.artificial) {
2210
- this.cursor.artificial = false
2211
- if (this.program.hideCursor_old) {
2212
- this.program.hideCursor = this.program.hideCursor_old
2213
- delete this.program.hideCursor_old
2214
- }
2215
- if (this.program.showCursor_old) {
2216
- this.program.showCursor = this.program.showCursor_old
2217
- delete this.program.showCursor_old
2218
- }
2219
- if (this._cursorBlink) {
2220
- clearInterval(this._cursorBlink)
2221
- delete this._cursorBlink
2222
- }
2223
- return true
2224
- }
2225
-
2226
- return this.program.cursorReset()
2227
- }
2228
-
2229
- Screen.prototype._cursorAttr = function (cursor, dattr) {
2230
- let attr = dattr || this.dattr,
2231
- cattr,
2232
- ch
2233
-
2234
- if (cursor.shape === 'line') {
2235
- attr &= ~(0x1ff << 9)
2236
- attr |= 7 << 9
2237
- ch = '\u2502'
2238
- } else if (cursor.shape === 'underline') {
2239
- attr &= ~(0x1ff << 9)
2240
- attr |= 7 << 9
2241
- attr |= 2 << 18
2242
- } else if (cursor.shape === 'block') {
2243
- attr &= ~(0x1ff << 9)
2244
- attr |= 7 << 9
2245
- attr |= 8 << 18
2246
- } else if (typeof cursor.shape === 'object' && cursor.shape) {
2247
- const Element = require('./element')
2248
- cattr = Element.prototype.sattr.call(cursor, cursor.shape)
2249
-
2250
- if (
2251
- cursor.shape.bold ||
2252
- cursor.shape.underline ||
2253
- cursor.shape.blink ||
2254
- cursor.shape.inverse ||
2255
- cursor.shape.invisible
2256
- ) {
2257
- attr &= ~(0x1ff << 18)
2258
- attr |= ((cattr >> 18) & 0x1ff) << 18
2259
- }
2260
-
2261
- if (cursor.shape.fg) {
2262
- attr &= ~(0x1ff << 9)
2263
- attr |= ((cattr >> 9) & 0x1ff) << 9
2264
- }
2265
-
2266
- if (cursor.shape.bg) {
2267
- attr &= ~(0x1ff << 0)
2268
- attr |= cattr & 0x1ff
2269
- }
2270
-
2271
- if (cursor.shape.ch) {
2272
- ch = cursor.shape.ch
2273
- }
2274
- }
2275
-
2276
- if (cursor.color != null) {
2277
- attr &= ~(0x1ff << 9)
2278
- attr |= cursor.color << 9
2279
- }
2280
-
2281
- return {
2282
- ch: ch,
2283
- attr: attr
2284
- }
2285
- }
2286
-
2287
- Screen.prototype.screenshot = function (xi, xl, yi, yl, term) {
2288
- if (xi == null) {
2289
- xi = 0
2290
- }
2291
- if (xl == null) {
2292
- xl = this.cols
2293
- }
2294
- if (yi == null) {
2295
- yi = 0
2296
- }
2297
- if (yl == null) {
2298
- yl = this.rows
2299
- }
2300
-
2301
- if (xi < 0) {
2302
- xi = 0
2303
- }
2304
- if (yi < 0) {
2305
- yi = 0
2306
- }
2307
-
2308
- let x, y, line, out, ch, data, attr
2309
-
2310
- const sdattr = this.dattr
2311
-
2312
- if (term) {
2313
- this.dattr = term.defAttr
2314
- }
2315
-
2316
- let main = ''
2317
-
2318
- for (y = yi; y < yl; y++) {
2319
- line = term ? term.lines[y] : this.lines[y]
2320
-
2321
- if (!line) {
2322
- break
2323
- }
2324
-
2325
- out = ''
2326
- attr = this.dattr
2327
-
2328
- for (x = xi; x < xl; x++) {
2329
- if (!line[x]) {
2330
- break
2331
- }
2332
-
2333
- data = line[x][0]
2334
- ch = line[x][1]
2335
-
2336
- if (data !== attr) {
2337
- if (attr !== this.dattr) {
2338
- out += '\x1b[m'
2339
- }
2340
- if (data !== this.dattr) {
2341
- let _data = data
2342
- if (term) {
2343
- if (((_data >> 9) & 0x1ff) === 257) {
2344
- _data |= 0x1ff << 9
2345
- }
2346
- if ((_data & 0x1ff) === 256) {
2347
- _data |= 0x1ff
2348
- }
2349
- }
2350
- out += this.codeAttr(_data)
2351
- }
2352
- }
2353
-
2354
- if (this.fullUnicode) {
2355
- if (unicode.charWidth(line[x][1]) === 2) {
2356
- if (x === xl - 1) {
2357
- ch = ' '
2358
- } else {
2359
- x++
2360
- }
2361
- }
2362
- }
2363
-
2364
- out += ch
2365
- attr = data
2366
- }
2367
-
2368
- if (attr !== this.dattr) {
2369
- out += '\x1b[m'
2370
- }
2371
-
2372
- if (out) {
2373
- main += (y > 0 ? '\n' : '') + out
2374
- }
2375
- }
2376
-
2377
- main = main.replace(/(?:\s*\x1b\[40m\s*\x1b\[m\s*)*$/, '') + '\n'
2378
-
2379
- if (term) {
2380
- this.dattr = sdattr
2381
- }
2382
-
2383
- return main
2384
- }
2385
-
2386
- /**
2387
- * Positioning
2388
- */
2389
-
2390
- Screen.prototype._getPos = function () {
2391
- return this
2392
- }
2393
-
2394
- /**
2395
- * Angle Table
2396
- */
2397
-
2398
- const angles = {
2399
- '\u2518': true, // '┘'
2400
- '\u2510': true, // '┐'
2401
- '\u250c': true, // '┌'
2402
- '\u2514': true, // '└'
2403
- '\u253c': true, // '┼'
2404
- '\u251c': true, // '├'
2405
- '\u2524': true, // '┤'
2406
- '\u2534': true, // '┴'
2407
- '\u252c': true, // '┬'
2408
- '\u2502': true, // '│'
2409
- '\u2500': true // '─'
2410
- }
2411
-
2412
- const langles = {
2413
- '\u250c': true, // '┌'
2414
- '\u2514': true, // '└'
2415
- '\u253c': true, // '┼'
2416
- '\u251c': true, // '├'
2417
- '\u2534': true, // '┴'
2418
- '\u252c': true, // '┬'
2419
- '\u2500': true // '─'
2420
- }
2421
-
2422
- const uangles = {
2423
- '\u2510': true, // '┐'
2424
- '\u250c': true, // '┌'
2425
- '\u253c': true, // '┼'
2426
- '\u251c': true, // '├'
2427
- '\u2524': true, // '┤'
2428
- '\u252c': true, // '┬'
2429
- '\u2502': true // '│'
2430
- }
2431
-
2432
- const rangles = {
2433
- '\u2518': true, // '┘'
2434
- '\u2510': true, // '┐'
2435
- '\u253c': true, // '┼'
2436
- '\u2524': true, // '┤'
2437
- '\u2534': true, // '┴'
2438
- '\u252c': true, // '┬'
2439
- '\u2500': true // '─'
2440
- }
2441
-
2442
- const dangles = {
2443
- '\u2518': true, // '┘'
2444
- '\u2514': true, // '└'
2445
- '\u253c': true, // '┼'
2446
- '\u251c': true, // '├'
2447
- '\u2524': true, // '┤'
2448
- '\u2534': true, // '┴'
2449
- '\u2502': true // '│'
2450
- }
2451
-
2452
- // var cdangles = {
2453
- // '\u250c': true // '┌'
2454
- // };
2455
-
2456
- // Every ACS angle character can be
2457
- // represented by 4 bits ordered like this:
2458
- // [langle][uangle][rangle][dangle]
2459
- const angleTable = {
2460
- '0000': '', // ?
2461
- '0001': '\u2502', // '│' // ?
2462
- '0010': '\u2500', // '─' // ??
2463
- '0011': '\u250c', // '┌'
2464
- '0100': '\u2502', // '│' // ?
2465
- '0101': '\u2502', // '│'
2466
- '0110': '\u2514', // '└'
2467
- '0111': '\u251c', // '├'
2468
- 1000: '\u2500', // '─' // ??
2469
- 1001: '\u2510', // '┐'
2470
- 1010: '\u2500', // '─' // ??
2471
- 1011: '\u252c', // '┬'
2472
- 1100: '\u2518', // '┘'
2473
- 1101: '\u2524', // '┤'
2474
- 1110: '\u2534', // '┴'
2475
- 1111: '\u253c' // '┼'
2476
- }
2477
-
2478
- Object.keys(angleTable).forEach(function (key) {
2479
- angleTable[parseInt(key, 2)] = angleTable[key]
2480
- delete angleTable[key]
2481
- })
2482
-
2483
- /**
2484
- * Expose
2485
- */
2486
-
2487
- module.exports = Screen