Switch panes with arrow keys + status display for current line

This commit is contained in:
n loewen 2025-04-23 22:08:08 +01:00
parent 29f0e7a28b
commit 01d24e0733
1 changed files with 33 additions and 17 deletions

View File

@ -1,4 +1,5 @@
# by ChatGPT # by ChatGPT
import curses import curses
import subprocess import subprocess
import sys import sys
@ -28,8 +29,15 @@ def main(stdscr, filename):
stdscr.clear() stdscr.clear()
height, width = stdscr.getmaxyx() height, width = stdscr.getmaxyx()
# Draw commit list on the left # Fetch file content for selected commit
for i in range(min(len(commits), height)): commit_hash = commits[selected_commit].split()[0]
file_lines = get_file_at_commit(commit_hash, filename)
max_scroll = max(0, len(file_lines) - (height - 1))
scroll_offset = min(scroll_offset, max_scroll)
visible_lines = file_lines[scroll_offset:scroll_offset + height - 1]
# Draw commit list
for i in range(min(len(commits), height - 1)):
line = commits[i] line = commits[i]
if i == selected_commit and focus == "left": if i == selected_commit and focus == "left":
stdscr.attron(curses.A_REVERSE) stdscr.attron(curses.A_REVERSE)
@ -37,22 +45,22 @@ def main(stdscr, filename):
if i == selected_commit and focus == "left": if i == selected_commit and focus == "left":
stdscr.attroff(curses.A_REVERSE) stdscr.attroff(curses.A_REVERSE)
# Draw vertical divider with box-drawing character # Vertical divider
for y in range(height): for y in range(height):
stdscr.addch(y, divider_col, '') stdscr.addch(y, divider_col, '')
# Draw file content on the right # File content
if commits:
commit_hash = commits[selected_commit].split()[0]
file_lines = get_file_at_commit(commit_hash, filename)
visible_lines = file_lines[scroll_offset:scroll_offset + height]
for i, line in enumerate(visible_lines): for i, line in enumerate(visible_lines):
stdscr.addnstr(i, divider_col + 2, line, width - divider_col - 3) stdscr.addnstr(i, divider_col + 2, line, width - divider_col - 3)
stdscr.refresh() # Status bar for right pane
status = f"line {scroll_offset + 1}/{len(file_lines)}"
stdscr.addnstr(height - 1, divider_col + 2, status, width - divider_col - 3, curses.A_DIM)
stdscr.refresh()
key = stdscr.getch() key = stdscr.getch()
# Mouse click changes focus
if key == curses.KEY_MOUSE: if key == curses.KEY_MOUSE:
try: try:
_, mx, my, _, bstate = curses.getmouse() _, mx, my, _, bstate = curses.getmouse()
@ -64,27 +72,35 @@ def main(stdscr, filename):
elif key in [ord('q'), 27]: elif key in [ord('q'), 27]:
break break
# Left pane movement
elif focus == "left": elif focus == "left":
if key in [curses.KEY_DOWN, ord('j')]: if key in [curses.KEY_DOWN, ord('j')]:
if selected_commit < len(commits) - 1: if selected_commit < len(commits) - 1:
selected_commit += 1 selected_commit += 1
scroll_offset = 0 # reset right pane scroll scroll_offset = 0
elif key in [curses.KEY_UP, ord('k')]: elif key in [curses.KEY_UP, ord('k')]:
if selected_commit > 0: if selected_commit > 0:
selected_commit -= 1 selected_commit -= 1
scroll_offset = 0 scroll_offset = 0
# Right pane scrolling
elif focus == "right": elif focus == "right":
if key == curses.KEY_DOWN or key == ord('j'): if key in [curses.KEY_DOWN, ord('j')]:
if scroll_offset < max(0, len(file_lines) - height): if scroll_offset < max_scroll:
scroll_offset += 1 scroll_offset += 1
elif key == curses.KEY_UP or key == ord('k'): elif key in [curses.KEY_UP, ord('k')]:
if scroll_offset > 0: if scroll_offset > 0:
scroll_offset -= 1 scroll_offset -= 1
elif key == curses.KEY_NPAGE: # Page Down elif key == curses.KEY_NPAGE: # Page Down
scroll_offset = min(scroll_offset + height, max(0, len(file_lines) - height)) scroll_offset = min(scroll_offset + height - 1, max_scroll)
elif key == curses.KEY_PPAGE: # Page Up elif key == curses.KEY_PPAGE: # Page Up
scroll_offset = max(0, scroll_offset - height) scroll_offset = max(0, scroll_offset - (height - 1))
# Pane switching
if key in [curses.KEY_LEFT, ord('h')]:
focus = "left"
elif key in [curses.KEY_RIGHT, ord('l')]:
focus = "right"
if __name__ == "__main__": if __name__ == "__main__":
if len(sys.argv) != 2: if len(sys.argv) != 2: