|
1 | 1 | """ANSI palette, block-char banner, and clack-style layout atoms (stdlib only).""" |
2 | | -import sys, os, shutil, tty, termios |
| 2 | +import sys, os, shutil |
| 3 | + |
| 4 | +_WIN = sys.platform == "win32" |
| 5 | +if _WIN: |
| 6 | + import msvcrt |
| 7 | +else: |
| 8 | + import tty, termios |
3 | 9 |
|
4 | 10 | # ── Palette ─────────────────────────────────────────────────────────────── |
5 | 11 | def _e(*c): return f"\x1b[{';'.join(map(str,c))}m" |
@@ -58,22 +64,34 @@ def outro(lines): |
58 | 64 | print(f"{MUTED}└{R}\n") |
59 | 65 |
|
60 | 66 | # ── Raw key reader ──────────────────────────────────────────────────────── |
61 | | -def _getch(): |
62 | | - fd = sys.stdin.fileno() |
63 | | - old = termios.tcgetattr(fd) |
64 | | - try: |
65 | | - tty.setraw(fd) |
66 | | - return sys.stdin.buffer.read(1).decode("utf-8", errors="replace") |
67 | | - finally: |
68 | | - termios.tcsetattr(fd, termios.TCSADRAIN, old) |
| 67 | +if _WIN: |
| 68 | + def get_key(): |
| 69 | + ch = msvcrt.getwch() |
| 70 | + if ch in ("\x00", "\xe0"): # arrow-key / function-key prefix |
| 71 | + c2 = msvcrt.getwch() |
| 72 | + return {"H": "UP", "P": "DOWN", "K": "LEFT", "M": "RIGHT"}.get(c2, "ESC") |
| 73 | + if ch in "\r\n": return "ENTER" |
| 74 | + if ch == "\x03": raise KeyboardInterrupt |
| 75 | + if ch == "\x08": return "BACKSPACE" |
| 76 | + if ch == "\x1b": return "ESC" |
| 77 | + return ch |
| 78 | +else: |
| 79 | + def _getch(): |
| 80 | + fd = sys.stdin.fileno() |
| 81 | + old = termios.tcgetattr(fd) |
| 82 | + try: |
| 83 | + tty.setraw(fd) |
| 84 | + return sys.stdin.buffer.read(1).decode("utf-8", errors="replace") |
| 85 | + finally: |
| 86 | + termios.tcsetattr(fd, termios.TCSADRAIN, old) |
69 | 87 |
|
70 | | -def get_key(): |
71 | | - ch = _getch() |
72 | | - if ch == "\x1b": |
73 | | - _getch() # consume '[' |
74 | | - c2 = _getch() |
75 | | - return {"A": "UP", "B": "DOWN", "C": "RIGHT", "D": "LEFT"}.get(c2, "ESC") |
76 | | - if ch in "\r\n": return "ENTER" |
77 | | - if ch == "\x03": raise KeyboardInterrupt |
78 | | - if ch == "\x7f": return "BACKSPACE" |
79 | | - return ch |
| 88 | + def get_key(): |
| 89 | + ch = _getch() |
| 90 | + if ch == "\x1b": |
| 91 | + _getch() # consume '[' |
| 92 | + c2 = _getch() |
| 93 | + return {"A": "UP", "B": "DOWN", "C": "RIGHT", "D": "LEFT"}.get(c2, "ESC") |
| 94 | + if ch in "\r\n": return "ENTER" |
| 95 | + if ch == "\x03": raise KeyboardInterrupt |
| 96 | + if ch == "\x7f": return "BACKSPACE" |
| 97 | + return ch |
0 commit comments