🌳
pt0/deployF/libF/promptSyncF.mts
1import fs from 'fs'
2import stripAnsi from 'strip-ansi'
6var term = 13
8function create(config?: any) {
9 config = config || {}
10 var sigint = config.sigint
11 var eot = config.eot
12 var autocomplete = config.autocomplete =
13 config.autocomplete || function(){return []}
14 var history = config.history
15 prompt.history = history || {save: function(){}}
16 prompt.hide = function (ask: any) { return prompt(ask, undefined, {echo: ''}) }
18 return prompt
20 function prompt(ask?: any, value?: any, opts?: any) {
21 var insert = 0, savedinsert = 0, res, i, savedstr
22 opts = opts || {}
24 if (Object(ask) === ask) {
25 opts = ask
26 ask = opts.ask
27 } else if (Object(value) === value) {
28 opts = value
29 value = opts.value
30 }
31 ask = ask || ''
32 var echo = opts.echo
33 var masked = 'echo' in opts
34 autocomplete = opts.autocomplete || autocomplete
36 var fd = (process.platform === 'win32') ?
37 process.stdin.fd :
38 fs.openSync('/dev/tty', 'rs')
40 var wasRaw = process.stdin.isRaw
41 if (!wasRaw) { process.stdin.setRawMode && process.stdin.setRawMode(true) }
43 var buf = Buffer.alloc(3)
44 var str = '', character, read
46 savedstr = ''
48 if (ask) {
49 process.stdout.write(ask)
50 }
52 var cycle = 0
53 var prevComplete
54 var prevLines = 1
56 while (true) {
57 read = fs.readSync(fd as number, buf, 0, 3, null)
58 if (read > 1) {
59 switch(buf.toString()) {
60 case '\u001b[A':
61 if (masked) break
62 if (!history) break
63 if (history.atStart()) break
65 if (history.atEnd()) {
66 savedstr = str
67 savedinsert = insert
68 }
69 str = history.prev()
70 insert = str.length
71 process.stdout.write('\u001b[2K\u001b[0G' + ask + str)
72 break
73 case '\u001b[B':
74 if (masked) break
75 if (!history) break
76 if (history.pastEnd()) break
78 if (history.atPenultimate()) {
79 str = savedstr
80 insert = savedinsert
81 history.next()
82 } else {
83 str = history.next()
84 insert = str.length
85 }
86 process.stdout.write('\u001b[2K\u001b[0G'+ ask + str + '\u001b['+(insert+ask.length+1)+'G')
87 break
88 case '\u001b[D':
89 if (masked) break
90 var before = insert
91 insert = (--insert < 0) ? 0 : insert
92 if (before - insert)
93 process.stdout.write('\u001b[1D')
94 break
95 case '\u001b[C':
96 if (masked) break
97 insert = (++insert > str.length) ? str.length : insert
98 process.stdout.write('\u001b[' + (insert+ask.length+1) + 'G')
99 break
100 default:
101 if (buf.toString()) {
102 str = str + buf.toString()
103 str = str.replace(/\0/g, '')
104 insert = str.length
105 promptPrint(masked, ask, echo, str, insert, prevLines)
106 prevLines = Math.ceil((stripAnsi(ask).length + str.length) / (process.stdout.columns || 80)) || 1
107 process.stdout.write('\u001b[' + (insert+ask.length+1) + 'G')
108 buf = Buffer.alloc(3)
109 }
110 }
111 continue
112 }
114 character = buf[read-1]
116 if (character == 3){
117 process.stdout.write('^C\n')
118 fs.closeSync(fd)
120 if (sigint) process.exit(130)
122 process.stdin.setRawMode && process.stdin.setRawMode(wasRaw)
124 process.exit(130)
125 }
127 if (character == 4) {
128 if (str.length == 0 && eot) {
129 process.stdout.write('exit\n')
130 process.exit(0)
131 }
132 }
134 if (character == term) {
135 fs.closeSync(fd)
136 if (!history) break
137 if (!masked && str.length) history.push(str)
138 history.reset()
139 break
140 }
142 if (character == 9) {
143 res = autocomplete(str)
145 if (str == res[0]) {
146 res = autocomplete('')
147 } else {
148 prevComplete = res.length
149 }
151 if (res.length == 0) {
152 process.stdout.write('\t')
153 continue
154 }
156 var item = res[cycle++] || res[cycle = 0, cycle++]
158 if (item) {
159 process.stdout.write('\r\u001b[K' + ask + item)
160 str = item
161 insert = item.length
162 }
163 }
165 if (character == 127 || (process.platform == 'win32' && character == 8)) {
166 if (!insert) continue
167 str = str.slice(0, insert-1) + str.slice(insert)
168 insert--
169 process.stdout.write('\u001b[2D')
170 } else {
171 if ((character < 32 ) || (character > 126))
172 continue
173 str = str.slice(0, insert) + String.fromCharCode(character) + str.slice(insert)
174 insert++
175 }
177 promptPrint(masked, ask, echo, str, insert, prevLines)
178 prevLines = Math.ceil((stripAnsi(ask).length + str.length) / (process.stdout.columns || 80)) || 1
180 }
182 process.stdout.write('\n')
184 process.stdin.setRawMode && process.stdin.setRawMode(wasRaw)
186 return str || value || ''
187 }
190 function promptPrint(masked: any, ask: any, echo: any, str: any, insert: any, prevLines: any) {
191 if (masked) {
192 process.stdout.write('\u001b[2K\u001b[0G' + ask + Array(str.length+1).join(echo))
193 } else {
194 process.stdout.write('\r')
196 if (prevLines > 1) {
197 process.stdout.write(`\u001b[${prevLines - 1}A`)
198 }
200 process.stdout.write('\u001b[0J')
202 process.stdout.write(ask + str)
204 var askLength = stripAnsi(ask).length
205 var totalLength = askLength + insert
206 var termWidth = process.stdout.columns || 80
207 var targetRow = Math.floor(totalLength / termWidth)
208 var targetCol = totalLength % termWidth
210 var currentRow = Math.floor((askLength + str.length) / termWidth)
212 if (currentRow > targetRow) {
213 process.stdout.write(`\u001b[${currentRow - targetRow}A`)
214 }
216 process.stdout.write(`\r\u001b[${targetCol}C`)
217 }
218 }
221export const promptSync = create()
223if (isDirectlyRun(import.meta.url)) {
224 const answerS = promptSync(`pls type your debug info: `)
225 betLog({answerS})