Add vim list nav, fix window-title padding toggle, widen title spacing
TUI: - VimListView: j/k now move down/up in the project and session lists (arrow keys still work); used by both list widgets. tmux status bar: - Widen the gap between window cells via a 2-space window-status-separator (WINDOW_STATUS_SEPARATOR). - Fix the current-window cell toggling between padded " 1: name " and unpadded "1: name". The per-window status format is static, but set_window_label re-asserted it on every 3s poll — letting a competing writer (e.g. a stale TUI process running older code with a differently padded format) flip the cell each cycle. The format is now owned by a single write-once path (new_window at creation, apply_theme for existing windows); the poll updates only the dynamic @hqt_label. Also lands pre-staged scaffolding: AGENTS.md quality gate, TODO.md backlog, and ty dev dependency. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -1057,3 +1057,76 @@ async def test_rename_session_opens_prefilled_and_updates():
|
||||
assert app._db_session.get(Session, sess.id).nickname == "after"
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Vim-style j/k navigation in the project and session lists
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_project_list_jk_navigation():
|
||||
"""j/k move the highlight down/up in the project list like the arrow keys."""
|
||||
app = HqtApp()
|
||||
async with app.run_test(size=(120, 40)) as pilot:
|
||||
from hqt.tui.widgets.project_list import ProjectList
|
||||
|
||||
p1 = app._project_service.create("first", "/tmp/jk-first")
|
||||
p2 = app._project_service.create("second", "/tmp/jk-second")
|
||||
app._load_projects()
|
||||
await app.workers.wait_for_complete()
|
||||
await pilot.pause()
|
||||
|
||||
pl = app.query_one(ProjectList)
|
||||
pl.query_one("#project-list").focus()
|
||||
await pilot.pause()
|
||||
# j walks down to the second project...
|
||||
await pilot.press("j")
|
||||
await pilot.pause()
|
||||
assert pl.get_selected_project_id() == p2.id
|
||||
# ...and k walks back up to the first.
|
||||
await pilot.press("k")
|
||||
await pilot.pause()
|
||||
assert pl.get_selected_project_id() == p1.id
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_session_list_jk_navigation():
|
||||
"""j/k move the highlight down/up in the session list like the arrow keys."""
|
||||
from hqt.db.models import Harness, Project, Session
|
||||
from hqt.tui.widgets.session_list import SessionList
|
||||
|
||||
app = HqtApp()
|
||||
async with app.run_test(size=(120, 40)) as pilot:
|
||||
proj = Project(name="jk-proj", path="/tmp/jk-proj")
|
||||
app._db_session.add(proj)
|
||||
app._db_session.flush()
|
||||
harness = app._db_session.query(Harness).first()
|
||||
sessions = []
|
||||
for n in range(2):
|
||||
s = Session(
|
||||
project_id=proj.id,
|
||||
harness_id=harness.id,
|
||||
nickname=f"sess-{n}",
|
||||
tmux_session_name=f"hqt-jk-{n}",
|
||||
archived=False,
|
||||
)
|
||||
app._db_session.add(s)
|
||||
sessions.append(s)
|
||||
app._db_session.commit()
|
||||
|
||||
app._selected_project_id = proj.id
|
||||
# restore_selection mirrors a real project switch, which highlights the
|
||||
# first session — giving j/k a defined starting point.
|
||||
await app._refresh_sessions(restore_selection=True)
|
||||
await pilot.pause()
|
||||
|
||||
sl = app.query_one(SessionList)
|
||||
sl.query_one("#session-list").focus()
|
||||
await pilot.pause()
|
||||
await pilot.press("j")
|
||||
await pilot.pause()
|
||||
assert sl.get_selected_session_id() == sessions[1].id
|
||||
await pilot.press("k")
|
||||
await pilot.pause()
|
||||
assert sl.get_selected_session_id() == sessions[0].id
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user