summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authornicm <nicm>2022-03-08 18:31:46 +0000
committernicm <nicm>2022-03-08 18:31:46 +0000
commita3d920930bf77cafa5260e25584dd3ba1d26f9cb (patch)
tree8b8515e1a02da155fb1c6d7acd506747efb7de58
parentad9b8059836d424f70a8579d28e28e0186cdbaa6 (diff)
Add remain-on-exit-format to set text shown when pane is dead.
-rw-r--r--format.c37
-rw-r--r--options-table.c13
-rw-r--r--server-fn.c42
-rw-r--r--tmux.17
-rw-r--r--tmux.h1
5 files changed, 77 insertions, 23 deletions
diff --git a/format.c b/format.c
index f381a0ec..981161b3 100644
--- a/format.c
+++ b/format.c
@@ -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/options-table.c b/options-table.c
index 6d136f76..d1bc3577 100644
--- a/options-table.c
+++ b/options-table.c
@@ -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/server-fn.c b/server-fn.c
index b29bc15c..2e9665f5 100644
--- a/server-fn.c
+++ b/server-fn.c
@@ -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/tmux.1 b/tmux.1
index 215d825c..d204e454 100644
--- a/tmux.1
+++ b/tmux.1
@@ -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/tmux.h b/tmux.h
index 0700f1b9..77c3b176 100644
--- a/tmux.h
+++ b/tmux.h
@@ -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;