Voice / vlib /ui.py
Wiself's picture
small tiny fixes
271bd15
Raw History Blame Contribute Delete
2.16 kB
"""Terminal output, prompts, and formatting."""
import os
import sys
_PLAIN_MAP = {"βœ“": "[OK]", "βœ—": "[ERR]", "⚠": "[WARN]", "β†’": ">", "↳": "->", "Β·": "-", "…": "...", "─": "-", "β€”": "-", "←": "<-", "↔": "<->"}
def _plain():
return os.environ.get("VOICE_PLAIN") == "1"
def _transform(msg):
if not _plain():
return msg
for k, v in _PLAIN_MAP.items():
msg = msg.replace(k, v)
return msg
def _now_iso():
from datetime import datetime, timezone
return datetime.now(timezone.utc).isoformat()
def _say(msg):
print(_transform(msg), flush=True)
def _quiet():
try:
from vlib import ctx as _ctx
return bool(getattr(_ctx, "QUIET", False))
except Exception:
return False
def _ok(msg):
if _quiet():
return
_say(f" βœ“ {msg}")
def _warn(msg):
_say(f" ⚠ {msg}")
def _step(msg):
if _quiet():
return
_say(f" β†’ {msg}")
def _note(msg):
if _quiet():
return
_say(f" ↳ {msg}")
def _fail(msg):
sys.stdout.flush()
msg = str(msg).lstrip()
if msg.startswith("βœ—"):
msg = msg[1:].lstrip()
_say(f" βœ— {msg}")
sys.exit(1)
def _noninteractive(args):
if getattr(args, "non_interactive", False) or getattr(args, "yes", False):
return True
try:
return not sys.stdin.isatty()
except Exception:
return True
def _progress_pref():
if _plain() or os.environ.get("REDUCE_MOTION") == "1":
return True
try:
return not sys.stdout.isatty()
except Exception:
return True
def _confirm(question, args):
if getattr(args, "yes", False):
return True
if _noninteractive(args):
return False
try:
ans = input(question).strip().lower()
except (EOFError, KeyboardInterrupt):
_say(" ⚠ Cancelled.")
sys.exit(1)
return ans in ("y", "yes")
def _trunc(s, w):
s = str(s)
return s[: w - 1] + "…" if len(s) > w else s
def _term_width():
try:
import shutil
return shutil.get_terminal_size().columns
except Exception:
return 80