Skip to content

Conversation

@mstfash
Copy link
Collaborator

@mstfash mstfash commented Jan 21, 2026

Summary

A collection of TUI enhancements focused on improving scroll behavior, diff view accuracy, session state management, and rendering robustness.

Changes

Scroll & Navigation Improvements

  • Automatic scroll to tool call start: When the approval bar appears or the user navigates between tool call tabs, the viewport now scrolls to show the beginning of the relevant tool call block with ~2 lines of context above it.
  • Scroll position stability: Introduced scroll_lines_from_end tracking and a block_stay_at_bottom_frames counter to maintain the user's scroll position even as content grows (e.g., while a tool is still streaming output).
  • Correct scroll when approval bar appears: The event loop now calculates the actual message area dimensions (accounting for side panel width and approval bar height) before dispatching the ShowConfirmationDialog event, so the scroll target is accurate.

Diff View — Correct Line Numbers

  • Extract line numbers from diff result: Added extract_starting_line_from_diff() to parse @@ -N +N @@ hunk headers from the tool call result string, giving accurate line offsets.
  • Fallback: read file to find position: Added find_starting_line_in_file() which locates old_str in the actual file to determine the starting line when no diff result is available (preview case).
  • Propagated result parameter: Updated render_file_diff_full, render_diff_result_block, render_file_diff_block_from_args, and preview_diff_from_strings to accept and use the starting line information throughout the rendering pipeline.
  • Full-screen popup uses render_full_content_message: Changed from render_collapsed_message to render_full_content_message for str_replace/create results so the full ToolCallResult (including the result text with line numbers) is preserved.

Session State Management

  • Clear changeset and todos on session transitions: Changeset and todo list are now reset when starting a new session (/new), resuming a session (/resume), switching profiles, or using the reset command (Ctrl+L). This prevents stale data from a previous session leaking into the side panel.

Shell Mode & Terminal

  • Terminal clear after shell popup closes: Added a needs_terminal_clear flag that triggers a full terminal clear and redraw after the interactive shell popup exits, cleaning up any leaked output (e.g., sudo password prompts).

Markdown & Rendering

  • Multi-line table row parsing: The markdown renderer now reassembles table rows that are split across multiple lines (a line starting with | but not ending with | will pull in continuation lines until a closing | is found or a new row begins).
  • Removed SPACING_MARKER in closing tag replacement: Closing XML tags (except checkpoint_id) are now replaced with an empty string instead of "SPACING_MARKER", avoiding spurious marker text in rendered output.

Approval Bar

  • Reduced height by 1 row: Removed the empty line between buttons and footer, changing calculated height from 8 to 7 and adjusting all internal Y-coordinate math accordingly.
  • Duplicate prevention simplified: Replaced manual already_in_bar check with the internal add_action dedup logic.

Side Panel

  • Width calculation fix: available_width in the changeset section now uses saturating_sub(1) to prevent off-by-one overflow at the panel edge.

Pending Command Preview

  • Cyan border for pending state: render_run_command_block now uses a Color::Cyan border for RunCommandState::Pending, visually distinguishing previews from completed/errored commands.

Files Changed (15 files)

File Changes
tui/src/app.rs Added scroll_to_last_message_start, block_stay_at_bottom_frames, scroll_lines_from_end, and needs_terminal_clear fields to AppState
tui/src/event_loop.rs Calculate real message area dimensions before showing confirmation dialog; use render_full_content_message for diff results; handle needs_terminal_clear
tui/src/services/approval_bar.rs Reduced height from 8→7; removed empty line between buttons and footer
tui/src/services/bash_block.rs Propagated result parameter to diff rendering functions; added Cyan border for pending command state
tui/src/services/commands.rs Clear changeset and todos on /resume and /new
tui/src/services/file_diff.rs Added extract_starting_line_from_diff, find_starting_line_in_file; updated preview_diff_from_strings and render_file_diff_block_from_args to use starting line offset
tui/src/services/handlers/dialog.rs Invalidate cache on pending tool call; trigger scroll_to_last_message_start when approval bar first appears; simplified dedup logic
tui/src/services/handlers/input.rs Clear changeset and todos on reset (Ctrl+L)
tui/src/services/handlers/navigation.rs Implemented scroll_to_last_message_start logic with lines_from_end tracking and block_stay_at_bottom_frames counter
tui/src/services/handlers/popup.rs Clear changeset and todos on profile switch
tui/src/services/handlers/shell.rs Set needs_terminal_clear on shell popup completion
tui/src/services/handlers/tool.rs Trigger scroll_to_last_message_start on tab next/prev in approval bar
tui/src/services/markdown_renderer.rs Multi-line table row reassembly; replaced SPACING_MARKER with empty string for closing tags
tui/src/services/message.rs Updated RenderCollapsedMessage and RenderFullContentMessage to use diff view with line numbers for str_replace/create
tui/src/services/side_panel.rs Fixed available width calculation with saturating_sub(1)

Tests

No new tests were added in this branch. The changes are UI/TUI-focused (scroll behavior, rendering, state management) which are validated through manual testing. Existing tests were not modified.

All validation checks pass:

Check Result
cargo check Compiles successfully with no errors
cargo clippy No warnings or lints
cargo fmt --check All code properly formatted
cargo test 70 passed, 0 failed, 0 ignored

Commits (8 non-merge)

  1. feat: Implement automatic scrolling to the last message's start for tool calls and filter completed todos from the side panel
  2. feat: Add clear/redraw for interactive command with shell mode retry
  3. feat: Clear changeset and todos on new session or reset, and refine UI scrolling and side panel width calculation
  4. fix: Correct scroll position when approval bar appears
  5. fix: Show correct line numbers in diff view
  6. refactor: Replace SPACING_MARKER with an empty string when removing markdown closing tags
  7. feat: Add support for parsing multi-line markdown table rows
  8. fmt: Code formatting

…ool calls and filter completed todos from the side panel.
…I scrolling and side panel width calculation.
- Calculate message area dimensions accounting for approval bar height
- Invalidate message cache when pending tool call message is added
- Ensures tool call preview is visible when approval bar first shows
@mstfash mstfash marked this pull request as ready for review January 22, 2026 17:13
- Extract starting line number from diff result (@@ -XX +XX @@) when available
- Fall back to reading file to find old_str position for preview case
- Use render_full_content_message for str_replace/create in fullscreen popup
  to preserve the result data needed for line number extraction
@kajogo777
Copy link
Member

the diff line number bug is still there

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants