import fcntl
import os
import pty
import re
import select
import struct
import sys
import termios
import time
LIGHT = {"fg": b"rgb:1a1a/1c1c/2323", "bg": b"rgb:f4f4/f5f5/fafa"}
DARK = {"fg": b"rgb:f4f4/f5f5/fafa", "bg": b"rgb:0606/0707/0c0c"}
LIGHT_SGR = b"38;2;14;116;144"
DARK_SGR = re.compile(rb"38;5;237|\x1b\[36m|;36m")
pid, master = pty.fork()
if pid == 0:
os.environ["TERM"] = "xterm-256color"
os.environ.pop("COLORFGBG", None)
os.execv(sys.argv[1], [sys.argv[1]])
fcntl.ioctl(master, termios.TIOCSWINSZ, struct.pack("HHHH", 30, 100, 0, 0))
colors = LIGHT
flip_at = time.monotonic() + 3.0
deadline = time.monotonic() + 9.0
pending = b""
phases = {"light": b"", "dark": b""}
flipped = False
def respond(chunk: bytes) -> bytes:
out = b""
while True:
m = re.search(rb"\x1b\]1([01]);\?(?:\x07|\x1b\\)|\x1b\[0?c", chunk)
if not m:
break
if m.group(0).endswith(b"c"):
out += b"\x1b[?62;22c"
else:
key = "fg" if m.group(1) == b"0" else "bg"
out += b"\x1b]1" + m.group(1) + b";" + colors[key] + b"\x1b\\"
chunk = chunk[: m.start()] + chunk[m.end() :]
if out:
os.write(master, out)
return chunk[-32:]
while time.monotonic() < deadline:
if not flipped and time.monotonic() >= flip_at:
colors = DARK
flipped = True
r, _, _ = select.select([master], [], [], 0.1)
if master in r:
try:
data = os.read(master, 65536)
except OSError:
break
if not data:
break
phases["dark" if flipped else "light"] += data
pending = respond(pending + data)
os.write(master, b"q")
time.sleep(0.5)
try:
os.kill(pid, 15)
except ProcessLookupError:
pass
ok = True
if LIGHT_SGR not in phases["light"]:
print("FAIL: light palette never rendered before the flip")
ok = False
if DARK_SGR.search(phases["light"]):
print("FAIL: dark palette rendered while background was light")
ok = False
if not DARK_SGR.search(phases["dark"]):
print("FAIL: dark palette never rendered after the flip")
ok = False
if LIGHT_SGR in phases["dark"].split(b"\x1b[2J")[-1]:
print("FAIL: last frame after flip still uses the light palette")
ok = False
print("PASS" if ok else "FAIL")
sys.exit(0 if ok else 1)