From 1c03bef555494268337b1baa599ea8d74722a905 Mon Sep 17 00:00:00 2001 From: "n loewen (aider)" Date: Sun, 8 Jun 2025 16:33:38 +0100 Subject: [PATCH] feat: Add warning message system with red status bar notifications --- gtm | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 55 insertions(+), 4 deletions(-) diff --git a/gtm b/gtm index 3a04054..8ee33f5 100755 --- a/gtm +++ b/gtm @@ -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")