-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathutils.js
More file actions
59 lines (52 loc) · 1.92 KB
/
Copy pathutils.js
File metadata and controls
59 lines (52 loc) · 1.92 KB
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
// ── Terminal & Input Utilities ───────────────────────────────
import { EventEmitter } from 'events';
import readline from 'readline';
// Input bus
export const keys = new EventEmitter();
keys.setMaxListeners(30);
readline.emitKeypressEvents(process.stdin);
if (process.stdin.isTTY) process.stdin.setRawMode(true);
process.stdin.on('keypress', (str, key) => keys.emit('key', str, key));
export const waitKey = () =>
new Promise(r => keys.once('key', (str, key) => r({ str, key })));
export const sleep = ms => new Promise(r => setTimeout(r, ms));
// Terminal control
export const cls = () => process.stdout.write('\x1B[2J\x1B[H');
export const hideCur = () => process.stdout.write('\x1B[?25l');
export const showCur = () => process.stdout.write('\x1B[?25h');
export const write = s => process.stdout.write(s);
// Visual width (emoji = 2, ASCII = 1)
function vw(s) {
const clean = s.replace(/\x1B\[[0-9;]*m/g, '');
let w = 0;
for (const c of clean) {
const cp = c.codePointAt(0);
w += (cp > 0x2E80 || (cp >= 0x2600 && cp <= 0x27BF) || (cp >= 0x1F000 && cp <= 0x1FFFF)) ? 2 : 1;
}
return w;
}
// Box drawing (W=60 inner)
export const BW = 60;
export function box(title, rows) {
const border = '═'.repeat(BW + 2);
const div = `╠${border}╣`;
const pad = Math.max(0, BW - vw(title));
const lp = Math.floor(pad / 2);
const rp = pad - lp;
const out = [
`╔${border}╗`,
`║${' '.repeat(lp + 1)}${title}${' '.repeat(rp + 1)}║`,
div,
];
for (const r of rows) {
if (r === '---') { out.push(div); continue; }
const p = Math.max(0, BW - vw(r));
out.push(`║ ${r}${' '.repeat(p)} ║`);
}
out.push(`╚${border}╝`);
return out.join('\n');
}
export function progressBar(pct, width = 20) {
const fill = Math.round(pct / 100 * width);
return '█'.repeat(fill) + '░'.repeat(width - fill);
}