@make-u-free/migi 0.4.3 → 0.4.5
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 +32 -32
- package/package.json +1 -1
package/bin/migi.js
CHANGED
|
@@ -86,47 +86,47 @@ async function readChatInput() {
|
|
|
86
86
|
const lines = ['']
|
|
87
87
|
let curLine = 0
|
|
88
88
|
let drawnLines = 0
|
|
89
|
-
let
|
|
90
|
-
let cursorLine = 0 // カーソルが実際にいる物理行(drawn area 先頭からの offset)
|
|
89
|
+
let cursorLine = 0 // カーソルの物理行(drawn area 先頭からの offset)
|
|
91
90
|
|
|
92
91
|
emitKeypressEvents(process.stdin)
|
|
93
92
|
if (process.stdin.isTTY) process.stdin.setRawMode(true)
|
|
94
93
|
|
|
95
94
|
function draw() {
|
|
96
95
|
const w = process.stdout.columns || 80
|
|
97
|
-
|
|
98
|
-
// 行数が変わっていない(通常の文字入力)→ 現在行だけ上書き。セパレーター・ガイドは触らない
|
|
99
|
-
if (lines.length === lastLineCount && drawnLines > 0) {
|
|
100
|
-
const prefix = curLine === 0 ? PFIRST : PCONT
|
|
101
|
-
process.stdout.write('\r\x1b[K' + chalk.cyan(prefix) + lines[curLine])
|
|
102
|
-
cursorLine = curLine
|
|
103
|
-
return
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
// 行数変化 or 初回 → 全体を再描画
|
|
107
|
-
lastLineCount = lines.length
|
|
108
|
-
const allLines = [
|
|
96
|
+
const newLines = [
|
|
109
97
|
...lines.map((l, i) => chalk.cyan(i === 0 ? PFIRST : PCONT) + l),
|
|
110
|
-
chalk.dim('─'.repeat(w)),
|
|
111
|
-
chalk.dim(` ✦ ${model} ·
|
|
98
|
+
chalk.dim('─'.repeat(w - 1)), // w-1: 行末での自動折り返し防止
|
|
99
|
+
chalk.dim(` ✦ ${model} · Alt+Enterで改行 / Enterで送信`)
|
|
112
100
|
]
|
|
101
|
+
const oldDrawnLines = drawnLines
|
|
102
|
+
drawnLines = newLines.length
|
|
113
103
|
|
|
114
104
|
let buf = ''
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
105
|
+
|
|
106
|
+
// ① drawn area 先頭まで戻る(cursorLine = カーソルが今いる物理行)
|
|
107
|
+
if (cursorLine > 0) buf += `\x1b[${cursorLine}A`
|
|
108
|
+
buf += '\r'
|
|
109
|
+
|
|
110
|
+
// ② 各行を上書き。「先クリア→描画」ではなく「描画→行末クリア」でちらつき防止
|
|
111
|
+
for (let i = 0; i < newLines.length; i++) {
|
|
112
|
+
buf += newLines[i] + '\x1b[K'
|
|
113
|
+
if (i < newLines.length - 1) buf += '\r\n'
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// ③ 行数が減った場合、余分な古い行をクリア
|
|
117
|
+
for (let i = newLines.length; i < oldDrawnLines; i++) {
|
|
118
|
+
buf += '\r\n\x1b[2K'
|
|
121
119
|
}
|
|
122
120
|
|
|
123
|
-
|
|
124
|
-
|
|
121
|
+
// ④ curLine の行まで戻る
|
|
122
|
+
// step②+③後のカーソル位置は max(新行数, 旧行数)-1 行目
|
|
123
|
+
const linesFromBottom = Math.max(drawnLines, oldDrawnLines) - 1 - curLine
|
|
124
|
+
if (linesFromBottom > 0) buf += `\x1b[${linesFromBottom}A`
|
|
125
|
+
buf += '\r'
|
|
125
126
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
buf += `\x1b[${col}G`
|
|
127
|
+
// ⑤ カーソルを入力内容の末尾へ
|
|
128
|
+
const prefix = curLine === 0 ? PFIRST : PCONT
|
|
129
|
+
buf += `\x1b[${prefix.length + lines[curLine].length + 1}G`
|
|
130
130
|
|
|
131
131
|
cursorLine = curLine
|
|
132
132
|
process.stdout.write(buf)
|
|
@@ -141,7 +141,7 @@ async function readChatInput() {
|
|
|
141
141
|
}
|
|
142
142
|
|
|
143
143
|
if (key.ctrl && key.name === 'c') {
|
|
144
|
-
process.stdout.write(`\x1b[${drawnLines - curLine}B\n`)
|
|
144
|
+
process.stdout.write(`\x1b[${drawnLines - 1 - curLine}B\n`)
|
|
145
145
|
process.stdin.removeListener('keypress', onKey)
|
|
146
146
|
if (process.stdin.isTTY) process.stdin.setRawMode(false)
|
|
147
147
|
console.log(chalk.cyan('\n お疲れ様でした!またね。\n'))
|
|
@@ -149,8 +149,8 @@ async function readChatInput() {
|
|
|
149
149
|
}
|
|
150
150
|
|
|
151
151
|
if (key.name === 'return') {
|
|
152
|
-
|
|
153
|
-
|
|
152
|
+
// Alt+Enter(macOS: Option+Enter)または Shift+Enter → 改行
|
|
153
|
+
if (key.meta || key.shift) {
|
|
154
154
|
lines.splice(curLine + 1, 0, '')
|
|
155
155
|
curLine++
|
|
156
156
|
draw()
|
|
@@ -158,7 +158,7 @@ async function readChatInput() {
|
|
|
158
158
|
// Enter → 送信
|
|
159
159
|
const content = lines.join('\n').trim()
|
|
160
160
|
if (!content) return
|
|
161
|
-
process.stdout.write(`\x1b[${drawnLines - curLine}B\n`)
|
|
161
|
+
process.stdout.write(`\x1b[${drawnLines - 1 - curLine}B\n`)
|
|
162
162
|
process.stdin.removeListener('keypress', onKey)
|
|
163
163
|
if (process.stdin.isTTY) process.stdin.setRawMode(false)
|
|
164
164
|
resolve(content)
|