diff --git a/src/hqt/tui/app.py b/src/hqt/tui/app.py index e19ff82..4df8d0b 100644 --- a/src/hqt/tui/app.py +++ b/src/hqt/tui/app.py @@ -70,6 +70,8 @@ class HqtApp(App): Binding("a", "add_project", "Add Project"), Binding("e", "edit_project", "Edit Project"), Binding("tab", "toggle_focus", "Switch Panel"), + Binding("h", "focus_projects", "Projects"), + Binding("l", "focus_sessions", "Sessions"), Binding("d", "delete_session", "Delete Session"), Binding("enter", "attach_session", "Attach", priority=True), Binding("r", "rename_session", "Rename"), @@ -213,6 +215,12 @@ class HqtApp(App): def action_toggle_focus(self) -> None: self.screen.focus_next() + def action_focus_projects(self) -> None: + self.query_one("#project-list").focus() + + def action_focus_sessions(self) -> None: + self.query_one("#session-list").focus() + def action_add_project(self) -> None: def on_dismiss(result: tuple[str, str] | None) -> None: if result: diff --git a/tests/test_tui.py b/tests/test_tui.py index dd99b55..9716f48 100644 --- a/tests/test_tui.py +++ b/tests/test_tui.py @@ -1983,3 +1983,35 @@ def test_policy_reflects_suboptions_when_sandbox_on(): assert policy is not None assert policy.fs == "ro" assert policy.net is False + + +# --------------------------------------------------------------------------- +# Task 3: h/l column focus navigation +# --------------------------------------------------------------------------- + + +@pytest.mark.asyncio +async def test_hl_focus_bindings_exist(): + bindings = {b.key: b for b in HqtApp.BINDINGS} + assert bindings["h"].action == "focus_projects" + assert bindings["l"].action == "focus_sessions" + + +@pytest.mark.asyncio +async def test_h_focuses_projects_l_focuses_sessions(tmp_path): + app = HqtApp() + async with app.run_test(size=(120, 40)) as pilot: + d = tmp_path / "hl-proj" + d.mkdir() + app._project_service.create("hl", str(d)) + app._load_projects() + await app.workers.wait_for_complete() + await pilot.pause() + + await pilot.press("l") + await pilot.pause() + assert app.focused is app.query_one("#session-list") + + await pilot.press("h") + await pilot.pause() + assert app.focused is app.query_one("#project-list")