feat: Add sidebar toggle with "s" key press
This commit is contained in:
parent
a73213a88b
commit
352edde492
105
gtm2.py
105
gtm2.py
|
|
@ -102,6 +102,7 @@ class AppState:
|
|||
self.show_additions = show_add
|
||||
self.show_deletions = show_del
|
||||
self.enable_mouse = mouse
|
||||
self.show_sidebar = True
|
||||
|
||||
self.commits = get_commits(filename)
|
||||
self.file_lines = []
|
||||
|
|
@ -136,6 +137,12 @@ class AppState:
|
|||
curses.mousemask(curses.ALL_MOUSE_EVENTS | curses.REPORT_MOUSE_POSITION)
|
||||
else:
|
||||
curses.mousemask(0)
|
||||
|
||||
def toggle_sidebar(self):
|
||||
self.show_sidebar = not self.show_sidebar
|
||||
# When hiding sidebar, focus should be on right pane
|
||||
if not self.show_sidebar:
|
||||
self.focus = "right"
|
||||
|
||||
def move_commit_selection(self, delta):
|
||||
new_idx = self.selected_commit_idx + delta
|
||||
|
|
@ -203,6 +210,9 @@ class AppState:
|
|||
# --- Rendering Functions (View) ---
|
||||
|
||||
def draw_left_pane(stdscr, state):
|
||||
if not state.show_sidebar:
|
||||
return
|
||||
|
||||
if state.selected_commit_idx < state.left_scroll_offset:
|
||||
state.left_scroll_offset = state.selected_commit_idx
|
||||
elif state.selected_commit_idx >= state.left_scroll_offset + state.height - 2:
|
||||
|
|
@ -218,7 +228,9 @@ def draw_left_pane(stdscr, state):
|
|||
stdscr.attroff(curses.A_REVERSE)
|
||||
|
||||
def draw_right_pane(stdscr, state):
|
||||
right_width = state.width - state.divider_col - 3
|
||||
# If sidebar is hidden, right pane starts at column 0
|
||||
right_start = 0 if not state.show_sidebar else state.divider_col + 2
|
||||
right_width = state.width - right_start - 1
|
||||
|
||||
max_scroll = max(0, len(state.file_lines) - (state.height - 2))
|
||||
state.right_scroll_offset = min(state.right_scroll_offset, max_scroll)
|
||||
|
|
@ -257,22 +269,25 @@ def draw_right_pane(stdscr, state):
|
|||
content = line_info['content']
|
||||
|
||||
if line_type == 'added':
|
||||
stdscr.addstr(display_row, state.divider_col + 2, "+ ", curses.color_pair(3))
|
||||
stdscr.addnstr(display_row, state.divider_col + 4, content, right_width - 2, curses.color_pair(3))
|
||||
stdscr.addstr(display_row, right_start, "+ ", curses.color_pair(3))
|
||||
stdscr.addnstr(display_row, right_start + 2, content, right_width - 2, curses.color_pair(3))
|
||||
elif line_type == 'deleted':
|
||||
stdscr.addstr(display_row, state.divider_col + 2, "- ", curses.color_pair(4))
|
||||
stdscr.addnstr(display_row, state.divider_col + 4, content, right_width - 2, curses.color_pair(4))
|
||||
stdscr.addstr(display_row, right_start, "- ", curses.color_pair(4))
|
||||
stdscr.addnstr(display_row, right_start + 2, content, right_width - 2, curses.color_pair(4))
|
||||
else:
|
||||
if state.show_whole_diff or state.show_additions or state.show_deletions:
|
||||
stdscr.addstr(display_row, state.divider_col + 2, " ")
|
||||
stdscr.addnstr(display_row, state.divider_col + 4, content, right_width - 2)
|
||||
stdscr.addstr(display_row, right_start, " ")
|
||||
stdscr.addnstr(display_row, right_start + 2, content, right_width - 2)
|
||||
else:
|
||||
# No diff mode, so don't add the margin padding
|
||||
stdscr.addnstr(display_row, state.divider_col + 2, content, right_width)
|
||||
stdscr.addnstr(display_row, right_start, content, right_width)
|
||||
|
||||
display_row += 1
|
||||
|
||||
def draw_divider(stdscr, state):
|
||||
if not state.show_sidebar:
|
||||
return
|
||||
|
||||
divider_char = "║" if state.dragging_divider else "│"
|
||||
for y in range(state.height - 1): # Don't draw through the commit message bar
|
||||
try:
|
||||
|
|
@ -368,24 +383,43 @@ def draw_status_bars(stdscr, state):
|
|||
left_attr = curses.color_pair(1) if state.focus == "left" else curses.color_pair(2)
|
||||
right_attr = curses.color_pair(1) if state.focus == "right" else curses.color_pair(2)
|
||||
|
||||
# Fill the original status bar with spaces
|
||||
for x in range(state.divider_col):
|
||||
if state.show_sidebar:
|
||||
# Fill the original status bar with spaces
|
||||
for x in range(state.divider_col):
|
||||
try:
|
||||
stdscr.addch(state.height - 2, x, ' ', left_attr)
|
||||
except curses.error:
|
||||
pass
|
||||
|
||||
# Add percentage indicators on left side of original status bar
|
||||
try:
|
||||
stdscr.addch(state.height - 2, x, ' ', left_attr)
|
||||
stdscr.addstr(state.height - 2, 1, left_status, left_attr)
|
||||
except curses.error:
|
||||
pass
|
||||
for x in range(state.divider_col + 1, state.width - 1):
|
||||
|
||||
# Draw divider in status bar with left and right colors
|
||||
try:
|
||||
stdscr.addch(state.height - 2, x, ' ', right_attr)
|
||||
# Use the half block character "▐" which can show both colors
|
||||
# First draw with left side color
|
||||
stdscr.addch(state.height - 2, state.divider_col, "▐", left_attr)
|
||||
except curses.error:
|
||||
pass
|
||||
|
||||
# Fill right side of status bar
|
||||
for x in range(state.divider_col + 1, state.width - 1):
|
||||
try:
|
||||
stdscr.addch(state.height - 2, x, ' ', right_attr)
|
||||
except curses.error:
|
||||
pass
|
||||
else:
|
||||
# When sidebar is hidden, fill the entire status bar with right pane color
|
||||
for x in range(state.width - 1):
|
||||
try:
|
||||
stdscr.addch(state.height - 2, x, ' ', right_attr)
|
||||
except curses.error:
|
||||
pass
|
||||
|
||||
# Add percentage indicators on left and right sides of original status bar
|
||||
try:
|
||||
stdscr.addstr(state.height - 2, 1, left_status, left_attr)
|
||||
except curses.error:
|
||||
pass
|
||||
|
||||
# Add right percentage indicator
|
||||
try:
|
||||
right_x = state.width - len(right_status) - 1
|
||||
if right_x >= 0:
|
||||
|
|
@ -393,14 +427,6 @@ def draw_status_bars(stdscr, state):
|
|||
except curses.error:
|
||||
pass
|
||||
|
||||
# Draw divider in status bar with left and right colors
|
||||
try:
|
||||
# Use the half block character "▐" which can show both colors
|
||||
# First draw with left side color
|
||||
stdscr.addch(state.height - 2, state.divider_col, "▐", left_attr)
|
||||
except curses.error:
|
||||
pass
|
||||
|
||||
# Draw new full-width status bar with commit message below the original status bars
|
||||
status_attr = curses.color_pair(5) # Color pair for commit message bar
|
||||
|
||||
|
|
@ -503,12 +529,15 @@ def handle_mouse_input(stdscr, state):
|
|||
|
||||
# Handle mouse button press
|
||||
if bstate & curses.BUTTON1_PRESSED:
|
||||
# Check if clicking near divider
|
||||
if abs(mx - state.divider_col) <= 1:
|
||||
# Check if clicking near divider (only if sidebar is visible)
|
||||
if state.show_sidebar and abs(mx - state.divider_col) <= 1:
|
||||
state.dragging_divider = True
|
||||
else:
|
||||
# Switch panes immediately on click
|
||||
state.focus = "left" if mx < state.divider_col else "right"
|
||||
# Switch panes immediately on click (only if sidebar is visible)
|
||||
if state.show_sidebar:
|
||||
state.focus = "left" if mx < state.divider_col else "right"
|
||||
else:
|
||||
state.focus = "right" # When sidebar is hidden, focus is always right
|
||||
|
||||
# Also start a potential selection (in case this becomes a drag)
|
||||
state.is_selecting = True
|
||||
|
|
@ -534,11 +563,14 @@ def handle_mouse_input(stdscr, state):
|
|||
if (state.click_position and
|
||||
abs(state.click_position[0] - mx) <= 2 and
|
||||
abs(state.click_position[1] - my) <= 2):
|
||||
# This was a click, so switch panes
|
||||
state.focus = "left" if mx < state.divider_col else "right"
|
||||
# This was a click, so switch panes (only if sidebar is visible)
|
||||
if state.show_sidebar:
|
||||
state.focus = "left" if mx < state.divider_col else "right"
|
||||
else:
|
||||
state.focus = "right" # When sidebar is hidden, focus is always right
|
||||
|
||||
# If clicking in the left pane on a commit entry, select that commit
|
||||
if mx < state.divider_col and my < len(state.commits) - state.left_scroll_offset:
|
||||
if state.show_sidebar and mx < state.divider_col and my < len(state.commits) - state.left_scroll_offset:
|
||||
new_commit_idx = my + state.left_scroll_offset
|
||||
if 0 <= new_commit_idx < len(state.commits):
|
||||
state.selected_commit_idx = new_commit_idx
|
||||
|
|
@ -579,8 +611,11 @@ def handle_keyboard_input(key, state):
|
|||
state.should_exit = True
|
||||
elif key == ord('m'):
|
||||
state.toggle_mouse()
|
||||
elif key == ord('s'):
|
||||
state.toggle_sidebar()
|
||||
elif key in [curses.KEY_LEFT, ord('h')]:
|
||||
state.focus = "left"
|
||||
if state.show_sidebar:
|
||||
state.focus = "left"
|
||||
elif key in [curses.KEY_RIGHT, ord('l')]:
|
||||
state.focus = "right"
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue