feat: Implement line wrapping with toggle and CLI option
This commit is contained in:
parent
cc25765a41
commit
a39c28c099
73
gtm
73
gtm
|
|
@ -123,6 +123,9 @@ class AppState:
|
||||||
last_bstate: int = 0
|
last_bstate: int = 0
|
||||||
mouse_x: int = -1
|
mouse_x: int = -1
|
||||||
mouse_y: int = -1
|
mouse_y: int = -1
|
||||||
|
|
||||||
|
# Line wrapping settings
|
||||||
|
wrap_lines: bool = True
|
||||||
|
|
||||||
# --- Actions (Controller) ---
|
# --- Actions (Controller) ---
|
||||||
|
|
||||||
|
|
@ -272,21 +275,57 @@ def draw_right_pane(stdscr, state):
|
||||||
line_type = line_info['type']
|
line_type = line_info['type']
|
||||||
content = line_info['content']
|
content = line_info['content']
|
||||||
|
|
||||||
|
# Determine prefix based on line type and diff mode
|
||||||
|
prefix = ""
|
||||||
if line_type == 'added':
|
if line_type == 'added':
|
||||||
stdscr.addstr(display_row, right_start, "+ ", curses.color_pair(3))
|
prefix = "+ "
|
||||||
stdscr.addnstr(display_row, right_start + 2, content, right_width - 2, curses.color_pair(3))
|
attr = curses.color_pair(3)
|
||||||
elif line_type == 'deleted':
|
elif line_type == 'deleted':
|
||||||
stdscr.addstr(display_row, right_start, "- ", curses.color_pair(4))
|
prefix = "- "
|
||||||
stdscr.addnstr(display_row, right_start + 2, content, right_width - 2, curses.color_pair(4))
|
attr = curses.color_pair(4)
|
||||||
else:
|
else:
|
||||||
if state.show_whole_diff or state.show_additions or state.show_deletions:
|
if state.show_whole_diff or state.show_additions or state.show_deletions:
|
||||||
stdscr.addstr(display_row, right_start, " ")
|
prefix = " "
|
||||||
stdscr.addnstr(display_row, right_start + 2, content, right_width - 2)
|
attr = curses.A_NORMAL
|
||||||
else:
|
|
||||||
# No diff mode, so don't add the margin padding
|
|
||||||
stdscr.addnstr(display_row, right_start, content, right_width)
|
|
||||||
|
|
||||||
display_row += 1
|
# Calculate available width for content
|
||||||
|
content_start = right_start + len(prefix)
|
||||||
|
available_width = right_width - len(prefix)
|
||||||
|
|
||||||
|
# Handle line wrapping
|
||||||
|
if len(content) <= available_width:
|
||||||
|
# Line fits, no wrapping needed
|
||||||
|
if prefix:
|
||||||
|
stdscr.addstr(display_row, right_start, prefix, attr)
|
||||||
|
stdscr.addnstr(display_row, content_start, content, available_width, attr)
|
||||||
|
display_row += 1
|
||||||
|
else:
|
||||||
|
# Line needs wrapping
|
||||||
|
remaining = content
|
||||||
|
first_line = True
|
||||||
|
|
||||||
|
while remaining and display_row < state.height - 2:
|
||||||
|
# For first line, add the prefix
|
||||||
|
if first_line:
|
||||||
|
if prefix:
|
||||||
|
stdscr.addstr(display_row, right_start, prefix, attr)
|
||||||
|
chunk = remaining[:available_width]
|
||||||
|
stdscr.addnstr(display_row, content_start, chunk, available_width, attr)
|
||||||
|
remaining = remaining[available_width:]
|
||||||
|
first_line = False
|
||||||
|
else:
|
||||||
|
# For continuation lines, indent by 2 spaces
|
||||||
|
indent = " "
|
||||||
|
indent_start = right_start
|
||||||
|
content_start = indent_start + len(indent)
|
||||||
|
wrap_width = right_width - len(indent)
|
||||||
|
|
||||||
|
stdscr.addstr(display_row, indent_start, indent)
|
||||||
|
chunk = remaining[:wrap_width]
|
||||||
|
stdscr.addnstr(display_row, content_start, chunk, wrap_width, attr)
|
||||||
|
remaining = remaining[wrap_width:]
|
||||||
|
|
||||||
|
display_row += 1
|
||||||
|
|
||||||
def draw_divider(stdscr, state):
|
def draw_divider(stdscr, state):
|
||||||
if not state.show_sidebar:
|
if not state.show_sidebar:
|
||||||
|
|
@ -364,6 +403,10 @@ def draw_status_bars(stdscr, state):
|
||||||
if len(parts) >= 4:
|
if len(parts) >= 4:
|
||||||
commit_message = parts[3]
|
commit_message = parts[3]
|
||||||
|
|
||||||
|
# Add wrap indicator to commit message
|
||||||
|
wrap_indicator = " [W] " if state.wrap_lines else " [NW] "
|
||||||
|
commit_message = wrap_indicator + commit_message
|
||||||
|
|
||||||
# Status bar percentages
|
# Status bar percentages
|
||||||
if len(state.file_lines) > 0:
|
if len(state.file_lines) > 0:
|
||||||
last_visible_line = state.right_scroll_offset + visible_height
|
last_visible_line = state.right_scroll_offset + visible_height
|
||||||
|
|
@ -587,6 +630,8 @@ def handle_keyboard_input(key, state: AppState) -> AppState:
|
||||||
return replace(state, should_exit=True)
|
return replace(state, should_exit=True)
|
||||||
elif key == ord('s'):
|
elif key == ord('s'):
|
||||||
return toggle_sidebar(state)
|
return toggle_sidebar(state)
|
||||||
|
elif key == ord('w'):
|
||||||
|
return replace(state, wrap_lines=not state.wrap_lines)
|
||||||
elif key in [curses.KEY_LEFT, ord('h')]:
|
elif key in [curses.KEY_LEFT, ord('h')]:
|
||||||
if state.show_sidebar:
|
if state.show_sidebar:
|
||||||
return replace(state, focus="left")
|
return replace(state, focus="left")
|
||||||
|
|
@ -616,7 +661,7 @@ def handle_keyboard_input(key, state: AppState) -> AppState:
|
||||||
|
|
||||||
# --- Main Application ---
|
# --- Main Application ---
|
||||||
|
|
||||||
def main(stdscr, filename, show_diff, show_add, show_del, mouse):
|
def main(stdscr, filename, show_diff, show_add, show_del, mouse, wrap_lines=True):
|
||||||
try:
|
try:
|
||||||
curses.curs_set(0)
|
curses.curs_set(0)
|
||||||
except:
|
except:
|
||||||
|
|
@ -637,7 +682,8 @@ def main(stdscr, filename, show_diff, show_add, show_del, mouse):
|
||||||
filename=filename, width=width, height=height,
|
filename=filename, width=width, height=height,
|
||||||
show_whole_diff=show_diff, show_additions=show_add,
|
show_whole_diff=show_diff, show_additions=show_add,
|
||||||
show_deletions=show_del, enable_mouse=mouse,
|
show_deletions=show_del, enable_mouse=mouse,
|
||||||
commits=get_commits(filename)
|
commits=get_commits(filename),
|
||||||
|
wrap_lines=wrap_lines
|
||||||
)
|
)
|
||||||
|
|
||||||
if state.enable_mouse:
|
if state.enable_mouse:
|
||||||
|
|
@ -695,6 +741,7 @@ if __name__ == "__main__":
|
||||||
parser.add_argument("--diff-additions", action="store_true", help="Highlight newly added lines in green")
|
parser.add_argument("--diff-additions", action="store_true", help="Highlight newly added lines in green")
|
||||||
parser.add_argument("--diff-deletions", action="store_true", help="Show deleted lines in red")
|
parser.add_argument("--diff-deletions", action="store_true", help="Show deleted lines in red")
|
||||||
parser.add_argument("--no-mouse", action="store_true", help="Disable mouse support")
|
parser.add_argument("--no-mouse", action="store_true", help="Disable mouse support")
|
||||||
|
parser.add_argument("--no-wrap", action="store_true", help="Disable line wrapping")
|
||||||
parser.add_argument("-v", "--version", action="store_true", help="Show version number")
|
parser.add_argument("-v", "--version", action="store_true", help="Show version number")
|
||||||
parser.add_argument("filename", nargs="?", help="File to view history for")
|
parser.add_argument("filename", nargs="?", help="File to view history for")
|
||||||
|
|
||||||
|
|
@ -713,4 +760,4 @@ if __name__ == "__main__":
|
||||||
print(f"Error: File '{filename}' does not exist")
|
print(f"Error: File '{filename}' does not exist")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
curses.wrapper(main, filename, args.diff, args.diff_additions, args.diff_deletions, not args.no_mouse)
|
curses.wrapper(main, filename, args.diff, args.diff_additions, args.diff_deletions, not args.no_mouse, not args.no_wrap)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue