feat: Add commit hash click-to-copy functionality with visual feedback
This commit is contained in:
parent
7304451f3f
commit
ecb452990b
43
gtm
43
gtm
|
|
@ -183,6 +183,10 @@ class AppState:
|
|||
mouse_x: int = -1
|
||||
mouse_y: int = -1
|
||||
|
||||
# Commit hash click tracking
|
||||
commit_hash_clicked: bool = False
|
||||
commit_hash_area: Optional[Tuple[int, int, int, int]] = None # (start_x, end_x, start_y, end_y)
|
||||
|
||||
# Line wrapping settings
|
||||
wrap_lines: bool = True
|
||||
|
||||
|
|
@ -963,7 +967,18 @@ def draw_commit_details(stdscr, state: AppState, layout: StatusBarLayout):
|
|||
|
||||
# Draw the commit hash at the start
|
||||
commit_info = f" {state.commit_hash} "
|
||||
stdscr.addstr(second_line, 0, commit_info, curses.A_REVERSE) # | curses.A_BOLD)
|
||||
hash_length = len(commit_info)
|
||||
|
||||
# Store the commit hash area for click detection
|
||||
state.commit_hash_area = (0, hash_length - 1, second_line, second_line)
|
||||
|
||||
# Use different style when the hash is being clicked
|
||||
if state.commit_hash_clicked:
|
||||
# When clicked, show in normal video (not reversed)
|
||||
stdscr.addstr(second_line, 0, commit_info, curses.A_BOLD)
|
||||
else:
|
||||
# Normal display: reverse video
|
||||
stdscr.addstr(second_line, 0, commit_info, curses.A_REVERSE | curses.A_BOLD)
|
||||
|
||||
# Calculate the author and branch info, ensuring it always fits
|
||||
author_branch_info = f" {state.commit_author} [{state.commit_branch}] "
|
||||
|
|
@ -1208,6 +1223,13 @@ def handle_mouse_input(stdscr, state: AppState) -> AppState:
|
|||
|
||||
# Handle mouse button press
|
||||
if bstate & curses.BUTTON1_PRESSED:
|
||||
# Check if click is on the commit hash
|
||||
if state.commit_hash_area and state.commit_hash:
|
||||
hash_start_x, hash_end_x, hash_start_y, hash_end_y = state.commit_hash_area
|
||||
if hash_start_x <= mx <= hash_end_x and hash_start_y <= my <= hash_end_y:
|
||||
# Clicked on commit hash
|
||||
return replace(state, commit_hash_clicked=True)
|
||||
|
||||
if state.show_sidebar and abs(mx - state.divider_col) <= 1:
|
||||
return replace(state, dragging_divider=True)
|
||||
elif my == status_bar_start:
|
||||
|
|
@ -1227,6 +1249,25 @@ def handle_mouse_input(stdscr, state: AppState) -> AppState:
|
|||
|
||||
# Handle mouse button release
|
||||
if bstate & curses.BUTTON1_RELEASED:
|
||||
if state.commit_hash_clicked:
|
||||
# Copy commit hash to clipboard
|
||||
if state.commit_hash:
|
||||
try:
|
||||
subprocess.run(['pbcopy'], input=state.commit_hash, text=True, check=True)
|
||||
except (FileNotFoundError, subprocess.CalledProcessError):
|
||||
try:
|
||||
# Try xclip for Linux systems
|
||||
subprocess.run(['xclip', '-selection', 'clipboard'], input=state.commit_hash, text=True, check=True)
|
||||
except (FileNotFoundError, subprocess.CalledProcessError):
|
||||
try:
|
||||
# Try clip.exe for Windows
|
||||
subprocess.run(['clip.exe'], input=state.commit_hash, text=True, check=True)
|
||||
except (FileNotFoundError, subprocess.CalledProcessError):
|
||||
pass # Silently fail if no clipboard command is available
|
||||
|
||||
# Reset the clicked state
|
||||
return replace(state, commit_hash_clicked=False)
|
||||
|
||||
if state.dragging_divider:
|
||||
return replace(state, dragging_divider=False)
|
||||
elif state.dragging_status_bar:
|
||||
|
|
|
|||
Loading…
Reference in New Issue