tankslab.com/recall/source

bin/console.py

64 lines, exactly as they ship in the download.

""" console.py - print without crashing on a Windows console. WHY THIS EXISTS --------------- Windows terminals commonly run code page 437 or 1252. Printing a check mark to one does not produce an ugly character — it raises UnicodeEncodeError and kills the command. `recall search` and `recall timeline` both print status icons, so on a default Windows 10/11 console they crashed on their first result. Two defences, because either alone is not enough: 1. stdout/stderr are reconfigured to replace unencodable characters instead of raising. Nothing can crash on output after that, whatever we print later. 2. Icons fall back to ASCII when the console genuinely cannot represent them, so the output stays READABLE rather than a row of question marks. Degrading to legible is the point; not crashing is only the floor. """ from __future__ import annotations import sys UNICODE_ICONS = {"change": "✓", "discovery": "○", "verification": "✓", "operation": "⛯", "bugfix": "●", "feature": "◆", "refactor": "↻", "decision": "⚖", "security_alert": "⚠", "security_note": "⚷"} ASCII_ICONS = {"change": "+", "discovery": "?", "verification": "v", "operation": "*", "bugfix": "!", "feature": "#", "refactor": "~", "decision": "=", "security_alert": "!!", "security_note": "$"} def _harden() -> None: for stream in (sys.stdout, sys.stderr): try: stream.reconfigure(errors="replace") except Exception: pass def _can_encode(sample: str) -> bool: enc = getattr(sys.stdout, "encoding", None) or "ascii" try: sample.encode(enc) return True except Exception: return False _harden() UNICODE_OK = _can_encode("".join(UNICODE_ICONS.values())) ICONS = UNICODE_ICONS if UNICODE_OK else ASCII_ICONS def icon(kind: str) -> str: return ICONS.get(kind, "-" if not UNICODE_OK else "·") def dash() -> str: return "--" if not UNICODE_OK else "—" def rule(n: int = 40) -> str: return ("-" if not UNICODE_OK else "─") * n