Copy-mode with scrollback search + config hot-reload
- alt+c enters copy-mode on the focused terminal: arrows/PgUp/PgDn/ Home/End scroll the history, / searches (matches highlighted in the view), n/N jump between hits, q/Esc exits back to the bottom. Status line shows position and key help - config.toml, panel files and the theme file are watched (1s mtime poll): edits reload theme/panels/keybinds live without restarting — windows and focus are untouched - Integration suite runs the daemon in an isolated config dir and covers copy-mode search and panel hot-reload — 27/27 passing Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -21,6 +21,7 @@ Miljö: TUI_WM_BIN (default target/debug/tui-wm)
|
||||
|
||||
import json
|
||||
import os
|
||||
import shutil
|
||||
import re
|
||||
import socket
|
||||
import struct
|
||||
@@ -116,8 +117,20 @@ def main():
|
||||
env = dict(os.environ, XDG_RUNTIME_DIR=tmp)
|
||||
sock_path = os.path.join(tmp, "tui-wm.sock")
|
||||
|
||||
# Egen konfig-katalog så testerna (t.ex. hot-reload) kan skriva i
|
||||
# konfigfiler utan att röra repot.
|
||||
cfgdir = os.path.join(tmp, "cfg")
|
||||
os.makedirs(cfgdir)
|
||||
shutil.copy(os.path.join(REPO, "config.toml"), cfgdir)
|
||||
shutil.copytree(os.path.join(REPO, "panels"), os.path.join(cfgdir, "panels"))
|
||||
shutil.copytree(os.path.join(REPO, "themes"), os.path.join(cfgdir, "themes"))
|
||||
# bakgrundsbilden finns inte i test-miljön — ta bort raden
|
||||
cfg = open(os.path.join(cfgdir, "config.toml")).read()
|
||||
cfg = "\n".join(l for l in cfg.splitlines() if not l.startswith("background_image"))
|
||||
open(os.path.join(cfgdir, "config.toml"), "w").write(cfg)
|
||||
|
||||
daemon = subprocess.Popen(
|
||||
[TUI_WM_BIN, "-d"], cwd=REPO, env=env,
|
||||
[TUI_WM_BIN, "-d"], cwd=cfgdir, env=env,
|
||||
stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL,
|
||||
)
|
||||
try:
|
||||
@@ -306,6 +319,35 @@ def main():
|
||||
f"geometri: {maxed}")
|
||||
app.send({"type": "close_window", "window_id": sw_open["id"]})
|
||||
|
||||
# ── 4f. Copy-mode: alt+c, sök, avsluta ───────────────────────────
|
||||
app.send({"type": "spawn_window", "command": "seq 1 200; exec cat",
|
||||
"request_id": "w-copy"})
|
||||
cm_open = app.recv_until("window_opened")
|
||||
disp.frame_text(timeout=5.0, contains="200")
|
||||
disp.send(key_event(ch="c", modifiers="ALT"))
|
||||
text = disp.frame_text(timeout=5.0, contains="KOPIERA")
|
||||
check("alt+c öppnar copy-mode", "KOPIERA" in text)
|
||||
# sök efter rad 42
|
||||
disp.send(key_event(ch="/"))
|
||||
for ch in "42\n":
|
||||
if ch == "\n":
|
||||
disp.send(key_event(code="Enter"))
|
||||
else:
|
||||
disp.send(key_event(ch=ch))
|
||||
text = disp.frame_text(timeout=5.0, contains="42")
|
||||
check("copy-mode-sökning hittar träffen", "42" in text)
|
||||
disp.send(key_event(ch="q"))
|
||||
text = disp.frame_text(timeout=5.0, contains="200")
|
||||
check("q lämnar copy-mode och hoppar till botten", "200" in text)
|
||||
app.send({"type": "close_window", "window_id": cm_open["id"]})
|
||||
|
||||
# ── 4g. Hot-reload: ändra panelfilen → panelen uppdateras ────────
|
||||
with open(os.path.join(cfgdir, "panels", "topbar.toml"), "a") as f:
|
||||
f.write('\n[[item]]\nlabel = "HOTRELOAD"\naction = { type = "no_op" }\n')
|
||||
text = disp.frame_text(timeout=6.0, contains="HOTRELOAD")
|
||||
check("hot-reload plockar upp panel-ändring", "HOTRELOAD" in text,
|
||||
f"frame-tail: {text[:150]!r}")
|
||||
|
||||
# ── 5. Popup + popup_result via Enter ───────────────────────────
|
||||
app.send({
|
||||
"type": "spawn_popup", "message": "Integrationstest?",
|
||||
|
||||
Reference in New Issue
Block a user