Add remain-on-exit-format to set text shown when pane is dead.

pull/3160/head
nicm 2022-03-08 18:31:46 +00:00 committed by Nicholas Marriott
parent 57f331438a
commit 98b92c0525
5 changed files with 75 additions and 21 deletions

View File

@ -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
},

View File

@ -1060,6 +1060,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,

View File

@ -310,9 +310,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) {
#ifdef HAVE_UTEMPTER
@ -339,32 +341,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);
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);
time(&t);
ctime_r(&t, tim);
tim[strcspn(tim, "\n")] = '\0';
expanded = format_single(NULL, s, NULL, NULL, NULL, wp);
format_draw(&ctx, &gc, sx, expanded, NULL, 0);
free(expanded);
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);
screen_write_stop(&ctx);
}
wp->base.mode &= ~MODE_CURSOR;
screen_write_stop(&ctx);
wp->flags |= PANE_REDRAW;
return;
}

7
tmux.1
View File

@ -4471,6 +4471,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
@ -5120,7 +5125,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"

1
tmux.h
View File

@ -1027,6 +1027,7 @@ struct window_pane {
pid_t pid;
char tty[TTY_NAME_MAX];
int status;
struct timeval dead_time;
int fd;
struct bufferevent *event;