diff options
-rw-r--r-- | usr.bin/tmux/format.c | 39 | ||||
-rw-r--r-- | usr.bin/tmux/options-table.c | 15 | ||||
-rw-r--r-- | usr.bin/tmux/server-fn.c | 44 | ||||
-rw-r--r-- | usr.bin/tmux/tmux.1 | 9 | ||||
-rw-r--r-- | usr.bin/tmux/tmux.h | 3 |
5 files changed, 82 insertions, 28 deletions
diff --git a/usr.bin/tmux/format.c b/usr.bin/tmux/format.c index d1cbe7b56c9..9a2ab01ebbc 100644 --- a/usr.bin/tmux/format.c +++ b/usr.bin/tmux/format.c @@ -1,4 +1,4 @@ -/* $OpenBSD: format.c,v 1.301 2022/03/08 11:28:40 nicm Exp $ */ +/* $OpenBSD: format.c,v 1.302 2022/03/08 18:31:46 nicm Exp $ */ /* * Copyright (c) 2011 Nicholas Marriott <nicholas.marriott@gmail.com> @@ -1756,6 +1756,23 @@ format_cb_pane_dead(struct format_tree *ft) return (NULL); } +/* Callback for pane_dead_signal. */ +static void * +format_cb_pane_dead_signal(struct format_tree *ft) +{ + struct window_pane *wp = ft->wp; + const char *name; + + if (wp != NULL) { + if ((wp->flags & PANE_STATUSREADY) && WIFSIGNALED(wp->status)) { + name = sig2name(WTERMSIG(wp->status)); + return (format_printf("%s", name)); + } + return (NULL); + } + return (NULL); +} + /* Callback for pane_dead_status. */ static void * format_cb_pane_dead_status(struct format_tree *ft) @@ -1770,6 +1787,20 @@ format_cb_pane_dead_status(struct format_tree *ft) return (NULL); } +/* Callback for pane_dead_time. */ +static void * +format_cb_pane_dead_time(struct format_tree *ft) +{ + struct window_pane *wp = ft->wp; + + if (wp != NULL) { + if (wp->flags & PANE_STATUSDRAWN) + return (&wp->dead_time); + return (NULL); + } + return (NULL); +} + /* Callback for pane_format. */ static void * format_cb_pane_format(struct format_tree *ft) @@ -2804,9 +2835,15 @@ static const struct format_table_entry format_table[] = { { "pane_dead", FORMAT_TABLE_STRING, format_cb_pane_dead }, + { "pane_dead_signal", FORMAT_TABLE_STRING, + format_cb_pane_dead_signal + }, { "pane_dead_status", FORMAT_TABLE_STRING, format_cb_pane_dead_status }, + { "pane_dead_time", FORMAT_TABLE_TIME, + format_cb_pane_dead_time + }, { "pane_fg", FORMAT_TABLE_STRING, format_cb_pane_fg }, diff --git a/usr.bin/tmux/options-table.c b/usr.bin/tmux/options-table.c index 231161e12f3..e73e2ab66d4 100644 --- a/usr.bin/tmux/options-table.c +++ b/usr.bin/tmux/options-table.c @@ -1,4 +1,4 @@ -/* $OpenBSD: options-table.c,v 1.158 2022/02/17 09:58:47 nicm Exp $ */ +/* $OpenBSD: options-table.c,v 1.159 2022/03/08 18:31:46 nicm Exp $ */ /* * Copyright (c) 2011 Nicholas Marriott <nicholas.marriott@gmail.com> @@ -1061,6 +1061,19 @@ const struct options_table_entry options_table[] = { "killed ('off' or 'failed') when the program inside exits." }, + { .name = "remain-on-exit-format", + .type = OPTIONS_TABLE_STRING, + .scope = OPTIONS_TABLE_WINDOW|OPTIONS_TABLE_PANE, + .default_str = "Pane is dead (" + "#{?#{!=:#{pane_dead_status},}," + "status #{pane_dead_status},}" + "#{?#{!=:#{pane_dead_signal},}," + "signal #{pane_dead_signal},}, " + "#{t:pane_dead_time})", + .text = "Message shown after the program in a pane has exited, if " + "remain-on-exit is enabled." + }, + { .name = "synchronize-panes", .type = OPTIONS_TABLE_FLAG, .scope = OPTIONS_TABLE_WINDOW|OPTIONS_TABLE_PANE, diff --git a/usr.bin/tmux/server-fn.c b/usr.bin/tmux/server-fn.c index 525f3613d6a..36c7231ddd0 100644 --- a/usr.bin/tmux/server-fn.c +++ b/usr.bin/tmux/server-fn.c @@ -1,4 +1,4 @@ -/* $OpenBSD: server-fn.c,v 1.132 2021/08/17 16:19:00 nicm Exp $ */ +/* $OpenBSD: server-fn.c,v 1.133 2022/03/08 18:31:46 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com> @@ -312,9 +312,11 @@ server_destroy_pane(struct window_pane *wp, int notify) struct window *w = wp->window; struct screen_write_ctx ctx; struct grid_cell gc; - time_t t; - char tim[26]; int remain_on_exit; + const char *s; + char *expanded; + u_int sx = screen_size_x(&wp->base); + u_int sy = screen_size_y(&wp->base); if (wp->fd != -1) { bufferevent_free(wp->event); @@ -338,32 +340,26 @@ server_destroy_pane(struct window_pane *wp, int notify) return; wp->flags |= PANE_STATUSDRAWN; + gettimeofday(&wp->dead_time, NULL); if (notify) notify_pane("pane-died", wp); - screen_write_start_pane(&ctx, wp, &wp->base); - screen_write_scrollregion(&ctx, 0, screen_size_y(ctx.s) - 1); - screen_write_cursormove(&ctx, 0, screen_size_y(ctx.s) - 1, 0); - screen_write_linefeed(&ctx, 1, 8); - memcpy(&gc, &grid_default_cell, sizeof gc); - - time(&t); - ctime_r(&t, tim); - tim[strcspn(tim, "\n")] = '\0'; - - if (WIFEXITED(wp->status)) { - screen_write_nputs(&ctx, -1, &gc, - "Pane is dead (status %d, %s)", - WEXITSTATUS(wp->status), - tim); - } else if (WIFSIGNALED(wp->status)) { - screen_write_nputs(&ctx, -1, &gc, - "Pane is dead (signal %s, %s)", - sig2name(WTERMSIG(wp->status)), - tim); + s = options_get_string(wp->options, "remain-on-exit-format"); + if (*s != '\0') { + screen_write_start_pane(&ctx, wp, &wp->base); + screen_write_scrollregion(&ctx, 0, sy - 1); + screen_write_cursormove(&ctx, 0, sy - 1, 0); + screen_write_linefeed(&ctx, 1, 8); + memcpy(&gc, &grid_default_cell, sizeof gc); + + expanded = format_single(NULL, s, NULL, NULL, NULL, wp); + format_draw(&ctx, &gc, sx, expanded, NULL, 0); + free(expanded); + + screen_write_stop(&ctx); } + wp->base.mode &= ~MODE_CURSOR; - screen_write_stop(&ctx); wp->flags |= PANE_REDRAW; return; } diff --git a/usr.bin/tmux/tmux.1 b/usr.bin/tmux/tmux.1 index 743bd645efe..6e180a69146 100644 --- a/usr.bin/tmux/tmux.1 +++ b/usr.bin/tmux/tmux.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: tmux.1,v 1.881 2022/03/08 12:01:19 nicm Exp $ +.\" $OpenBSD: tmux.1,v 1.882 2022/03/08 18:31:46 nicm Exp $ .\" .\" Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com> .\" @@ -4468,6 +4468,11 @@ The pane may be reactivated with the .Ic respawn-pane command. .Pp +.It Ic remain-on-exit-format Ar string +Set the text shown at the bottom of exited panes when +.Ic remain-on-exit +is enabled. +.Pp .It Xo Ic synchronize-panes .Op Ic on | off .Xc @@ -5117,7 +5122,9 @@ The following variables are available, where appropriate: .It Li "pane_current_command" Ta "" Ta "Current command if available" .It Li "pane_current_path" Ta "" Ta "Current path if available" .It Li "pane_dead" Ta "" Ta "1 if pane is dead" +.It Li "pane_dead_signal" Ta "" Ta "Exit signal of process in dead pane" .It Li "pane_dead_status" Ta "" Ta "Exit status of process in dead pane" +.It Li "pane_dead_time" Ta "" Ta "Exit time of process in dead pane" .It Li "pane_fg" Ta "" Ta "Pane foreground colour" .It Li "pane_format" Ta "" Ta "1 if format is for a pane" .It Li "pane_height" Ta "" Ta "Height of pane" diff --git a/usr.bin/tmux/tmux.h b/usr.bin/tmux/tmux.h index d88f9cb1a02..ccdb6188086 100644 --- a/usr.bin/tmux/tmux.h +++ b/usr.bin/tmux/tmux.h @@ -1,4 +1,4 @@ -/* $OpenBSD: tmux.h,v 1.1163 2022/03/08 12:01:19 nicm Exp $ */ +/* $OpenBSD: tmux.h,v 1.1164 2022/03/08 18:31:47 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com> @@ -1026,6 +1026,7 @@ struct window_pane { pid_t pid; char tty[TTY_NAME_MAX]; int status; + struct timeval dead_time; int fd; struct bufferevent *event; |