feat: Add warning message system with red status bar notifications

This commit is contained in:
n loewen (aider) 2025-06-08 16:33:38 +01:00
parent 0f70502afc
commit 1c03bef555
1 changed files with 55 additions and 4 deletions

59
gtm
View File

@ -164,6 +164,9 @@ class AppState:
file_lines: List[str] = field(default_factory=list)
added_lines: List[Tuple[int, str]] = field(default_factory=list)
deleted_lines: List[Tuple[int, str]] = field(default_factory=list)
# Warning message system
warning_message: Optional[str] = None
focus: str = "left"
divider_col: int = 40
@ -903,8 +906,40 @@ def draw_status_bar_background(stdscr, layout: StatusBarLayout):
except curses.error:
pass
def draw_warning_message(stdscr, state: AppState, layout: StatusBarLayout):
"""Draw a warning message in red at the top of the status bar"""
if not state.warning_message:
return
try:
# Initialize color pair for warning if not already done
if curses.has_colors():
try:
curses.init_pair(8, curses.COLOR_RED, -1) # Red text on default background
except:
pass # Silently fail if we can't set the color
# Use red text with bold for warning
warning_attr = curses.color_pair(8) | curses.A_BOLD
# Draw the warning message
warning_text = f" WARNING: {state.warning_message} "
stdscr.addstr(layout.main_status_y, 0, warning_text, warning_attr)
# Add instruction to dismiss
dismiss_text = " (Press any key to dismiss) "
if len(warning_text) + len(dismiss_text) < layout.screen_width:
stdscr.addstr(layout.main_status_y, len(warning_text), dismiss_text, curses.A_REVERSE)
except curses.error:
pass # Silently fail if we can't draw the warning
def draw_main_status_line(stdscr, state: AppState, layout: StatusBarLayout):
"""Draw the main status line (percentages, indicators, etc.)"""
# If there's a warning message, draw it instead of the normal status line
if state.warning_message:
draw_warning_message(stdscr, state, layout)
return
visible_height = layout.start_y
# Add indicators to status bar
@ -1267,6 +1302,10 @@ def handle_mouse_input(stdscr, state: AppState) -> AppState:
_, mx, my, _, bstate = curses.getmouse()
state = replace(state, last_bstate=bstate, mouse_x=mx, mouse_y=my)
# If there's a warning message, any mouse click dismisses it
if state.warning_message:
return replace(state, warning_message=None)
# Status bar position
status_bar_start = state.height - state.status_bar_height
@ -1376,6 +1415,10 @@ def handle_keyboard_input(key, state: AppState) -> AppState:
if state.show_help:
return replace(state, show_help=False)
# If there's a warning message, any key dismisses it
if state.warning_message:
return replace(state, warning_message=None)
# Handle Escape key immediately for search results
if key == 27: # Escape key
# Create a new state with all escape-related changes
@ -1547,6 +1590,10 @@ def main(stdscr, filename, show_add, show_del, mouse=True, no_diff=False, wrap_l
if state.commits:
state = load_commit_content(state)
# Set warning message if we had to use a terminal fallback
if terminal_warning:
state = set_warning_message(state, terminal_warning)
# Initial draw before the main loop starts
draw_ui(stdscr, state)
@ -1584,15 +1631,19 @@ def main(stdscr, filename, show_add, show_del, mouse=True, no_diff=False, wrap_l
except Exception:
pass
def set_warning_message(state: AppState, message: str) -> AppState:
"""Set a warning message to be displayed in the status bar"""
return replace(state, warning_message=message)
if __name__ == "__main__":
# Set a fallback terminal type if the current one isn't recognized
original_term = os.environ.get("TERM")
if original_term in ["xterm-ghostty", "unknown"]:
print(f"Warning: Terminal type '{original_term}' not recognized by curses.")
print("Falling back to 'xterm-256color' for compatibility.")
print("Press Enter to continue...")
input() # Wait for user to acknowledge before continuing
# We'll show this warning in the UI instead of console
terminal_warning = f"Terminal type '{original_term}' not recognized. Using 'xterm-256color'."
os.environ["TERM"] = "xterm-256color"
else:
terminal_warning = None
parser = argparse.ArgumentParser(description="A \"Git Time Machine\" for viewing file history")
parser.add_argument("--no-diff", action="store_true", help="Don't highlight added and deleted lines")