feat: improve terminal navigation and UI behavior
- refine tree and history navigation behavior - improve scrolling continuity in the terminal UI - keep AI worklog and prompt log updated - validate changes with project quality checks
This commit is contained in:
@@ -10,6 +10,7 @@ from app.ui import (
|
||||
TerminalUI,
|
||||
build_history_lines,
|
||||
build_render_lines,
|
||||
clamp_scroll_offset,
|
||||
format_entry,
|
||||
move_selection,
|
||||
open_terminal_streams,
|
||||
@@ -79,6 +80,18 @@ def test_build_history_lines_marks_selected_history_entry(tmp_path: Path) -> Non
|
||||
]
|
||||
|
||||
|
||||
def test_clamp_scroll_offset_keeps_selection_visible_when_moving_down() -> None:
|
||||
assert clamp_scroll_offset(5, scroll_offset=0, visible_count=3, total_count=10) == 3
|
||||
|
||||
|
||||
def test_clamp_scroll_offset_keeps_selection_visible_when_moving_up() -> None:
|
||||
assert clamp_scroll_offset(1, scroll_offset=4, visible_count=3, total_count=10) == 1
|
||||
|
||||
|
||||
def test_clamp_scroll_offset_returns_zero_when_all_items_fit() -> None:
|
||||
assert clamp_scroll_offset(2, scroll_offset=1, visible_count=5, total_count=3) == 0
|
||||
|
||||
|
||||
def test_toggle_history_mode_selects_current_history_entry(tmp_path: Path) -> None:
|
||||
root = tmp_path / "root"
|
||||
child = root / "child"
|
||||
@@ -134,6 +147,80 @@ def test_history_mode_toggle_off_keeps_current_directory(tmp_path: Path) -> None
|
||||
assert navigator.current_path == root.resolve()
|
||||
|
||||
|
||||
def test_right_arrow_expands_collapsed_directory(tmp_path: Path) -> None:
|
||||
workspace = tmp_path / "workspace"
|
||||
scripts = workspace / "scripts"
|
||||
build = scripts / "build"
|
||||
workspace.mkdir()
|
||||
scripts.mkdir()
|
||||
build.mkdir()
|
||||
|
||||
navigator = Navigator(workspace)
|
||||
navigator.set_selected_index(1)
|
||||
ui = TerminalUI()
|
||||
|
||||
assert ui._handle_tree_key(curses.KEY_RIGHT, navigator) is None
|
||||
assert navigator.current_path == workspace.resolve()
|
||||
assert [entry.name for entry in navigator.visible_entries] == [
|
||||
"..",
|
||||
"scripts",
|
||||
"build",
|
||||
]
|
||||
|
||||
|
||||
def test_right_arrow_enters_already_expanded_directory(tmp_path: Path) -> None:
|
||||
workspace = tmp_path / "workspace"
|
||||
scripts = workspace / "scripts"
|
||||
build = scripts / "build"
|
||||
workspace.mkdir()
|
||||
scripts.mkdir()
|
||||
build.mkdir()
|
||||
|
||||
navigator = Navigator(workspace)
|
||||
navigator.set_selected_index(1)
|
||||
navigator.expand_selected_directory()
|
||||
ui = TerminalUI()
|
||||
|
||||
assert ui._handle_tree_key(curses.KEY_RIGHT, navigator) is None
|
||||
assert navigator.current_path == scripts.resolve()
|
||||
assert navigator.selected_index == 0
|
||||
|
||||
|
||||
def test_left_arrow_goes_to_parent_when_selected_entry_is_collapsed(
|
||||
tmp_path: Path,
|
||||
) -> None:
|
||||
parent = tmp_path / "parent"
|
||||
current = parent / "current"
|
||||
child = current / "child"
|
||||
parent.mkdir()
|
||||
current.mkdir()
|
||||
child.mkdir()
|
||||
|
||||
navigator = Navigator(current)
|
||||
navigator.set_selected_index(1)
|
||||
ui = TerminalUI()
|
||||
|
||||
assert ui._handle_tree_key(curses.KEY_LEFT, navigator) is None
|
||||
assert navigator.current_path == parent.resolve()
|
||||
assert navigator.selected_index == 0
|
||||
|
||||
|
||||
def test_enter_returns_selected_path_without_navigating(tmp_path: Path) -> None:
|
||||
workspace = tmp_path / "workspace"
|
||||
child = workspace / "child"
|
||||
workspace.mkdir()
|
||||
child.mkdir()
|
||||
|
||||
navigator = Navigator(workspace)
|
||||
navigator.set_selected_index(1)
|
||||
ui = TerminalUI()
|
||||
|
||||
result = ui._handle_tree_key(10, navigator)
|
||||
|
||||
assert result == child.resolve()
|
||||
assert navigator.current_path == workspace.resolve()
|
||||
|
||||
|
||||
def test_open_terminal_streams_raises_without_terminal(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
) -> None:
|
||||
|
||||
Reference in New Issue
Block a user