diff --git a/key-bindings.c b/key-bindings.c index 359a7b5cb..f90307fc1 100644 --- a/key-bindings.c +++ b/key-bindings.c @@ -1,4 +1,4 @@ -/* $OpenBSD: key-bindings.c,v 1.187 2026/07/13 16:07:47 nicm Exp $ */ +/* $OpenBSD: key-bindings.c,v 1.188 2026/07/13 16:30:28 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -49,6 +49,9 @@ " '#{?#{m/r:(copy|view)-mode,#{pane_mode}},Go To Top,}' '<' {send -X history-top}" \ " '#{?#{m/r:(copy|view)-mode,#{pane_mode}},Go To Bottom,}' '>' {send -X history-bottom}" \ " ''" \ + " '#{?#{==:#{pane_mode},copy-mode},#{?copy_line_numbers,Hide Line Numbers,Show Line Numbers},}' 'L' {send -X line-numbers-toggle}" \ + " '#{?#{==:#{pane_mode},copy-mode},#{?refresh_active,Refresh Off,Refresh On},}' 'r' {send -X refresh-toggle}" \ + " ''" \ " '#{?#{&&:#{buffer_size},#{!:#{pane_in_mode}}},Paste #[underscore]#{=/9/...:buffer_sample},}' 'p' {paste-buffer}" \ " ''" \ " '#{?mouse_word,Search For #[underscore]#{=/9/...:mouse_word},}' 'C-r' {if -F '#{?#{m/r:(copy|view)-mode,#{pane_mode}},0,1}' 'copy-mode -t='; send -Xt= search-backward -- \"#{q:mouse_word}\"}" \ @@ -576,6 +579,7 @@ key_bindings_init(void) "bind -Tcopy-mode , { send -X jump-reverse }", "bind -Tcopy-mode \\; { send -X jump-again }", "bind -Tcopy-mode F { command-prompt -P -1p'(jump backward)' { send -X jump-backward -- '%%' } }", + "bind -Tcopy-mode L { send -X line-numbers-toggle }", "bind -Tcopy-mode N { send -X search-reverse }", "bind -Tcopy-mode P { send -X toggle-position }", "bind -Tcopy-mode R { send -X rectangle-toggle }", diff --git a/tmux.1 b/tmux.1 index 029f1ee26..52e83ed98 100644 --- a/tmux.1 +++ b/tmux.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: tmux.1,v 1.1136 2026/07/13 16:07:47 nicm Exp $ +.\" $OpenBSD: tmux.1,v 1.1137 2026/07/13 16:30:28 nicm Exp $ .\" .\" Copyright (c) 2007 Nicholas Marriott .\" @@ -2158,6 +2158,19 @@ before the target. .Xc Jump to the last mark. .It Xo +.Ic line\-numbers\-on +.Xc +Show line numbers in copy mode. +.It Xo +.Ic line\-numbers\-off +.Xc +Hide line numbers in copy mode. +.It Xo +.Ic line\-numbers\-toggle +(emacs: L) +.Xc +Toggle line numbers in copy mode. +.It Xo .Ic middle\-line (vi: M) (emacs: M\-r) @@ -7175,6 +7188,7 @@ The following variables are available, where appropriate: .It Li "copy_cursor_word" Ta "" Ta "Word under cursor in copy mode" .It Li "copy_cursor_x" Ta "" Ta "Cursor X position in copy mode" .It Li "copy_cursor_y" Ta "" Ta "Cursor Y position in copy mode" +.It Li "copy_line_numbers" Ta "" Ta "1 if line numbers are shown in copy mode" .It Li "copy_position" Ta "" Ta "Position shown in the copy mode indicator" .It Li "copy_position_limit" Ta "" Ta "Limit shown in the copy mode indicator" .It Li "current_file" Ta "" Ta "Current configuration file" @@ -7294,6 +7308,7 @@ The following variables are available, where appropriate: .It Li "prev_window_active" Ta "" Ta "1 if previous window in W: loop is active" .It Li "prev_window_index" Ta "" Ta "Index of previous window in W: loop" .It Li "rectangle_toggle" Ta "" Ta "1 if rectangle selection is activated" +.It Li "refresh_active" Ta "" Ta "1 if copy mode refresh is active" .It Li "scroll_position" Ta "" Ta "Scroll position in copy mode" .It Li "scroll_region_lower" Ta "" Ta "Bottom of scroll region in pane" .It Li "scroll_region_upper" Ta "" Ta "Top of scroll region in pane" diff --git a/window-copy.c b/window-copy.c index 6d0390fe9..2213dcebb 100644 --- a/window-copy.c +++ b/window-copy.c @@ -1,4 +1,4 @@ -/* $OpenBSD: window-copy.c,v 1.415 2026/07/13 12:53:56 jsg Exp $ */ +/* $OpenBSD: window-copy.c,v 1.416 2026/07/13 16:30:28 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -57,6 +57,8 @@ static void window_copy_refresh_arm(struct window_mode_entry *); static void window_copy_refresh_start(struct window_mode_entry *); static void window_copy_refresh_stop(struct window_mode_entry *); static void window_copy_style_changed(struct window_mode_entry *); +static void window_copy_set_line_numbers1(struct window_mode_entry *, int, + int); static int window_copy_line_number_mode(struct window_mode_entry *); static int window_copy_line_number_is_absolute(struct window_mode_entry *); static int window_copy_line_numbers_active(struct window_mode_entry *); @@ -296,7 +298,7 @@ struct window_copy_mode_data { int rectflag; /* in rectangle copy mode? */ int scroll_exit; /* exit on scroll to end? */ int hide_position; /* hide position marker */ - int line_numbers; + int line_numbers; /* 0 off, 1 from option, 2 default */ enum { SEL_CHAR, /* select one char at a time */ @@ -1117,6 +1119,9 @@ window_copy_formats(struct window_mode_entry *wme, struct format_tree *ft) } format_add(ft, "copy_position", "%u", position); format_add(ft, "copy_position_limit", "%u", limit); + format_add(ft, "copy_line_numbers", "%d", + window_copy_line_numbers_active(wme)); + format_add(ft, "refresh_active", "%d", data->refresh_active); format_add(ft, "rectangle_toggle", "%d", data->rectflag); format_add(ft, "copy_cursor_x", "%d", data->cx); @@ -3150,6 +3155,28 @@ window_copy_cmd_recentre_top_bottom(struct window_copy_cmd_state *cs) return (WINDOW_COPY_CMD_REDRAW); } +static enum window_copy_cmd_action +window_copy_cmd_line_numbers_on(struct window_copy_cmd_state *cs) +{ + window_copy_set_line_numbers1(cs->wme, 1, 1); + return (WINDOW_COPY_CMD_NOTHING); +} + +static enum window_copy_cmd_action +window_copy_cmd_line_numbers_off(struct window_copy_cmd_state *cs) +{ + window_copy_set_line_numbers1(cs->wme, 0, 0); + return (WINDOW_COPY_CMD_NOTHING); +} + +static enum window_copy_cmd_action +window_copy_cmd_line_numbers_toggle(struct window_copy_cmd_state *cs) +{ + window_copy_set_line_numbers1(cs->wme, + !window_copy_line_numbers_active(cs->wme), 1); + return (WINDOW_COPY_CMD_NOTHING); +} + static const struct { const char *command; u_int minargs; @@ -3414,6 +3441,24 @@ static const struct { .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_jump_to_mark }, + { .command = "line-numbers-on", + .args = { "", 0, 0, NULL }, + .flags = WINDOW_COPY_CMD_FLAG_READONLY, + .clear = WINDOW_COPY_CMD_CLEAR_NEVER, + .f = window_copy_cmd_line_numbers_on + }, + { .command = "line-numbers-off", + .args = { "", 0, 0, NULL }, + .flags = WINDOW_COPY_CMD_FLAG_READONLY, + .clear = WINDOW_COPY_CMD_CLEAR_NEVER, + .f = window_copy_cmd_line_numbers_off + }, + { .command = "line-numbers-toggle", + .args = { "", 0, 0, NULL }, + .flags = WINDOW_COPY_CMD_FLAG_READONLY, + .clear = WINDOW_COPY_CMD_CLEAR_NEVER, + .f = window_copy_cmd_line_numbers_toggle + }, { .command = "next-prompt", .args = { "o", 0, 0, NULL }, .flags = WINDOW_COPY_CMD_FLAG_READONLY, @@ -5066,10 +5111,14 @@ window_copy_line_number_mode(struct window_mode_entry *wme) struct window_pane *wp = wme->wp; struct window_copy_mode_data *data = wme->data; struct options *oo = wp->window->options; + int mode; if (!data->line_numbers) return (WINDOW_COPY_LINE_NUMBERS_OFF); - return (options_get_number(oo, "copy-mode-line-numbers")); + mode = options_get_number(oo, "copy-mode-line-numbers"); + if (data->line_numbers == 2 && mode == WINDOW_COPY_LINE_NUMBERS_OFF) + return (WINDOW_COPY_LINE_NUMBERS_DEFAULT); + return (mode); } static int @@ -5155,14 +5204,33 @@ void window_copy_set_line_numbers(struct window_pane *wp, int enabled) { struct window_mode_entry *wme = TAILQ_FIRST(&wp->modes); - struct window_copy_mode_data *data; if (wme == NULL || wme->mode != &window_copy_mode) return; - data = wme->data; - if (data == NULL || data->line_numbers == enabled) + window_copy_set_line_numbers1(wme, enabled, 0); +} + +static void +window_copy_set_line_numbers1(struct window_mode_entry *wme, int enabled, + int force) +{ + struct window_copy_mode_data *data = wme->data; + struct options *oo = wme->wp->window->options; + int active, line_numbers; + + if (data == NULL) return; - data->line_numbers = enabled; + active = window_copy_line_numbers_active(wme); + if (!enabled) + line_numbers = 0; + else if (force && options_get_number(oo, "copy-mode-line-numbers") == + WINDOW_COPY_LINE_NUMBERS_OFF) + line_numbers = 2; + else + line_numbers = 1; + if (data->line_numbers == line_numbers && active == enabled) + return; + data->line_numbers = line_numbers; window_copy_redraw_screen(wme, 1); }