1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
|
const ansi = require('../../util/ansi')
const unic = require('../../util/unichars')
const telc = require('../../util/telchars')
const FocusElement = require('./FocusElement')
module.exports = class TextInput extends FocusElement {
// An element that the user can type in.
constructor() {
super()
this.value = ''
this.cursorIndex = 0
this.scrollChars = 0
}
drawTo(writable) {
// There should be room for the cursor so move the "right edge" left a
// single character.
const startRange = this.scrollChars
const endRange = this.scrollChars + this.w - 3
let str = this.value.slice(startRange, endRange)
writable.write(ansi.moveCursor(this.absTop, this.absLeft + 1))
writable.write(str)
// Ellipsis on left side, if there's more characters behind the visible
// area.
if (startRange > 0) {
writable.write(ansi.moveCursor(this.absTop, this.absLeft))
writable.write(unic.ELLIPSIS)
}
// Ellipsis on the right side, if there's more characters ahead of the
// visible area.
if (endRange < this.value.length) {
writable.write(ansi.moveCursor(this.absTop, this.absRight - 1))
writable.write(unic.ELLIPSIS.repeat(2))
}
this.cursorX = this.cursorIndex - this.scrollChars + 1
super.drawTo(writable)
}
keyPressed(keyBuf) {
if (keyBuf[0] === 127) {
this.value = (
this.value.slice(0, this.cursorIndex - 1) +
this.value.slice(this.cursorIndex)
)
this.cursorIndex--
this.root.cursorMoved()
} else if (keyBuf[0] === 13) {
this.emit('value', this.value)
} else if (keyBuf[0] === 0x1b && keyBuf[1] === 0x5b) {
// Keyboard navigation
if (keyBuf[2] === 0x44) {
this.cursorIndex--
this.root.cursorMoved()
} else if (keyBuf[2] === 0x43) {
this.cursorIndex++
this.root.cursorMoved()
}
} else if (telc.isEscape(keyBuf)) {
// ESC is bad and we don't want that in the text input!
return
} else {
// console.log(keyBuf, keyBuf[0], keyBuf[1], keyBuf[2])
this.value = (
this.value.slice(0, this.cursorIndex) + keyBuf.toString() +
this.value.slice(this.cursorIndex)
)
this.cursorIndex++
this.root.cursorMoved()
}
this.keepCursorInRange()
}
keepCursorInRange() {
// Keep the cursor inside or at the end of the input value.
if (this.cursorIndex < 0) {
this.cursorIndex = 0
}
if (this.cursorIndex > this.value.length) {
this.cursorIndex = this.value.length
}
// Scroll right, if the cursor is past the right edge of where text is
// displayed.
if (this.cursorIndex - this.scrollChars > this.w - 3) {
this.scrollChars++
}
// Scroll left, if the cursor is behind the left edge of where text is
// displayed.
if (this.cursorIndex - this.scrollChars < 0) {
this.scrollChars--
}
// Scroll left, if we can see past the end of the text.
if (this.scrollChars > 0 && (
this.scrollChars + this.w - 3 > this.value.length)
) {
this.scrollChars--
}
}
}
|