@make-u-free/migi 0.4.4 → 0.4.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/migi.js +18 -7
- package/package.json +1 -1
package/bin/migi.js
CHANGED
|
@@ -87,10 +87,18 @@ async function readChatInput() {
|
|
|
87
87
|
let curLine = 0
|
|
88
88
|
let drawnLines = 0
|
|
89
89
|
let cursorLine = 0 // カーソルの物理行(drawn area 先頭からの offset)
|
|
90
|
+
let drawPending = false
|
|
90
91
|
|
|
91
92
|
emitKeypressEvents(process.stdin)
|
|
92
93
|
if (process.stdin.isTTY) process.stdin.setRawMode(true)
|
|
93
94
|
|
|
95
|
+
// ペースト等の連続入力をまとめて1回の描画にするためのデバウンス
|
|
96
|
+
function scheduleDraw() {
|
|
97
|
+
if (drawPending) return
|
|
98
|
+
drawPending = true
|
|
99
|
+
setImmediate(() => { drawPending = false; draw() })
|
|
100
|
+
}
|
|
101
|
+
|
|
94
102
|
function draw() {
|
|
95
103
|
const w = process.stdout.columns || 80
|
|
96
104
|
const newLines = [
|
|
@@ -119,7 +127,8 @@ async function readChatInput() {
|
|
|
119
127
|
}
|
|
120
128
|
|
|
121
129
|
// ④ curLine の行まで戻る
|
|
122
|
-
|
|
130
|
+
// step②+③後のカーソル位置は max(新行数, 旧行数)-1 行目
|
|
131
|
+
const linesFromBottom = Math.max(drawnLines, oldDrawnLines) - 1 - curLine
|
|
123
132
|
if (linesFromBottom > 0) buf += `\x1b[${linesFromBottom}A`
|
|
124
133
|
buf += '\r'
|
|
125
134
|
|
|
@@ -135,11 +144,12 @@ async function readChatInput() {
|
|
|
135
144
|
|
|
136
145
|
const onKey = (str, key) => {
|
|
137
146
|
if (!key) {
|
|
138
|
-
if (str) { lines[curLine] += str;
|
|
147
|
+
if (str) { lines[curLine] += str; scheduleDraw() }
|
|
139
148
|
return
|
|
140
149
|
}
|
|
141
150
|
|
|
142
151
|
if (key.ctrl && key.name === 'c') {
|
|
152
|
+
if (drawPending) { drawPending = false; draw() } // カーソル位置を確定させてから終了
|
|
143
153
|
process.stdout.write(`\x1b[${drawnLines - 1 - curLine}B\n`)
|
|
144
154
|
process.stdin.removeListener('keypress', onKey)
|
|
145
155
|
if (process.stdin.isTTY) process.stdin.setRawMode(false)
|
|
@@ -152,9 +162,10 @@ async function readChatInput() {
|
|
|
152
162
|
if (key.meta || key.shift) {
|
|
153
163
|
lines.splice(curLine + 1, 0, '')
|
|
154
164
|
curLine++
|
|
155
|
-
|
|
165
|
+
scheduleDraw()
|
|
156
166
|
} else {
|
|
157
|
-
// Enter →
|
|
167
|
+
// Enter → 送信(保留中の描画があれば先に確定)
|
|
168
|
+
if (drawPending) { drawPending = false; draw() }
|
|
158
169
|
const content = lines.join('\n').trim()
|
|
159
170
|
if (!content) return
|
|
160
171
|
process.stdout.write(`\x1b[${drawnLines - 1 - curLine}B\n`)
|
|
@@ -168,18 +179,18 @@ async function readChatInput() {
|
|
|
168
179
|
if (key.name === 'backspace') {
|
|
169
180
|
if (lines[curLine].length > 0) {
|
|
170
181
|
lines[curLine] = lines[curLine].slice(0, -1)
|
|
171
|
-
|
|
182
|
+
scheduleDraw()
|
|
172
183
|
} else if (curLine > 0) {
|
|
173
184
|
lines.splice(curLine, 1)
|
|
174
185
|
curLine--
|
|
175
|
-
|
|
186
|
+
scheduleDraw()
|
|
176
187
|
}
|
|
177
188
|
return
|
|
178
189
|
}
|
|
179
190
|
|
|
180
191
|
if (str && !key.ctrl && !key.meta) {
|
|
181
192
|
lines[curLine] += str
|
|
182
|
-
|
|
193
|
+
scheduleDraw()
|
|
183
194
|
}
|
|
184
195
|
}
|
|
185
196
|
|