From bc6ec6d847f1b416ca53796ef0e6eac308fb746a Mon Sep 17 00:00:00 2001 From: "n loewen (aider)" Date: Mon, 5 May 2025 09:18:18 +0100 Subject: [PATCH] feat: implement vertical scrolling for commit list in left pane --- git_time_machine.py | 62 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 49 insertions(+), 13 deletions(-) diff --git a/git_time_machine.py b/git_time_machine.py index f36e7fb..1ea828a 100644 --- a/git_time_machine.py +++ b/git_time_machine.py @@ -32,6 +32,7 @@ def main(stdscr, filename): divider_col = 40 focus = "left" scroll_offset = 0 + left_scroll_offset = 0 # Scroll position for left pane dragging_divider = False @@ -55,13 +56,24 @@ def main(stdscr, filename): scroll_offset = min(scroll_offset, max_scroll) visible_lines = file_lines[scroll_offset:scroll_offset + height - 1] + # Calculate visible commits for left pane + left_max_scroll = max(0, len(commits) - (height - 1)) + left_scroll_offset = min(left_scroll_offset, left_max_scroll) + + # Ensure selected commit is visible + if selected_commit < left_scroll_offset: + left_scroll_offset = selected_commit + elif selected_commit >= left_scroll_offset + height - 1: + left_scroll_offset = selected_commit - (height - 2) + # Draw commit list (left pane) - for i in range(min(len(commits), height - 1)): - line = commits[i] - if i == selected_commit: + visible_commits = commits[left_scroll_offset:left_scroll_offset + height - 1] + for i, line in enumerate(visible_commits): + display_index = i + left_scroll_offset + if display_index == selected_commit: stdscr.attron(curses.A_REVERSE) # Highlight selected commit stdscr.addnstr(i, 0, line, divider_col - 1) - if i == selected_commit: + if display_index == selected_commit: stdscr.attroff(curses.A_REVERSE) # Vertical divider @@ -76,19 +88,31 @@ def main(stdscr, filename): if i < height - 1: stdscr.addnstr(i, divider_col + 2, line, right_width) - # Status bar for right pane + # Status bars for both panes visible_height = height - 1 # Reserve 1 line for the status bar + + # Right pane status last_visible_line = scroll_offset + visible_height - if len(file_lines) > 0: - percent = int((last_visible_line / len(file_lines)) * 100) - percent = 100 if last_visible_line >= len(file_lines) else percent + right_percent = int((last_visible_line / len(file_lines)) * 100) + right_percent = 100 if last_visible_line >= len(file_lines) else right_percent else: - percent = 0 - - status = f"{percent}%" - x = width - len(status) - 1 - stdscr.addnstr(height - 1, x, status, len(status), curses.A_REVERSE) + right_percent = 0 + right_status = f"{right_percent}%" + + # Left pane status + last_visible_commit = left_scroll_offset + visible_height + if len(commits) > 0: + left_percent = int((last_visible_commit / len(commits)) * 100) + left_percent = 100 if last_visible_commit >= len(commits) else left_percent + else: + left_percent = 0 + left_status = f"{left_percent}%" + + # Draw status bars + stdscr.addnstr(height - 1, 1, left_status, len(left_status), curses.A_REVERSE) + x = width - len(right_status) - 1 + stdscr.addnstr(height - 1, x, right_status, len(right_status), curses.A_REVERSE) # Get input with a small timeout for smoother scrolling stdscr.timeout(50) # 50ms timeout @@ -140,6 +164,18 @@ def main(stdscr, filename): if selected_commit > 0: selected_commit -= 1 scroll_offset = 0 + elif key in [curses.KEY_NPAGE, ord(' ')]: + # Page down in left pane + new_selected = min(selected_commit + height - 1, len(commits) - 1) + if new_selected != selected_commit: + selected_commit = new_selected + scroll_offset = 0 + elif key in [curses.KEY_PPAGE, 8, 127, curses.KEY_SR]: + # Page up in left pane + new_selected = max(0, selected_commit - (height - 1)) + if new_selected != selected_commit: + selected_commit = new_selected + scroll_offset = 0 # Right pane scrolling elif focus == "right":