mirror of
https://github.com/tmux/tmux.git
synced 2026-10-09 11:44:23 +00:00
Add formats and events for OSC 133 commmands, as well as a -T flag to
set-hook -B to only fire when the format is true.
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: cmd-set-option.c,v 1.145 2026/07/10 13:38:45 nicm Exp $ */
|
/* $OpenBSD: cmd-set-option.c,v 1.146 2026/07/10 15:20:06 nicm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||||
@@ -66,8 +66,8 @@ const struct cmd_entry cmd_set_hook_entry = {
|
|||||||
.name = "set-hook",
|
.name = "set-hook",
|
||||||
.alias = NULL,
|
.alias = NULL,
|
||||||
|
|
||||||
.args = { "agpERt:uB:w", 0, 2, cmd_set_option_args_parse },
|
.args = { "agpERTt:uB:w", 0, 2, cmd_set_option_args_parse },
|
||||||
.usage = "[-agpERuw] [-B name:what:format] " CMD_TARGET_PANE_USAGE " "
|
.usage = "[-agpERTuw] [-B name:what:format] " CMD_TARGET_PANE_USAGE " "
|
||||||
"[hook] [command]",
|
"[hook] [command]",
|
||||||
|
|
||||||
.target = { 't', CMD_FIND_PANE, CMD_FIND_CANFAIL },
|
.target = { 't', CMD_FIND_PANE, CMD_FIND_CANFAIL },
|
||||||
@@ -143,7 +143,7 @@ cmd_set_hook_monitor_exec(struct cmdq_item *item, struct args *args, int window)
|
|||||||
char *expanded = NULL, *newvalue = NULL;
|
char *expanded = NULL, *newvalue = NULL;
|
||||||
const char *value, *old;
|
const char *value, *old;
|
||||||
enum monitor_type type;
|
enum monitor_type type;
|
||||||
int id, scope;
|
int id, scope, flags = 0;
|
||||||
|
|
||||||
if (args_count(args) > 1) {
|
if (args_count(args) > 1) {
|
||||||
cmdq_error(item, "too many arguments");
|
cmdq_error(item, "too many arguments");
|
||||||
@@ -204,7 +204,9 @@ cmd_set_hook_monitor_exec(struct cmdq_item *item, struct args *args, int window)
|
|||||||
oo != global_s_options &&
|
oo != global_s_options &&
|
||||||
oo != global_w_options)
|
oo != global_w_options)
|
||||||
s = target->s;
|
s = target->s;
|
||||||
hooks_monitor_add(item, oo, name, type, id, format, &fs, s);
|
if (args_has(args, 'T'))
|
||||||
|
flags |= MONITOR_NOTIFY_TRUE;
|
||||||
|
hooks_monitor_add(item, oo, name, type, id, format, flags, &fs, s);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
free(newvalue);
|
free(newvalue);
|
||||||
|
|||||||
123
format.c
123
format.c
@@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: format.c,v 1.402 2026/07/09 06:33:19 nicm Exp $ */
|
/* $OpenBSD: format.c,v 1.403 2026/07/10 15:20:06 nicm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2011 Nicholas Marriott <nicholas.marriott@gmail.com>
|
* Copyright (c) 2011 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||||
@@ -2173,6 +2173,106 @@ format_cb_pane_dead_time(struct format_tree *ft)
|
|||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Callback for pane_last_output_time. */
|
||||||
|
static void *
|
||||||
|
format_cb_pane_last_output_time(struct format_tree *ft)
|
||||||
|
{
|
||||||
|
struct window_pane *wp = ft->wp;
|
||||||
|
static struct timeval tv;
|
||||||
|
|
||||||
|
if (wp != NULL && wp->last_output_time != 0) {
|
||||||
|
tv.tv_sec = wp->last_output_time;
|
||||||
|
tv.tv_usec = 0;
|
||||||
|
return (&tv);
|
||||||
|
}
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Callback for pane_last_prompt_time. */
|
||||||
|
static void *
|
||||||
|
format_cb_pane_last_prompt_time(struct format_tree *ft)
|
||||||
|
{
|
||||||
|
struct window_pane *wp = ft->wp;
|
||||||
|
static struct timeval tv;
|
||||||
|
|
||||||
|
if (wp != NULL && wp->last_prompt_time != 0) {
|
||||||
|
tv.tv_sec = wp->last_prompt_time;
|
||||||
|
tv.tv_usec = 0;
|
||||||
|
return (&tv);
|
||||||
|
}
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Callback for pane_command_start_time. */
|
||||||
|
static void *
|
||||||
|
format_cb_pane_command_start_time(struct format_tree *ft)
|
||||||
|
{
|
||||||
|
struct window_pane *wp = ft->wp;
|
||||||
|
static struct timeval tv;
|
||||||
|
|
||||||
|
if (wp != NULL && wp->cmd_start_time != 0) {
|
||||||
|
tv.tv_sec = wp->cmd_start_time;
|
||||||
|
tv.tv_usec = 0;
|
||||||
|
return (&tv);
|
||||||
|
}
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Callback for pane_command_end_time. */
|
||||||
|
static void *
|
||||||
|
format_cb_pane_command_end_time(struct format_tree *ft)
|
||||||
|
{
|
||||||
|
struct window_pane *wp = ft->wp;
|
||||||
|
static struct timeval tv;
|
||||||
|
|
||||||
|
if (wp != NULL && wp->cmd_end_time != 0) {
|
||||||
|
tv.tv_sec = wp->cmd_end_time;
|
||||||
|
tv.tv_usec = 0;
|
||||||
|
return (&tv);
|
||||||
|
}
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Callback for pane_command_running. */
|
||||||
|
static void *
|
||||||
|
format_cb_pane_command_running(struct format_tree *ft)
|
||||||
|
{
|
||||||
|
struct window_pane *wp = ft->wp;
|
||||||
|
|
||||||
|
if (wp != NULL)
|
||||||
|
return (format_printf("%d", !!(wp->flags & PANE_CMDRUNNING)));
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Callback for pane_command_duration. */
|
||||||
|
static void *
|
||||||
|
format_cb_pane_command_duration(struct format_tree *ft)
|
||||||
|
{
|
||||||
|
struct window_pane *wp = ft->wp;
|
||||||
|
time_t end;
|
||||||
|
|
||||||
|
if (wp == NULL || wp->cmd_start_time == 0)
|
||||||
|
return (NULL);
|
||||||
|
if (wp->flags & PANE_CMDRUNNING)
|
||||||
|
end = time(NULL);
|
||||||
|
else
|
||||||
|
end = wp->cmd_end_time;
|
||||||
|
if (end < wp->cmd_start_time)
|
||||||
|
end = wp->cmd_start_time;
|
||||||
|
return (format_printf("%lld", (long long)(end - wp->cmd_start_time)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Callback for pane_command_status. */
|
||||||
|
static void *
|
||||||
|
format_cb_pane_command_status(struct format_tree *ft)
|
||||||
|
{
|
||||||
|
struct window_pane *wp = ft->wp;
|
||||||
|
|
||||||
|
if (wp != NULL && wp->cmd_status != -1)
|
||||||
|
return (format_printf("%d", wp->cmd_status));
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
/* Callback for pane_format. */
|
/* Callback for pane_format. */
|
||||||
static void *
|
static void *
|
||||||
format_cb_pane_format(struct format_tree *ft)
|
format_cb_pane_format(struct format_tree *ft)
|
||||||
@@ -3485,6 +3585,21 @@ static const struct format_table_entry format_table[] = {
|
|||||||
{ "pane_bottom", FORMAT_TABLE_STRING,
|
{ "pane_bottom", FORMAT_TABLE_STRING,
|
||||||
format_cb_pane_bottom
|
format_cb_pane_bottom
|
||||||
},
|
},
|
||||||
|
{ "pane_command_duration", FORMAT_TABLE_STRING,
|
||||||
|
format_cb_pane_command_duration
|
||||||
|
},
|
||||||
|
{ "pane_command_end_time", FORMAT_TABLE_TIME,
|
||||||
|
format_cb_pane_command_end_time
|
||||||
|
},
|
||||||
|
{ "pane_command_running", FORMAT_TABLE_STRING,
|
||||||
|
format_cb_pane_command_running
|
||||||
|
},
|
||||||
|
{ "pane_command_start_time", FORMAT_TABLE_TIME,
|
||||||
|
format_cb_pane_command_start_time
|
||||||
|
},
|
||||||
|
{ "pane_command_status", FORMAT_TABLE_STRING,
|
||||||
|
format_cb_pane_command_status
|
||||||
|
},
|
||||||
{ "pane_current_command", FORMAT_TABLE_STRING,
|
{ "pane_current_command", FORMAT_TABLE_STRING,
|
||||||
format_cb_current_command
|
format_cb_current_command
|
||||||
},
|
},
|
||||||
@@ -3536,6 +3651,12 @@ static const struct format_table_entry format_table[] = {
|
|||||||
{ "pane_last", FORMAT_TABLE_STRING,
|
{ "pane_last", FORMAT_TABLE_STRING,
|
||||||
format_cb_pane_last
|
format_cb_pane_last
|
||||||
},
|
},
|
||||||
|
{ "pane_last_output_time", FORMAT_TABLE_TIME,
|
||||||
|
format_cb_pane_last_output_time
|
||||||
|
},
|
||||||
|
{ "pane_last_prompt_time", FORMAT_TABLE_TIME,
|
||||||
|
format_cb_pane_last_prompt_time
|
||||||
|
},
|
||||||
{ "pane_left", FORMAT_TABLE_STRING,
|
{ "pane_left", FORMAT_TABLE_STRING,
|
||||||
format_cb_pane_left
|
format_cb_pane_left
|
||||||
},
|
},
|
||||||
|
|||||||
6
hooks.c
6
hooks.c
@@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: hooks.c,v 1.12 2026/07/10 13:38:45 nicm Exp $ */
|
/* $OpenBSD: hooks.c,v 1.13 2026/07/10 15:20:06 nicm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2026 Nicholas Marriott <nicholas.marriott@gmail.com>
|
* Copyright (c) 2026 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||||
@@ -407,7 +407,7 @@ hooks_monitor_cb(struct monitor_change *change, void *data)
|
|||||||
void
|
void
|
||||||
hooks_monitor_add(__unused struct cmdq_item *item, struct options *oo,
|
hooks_monitor_add(__unused struct cmdq_item *item, struct options *oo,
|
||||||
const char *name, enum monitor_type type, int id, const char *format,
|
const char *name, enum monitor_type type, int id, const char *format,
|
||||||
struct cmd_find_state *fs, struct session *s)
|
int flags, struct cmd_find_state *fs, struct session *s)
|
||||||
{
|
{
|
||||||
struct options_entry *o;
|
struct options_entry *o;
|
||||||
struct hook_monitor *hm;
|
struct hook_monitor *hm;
|
||||||
@@ -426,7 +426,7 @@ hooks_monitor_add(__unused struct cmdq_item *item, struct options *oo,
|
|||||||
hm->set = monitor_create_session(s, hooks_monitor_cb, hm);
|
hm->set = monitor_create_session(s, hooks_monitor_cb, hm);
|
||||||
hm->sink = events_add_sink(name, hooks_monitor_hook_cb, hm);
|
hm->sink = events_add_sink(name, hooks_monitor_hook_cb, hm);
|
||||||
options_set_monitor_data(o, hm);
|
options_set_monitor_data(o, hm);
|
||||||
monitor_add(hm->set, name, type, id, format, 0);
|
monitor_add(hm->set, name, type, id, format, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Convert a hook monitor to its value. */
|
/* Convert a hook monitor to its value. */
|
||||||
|
|||||||
87
input.c
87
input.c
@@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: input.c,v 1.265 2026/07/10 13:38:45 nicm Exp $ */
|
/* $OpenBSD: input.c,v 1.266 2026/07/10 15:20:06 nicm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||||
@@ -1034,6 +1034,8 @@ input_parse_pane(struct window_pane *wp)
|
|||||||
size_t new_size;
|
size_t new_size;
|
||||||
|
|
||||||
new_data = window_pane_get_new_data(wp, &wp->offset, &new_size);
|
new_data = window_pane_get_new_data(wp, &wp->offset, &new_size);
|
||||||
|
if (new_size != 0)
|
||||||
|
wp->last_output_time = time(NULL);
|
||||||
input_parse_buffer(wp, new_data, new_size);
|
input_parse_buffer(wp, new_data, new_size);
|
||||||
window_pane_update_used_data(wp, &wp->offset, new_size);
|
window_pane_update_used_data(wp, &wp->offset, new_size);
|
||||||
}
|
}
|
||||||
@@ -3126,7 +3128,8 @@ input_osc_12(struct input_ctx *ictx, const char *p)
|
|||||||
c = ictx->ctx.s->ccolour;
|
c = ictx->ctx.s->ccolour;
|
||||||
if (c == -1)
|
if (c == -1)
|
||||||
c = ictx->ctx.s->default_ccolour;
|
c = ictx->ctx.s->default_ccolour;
|
||||||
input_osc_colour_reply(ictx, 1, 12, 0, c, ictx->input_end);
|
input_osc_colour_reply(ictx, 1, 12, 0, c,
|
||||||
|
ictx->input_end);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -3146,24 +3149,92 @@ input_osc_112(struct input_ctx *ictx, const char *p)
|
|||||||
screen_set_cursor_colour(ictx->ctx.s, -1);
|
screen_set_cursor_colour(ictx->ctx.s, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Fire an OSC 133 command event. */
|
||||||
|
static void
|
||||||
|
input_fire_command_event(struct window_pane *wp, const char *name)
|
||||||
|
{
|
||||||
|
struct event_payload *ep;
|
||||||
|
struct cmd_find_state fs;
|
||||||
|
time_t tstart = wp->cmd_start_time, end;
|
||||||
|
time_t tend = wp->cmd_end_time;
|
||||||
|
|
||||||
|
ep = event_payload_create();
|
||||||
|
cmd_find_from_pane(&fs, wp, 0);
|
||||||
|
event_payload_set_target(ep, &fs);
|
||||||
|
if (fs.s != NULL)
|
||||||
|
event_payload_set_session(ep, "session", fs.s);
|
||||||
|
if (fs.wl != NULL)
|
||||||
|
event_payload_set_int(ep, "window_index", fs.wl->idx);
|
||||||
|
event_payload_set_window(ep, "window", wp->window);
|
||||||
|
event_payload_set_pane(ep, "pane", wp);
|
||||||
|
|
||||||
|
if (wp->cmd_status != -1)
|
||||||
|
event_payload_set_int(ep, "command_status", wp->cmd_status);
|
||||||
|
if (tstart != 0)
|
||||||
|
event_payload_set_time(ep, "command_start_time", tstart);
|
||||||
|
if (tend != 0)
|
||||||
|
event_payload_set_time(ep, "command_end_time", tend);
|
||||||
|
|
||||||
|
if (tstart != 0) {
|
||||||
|
if (wp->flags & PANE_CMDRUNNING)
|
||||||
|
end = time(NULL);
|
||||||
|
else
|
||||||
|
end = tend;
|
||||||
|
if (end < tstart)
|
||||||
|
end = tstart;
|
||||||
|
end -= tstart;
|
||||||
|
event_payload_set_uint(ep, "command_duration", end);
|
||||||
|
}
|
||||||
|
|
||||||
|
events_fire(name, ep);
|
||||||
|
}
|
||||||
|
|
||||||
/* Handle the OSC 133 sequence. */
|
/* Handle the OSC 133 sequence. */
|
||||||
static void
|
static void
|
||||||
input_osc_133(struct input_ctx *ictx, const char *p)
|
input_osc_133(struct input_ctx *ictx, const char *p)
|
||||||
{
|
{
|
||||||
|
struct window_pane *wp = ictx->wp;
|
||||||
struct grid *gd = ictx->ctx.s->grid;
|
struct grid *gd = ictx->ctx.s->grid;
|
||||||
u_int line = ictx->ctx.s->cy + gd->hsize;
|
u_int line = ictx->ctx.s->cy + gd->hsize;
|
||||||
struct grid_line *gl;
|
struct grid_line *gl = NULL;
|
||||||
|
const char *errstr;
|
||||||
|
int status;
|
||||||
|
|
||||||
if (line > gd->hsize + gd->sy - 1)
|
if (line <= gd->hsize + gd->sy - 1)
|
||||||
return;
|
gl = grid_get_line(gd, line);
|
||||||
gl = grid_get_line(gd, line);
|
|
||||||
|
|
||||||
switch (*p) {
|
switch (*p) {
|
||||||
case 'A':
|
case 'A':
|
||||||
gl->flags |= GRID_LINE_START_PROMPT;
|
if (gl != NULL)
|
||||||
|
gl->flags |= GRID_LINE_START_PROMPT;
|
||||||
|
if (wp != NULL) {
|
||||||
|
wp->last_prompt_time = time(NULL);
|
||||||
|
events_fire_pane("pane-shell-prompt", wp);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 'C':
|
case 'C':
|
||||||
gl->flags |= GRID_LINE_START_OUTPUT;
|
if (gl != NULL)
|
||||||
|
gl->flags |= GRID_LINE_START_OUTPUT;
|
||||||
|
if (wp != NULL) {
|
||||||
|
wp->cmd_start_time = time(NULL);
|
||||||
|
wp->cmd_end_time = 0;
|
||||||
|
wp->flags |= PANE_CMDRUNNING;
|
||||||
|
wp->cmd_status = -1;
|
||||||
|
input_fire_command_event(wp, "pane-command-started");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'D':
|
||||||
|
if (wp != NULL) {
|
||||||
|
wp->cmd_end_time = time(NULL);
|
||||||
|
wp->flags &= ~PANE_CMDRUNNING;
|
||||||
|
wp->cmd_status = -1;
|
||||||
|
if (p[1] == ';' && p[2] != '\0') {
|
||||||
|
status = strtonum(p + 2, 0, INT_MAX, &errstr);
|
||||||
|
if (errstr == NULL)
|
||||||
|
wp->cmd_status = status;
|
||||||
|
}
|
||||||
|
input_fire_command_event(wp, "pane-command-finished");
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
13
monitor.c
13
monitor.c
@@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: monitor.c,v 1.5 2026/07/10 13:38:45 nicm Exp $ */
|
/* $OpenBSD: monitor.c,v 1.6 2026/07/10 15:20:06 nicm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2026 Nicholas Marriott <nicholas.marriott@gmail.com>
|
* Copyright (c) 2026 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||||
@@ -53,7 +53,7 @@ struct monitor_item {
|
|||||||
|
|
||||||
enum monitor_type type;
|
enum monitor_type type;
|
||||||
u_int id;
|
u_int id;
|
||||||
u_int flags;
|
int flags;
|
||||||
|
|
||||||
char *last;
|
char *last;
|
||||||
struct monitor_panes panes;
|
struct monitor_panes panes;
|
||||||
@@ -198,7 +198,9 @@ monitor_check_value(struct monitor_set *ms, struct monitor_item *me,
|
|||||||
{
|
{
|
||||||
if (*last == NULL) {
|
if (*last == NULL) {
|
||||||
*last = value;
|
*last = value;
|
||||||
if (me->flags & MONITOR_NOTIFY_INITIAL)
|
if ((me->flags & MONITOR_NOTIFY_INITIAL) &&
|
||||||
|
((~me->flags & MONITOR_NOTIFY_TRUE) ||
|
||||||
|
format_true(value)))
|
||||||
monitor_report(ms, me, s, wl, wp, value, NULL);
|
monitor_report(ms, me, s, wl, wp, value, NULL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -208,7 +210,8 @@ monitor_check_value(struct monitor_set *ms, struct monitor_item *me,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
monitor_report(ms, me, s, wl, wp, value, *last);
|
if ((~me->flags & MONITOR_NOTIFY_TRUE) || format_true(value))
|
||||||
|
monitor_report(ms, me, s, wl, wp, value, *last);
|
||||||
free(*last);
|
free(*last);
|
||||||
*last = value;
|
*last = value;
|
||||||
}
|
}
|
||||||
@@ -621,7 +624,7 @@ fail:
|
|||||||
/* Add a subscription. */
|
/* Add a subscription. */
|
||||||
void
|
void
|
||||||
monitor_add(struct monitor_set *ms, const char *name, enum monitor_type type,
|
monitor_add(struct monitor_set *ms, const char *name, enum monitor_type type,
|
||||||
int id, const char *format, u_int flags)
|
int id, const char *format, int flags)
|
||||||
{
|
{
|
||||||
struct monitor_item *me, find = { .name = (char *)name };
|
struct monitor_item *me, find = { .name = (char *)name };
|
||||||
struct timeval tv = { .tv_sec = 1 };
|
struct timeval tv = { .tv_sec = 1 };
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: options-table.c,v 1.232 2026/07/10 13:38:45 nicm Exp $ */
|
/* $OpenBSD: options-table.c,v 1.233 2026/07/10 15:20:06 nicm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2011 Nicholas Marriott <nicholas.marriott@gmail.com>
|
* Copyright (c) 2011 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||||
@@ -1934,6 +1934,8 @@ const struct options_table_entry options_table[] = {
|
|||||||
OPTIONS_TABLE_HOOK("client-dark-theme", ""),
|
OPTIONS_TABLE_HOOK("client-dark-theme", ""),
|
||||||
OPTIONS_TABLE_HOOK("command-error", ""),
|
OPTIONS_TABLE_HOOK("command-error", ""),
|
||||||
OPTIONS_TABLE_HOOK("marked-pane-changed", ""),
|
OPTIONS_TABLE_HOOK("marked-pane-changed", ""),
|
||||||
|
OPTIONS_TABLE_PANE_HOOK("pane-command-finished", ""),
|
||||||
|
OPTIONS_TABLE_PANE_HOOK("pane-command-started", ""),
|
||||||
OPTIONS_TABLE_PANE_HOOK("pane-created", ""),
|
OPTIONS_TABLE_PANE_HOOK("pane-created", ""),
|
||||||
OPTIONS_TABLE_PANE_HOOK("pane-died", ""),
|
OPTIONS_TABLE_PANE_HOOK("pane-died", ""),
|
||||||
OPTIONS_TABLE_PANE_HOOK("pane-exited", ""),
|
OPTIONS_TABLE_PANE_HOOK("pane-exited", ""),
|
||||||
@@ -1946,6 +1948,7 @@ const struct options_table_entry options_table[] = {
|
|||||||
OPTIONS_TABLE_PANE_HOOK("pane-prompt-opened", ""),
|
OPTIONS_TABLE_PANE_HOOK("pane-prompt-opened", ""),
|
||||||
OPTIONS_TABLE_PANE_HOOK("pane-resized", ""),
|
OPTIONS_TABLE_PANE_HOOK("pane-resized", ""),
|
||||||
OPTIONS_TABLE_PANE_HOOK("pane-set-clipboard", ""),
|
OPTIONS_TABLE_PANE_HOOK("pane-set-clipboard", ""),
|
||||||
|
OPTIONS_TABLE_PANE_HOOK("pane-shell-prompt", ""),
|
||||||
OPTIONS_TABLE_PANE_HOOK("pane-title-changed", ""),
|
OPTIONS_TABLE_PANE_HOOK("pane-title-changed", ""),
|
||||||
OPTIONS_TABLE_HOOK("session-closed", ""),
|
OPTIONS_TABLE_HOOK("session-closed", ""),
|
||||||
OPTIONS_TABLE_HOOK("session-created", ""),
|
OPTIONS_TABLE_HOOK("session-created", ""),
|
||||||
|
|||||||
29
tmux.1
29
tmux.1
@@ -1,4 +1,4 @@
|
|||||||
.\" $OpenBSD: tmux.1,v 1.1131 2026/07/10 13:38:45 nicm Exp $
|
.\" $OpenBSD: tmux.1,v 1.1132 2026/07/10 15:20:06 nicm Exp $
|
||||||
.\"
|
.\"
|
||||||
.\" Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
.\" Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||||
.\"
|
.\"
|
||||||
@@ -6359,6 +6359,17 @@ Run when a client switches to a dark theme.
|
|||||||
Run when a command fails.
|
Run when a command fails.
|
||||||
.It marked\-pane\-changed
|
.It marked\-pane\-changed
|
||||||
Run when the marked pane is set or cleared.
|
Run when the marked pane is set or cleared.
|
||||||
|
.It pane\-command\-finished
|
||||||
|
Run when an OSC 133 command finishes in a pane.
|
||||||
|
The event payload includes
|
||||||
|
.Ql hook_command_start_time ,
|
||||||
|
.Ql hook_command_end_time ,
|
||||||
|
.Ql hook_command_duration
|
||||||
|
and
|
||||||
|
.Ql hook_command_status
|
||||||
|
if present.
|
||||||
|
.It pane\-command\-started
|
||||||
|
Run when an OSC 133 command starts in a pane.
|
||||||
.It pane\-created
|
.It pane\-created
|
||||||
Run when a pane is created or respawned.
|
Run when a pane is created or respawned.
|
||||||
.It pane\-died
|
.It pane\-died
|
||||||
@@ -6391,6 +6402,8 @@ Run when a pane is resized.
|
|||||||
Run when the terminal clipboard is set using the
|
Run when the terminal clipboard is set using the
|
||||||
.Xr xterm 1
|
.Xr xterm 1
|
||||||
escape sequence.
|
escape sequence.
|
||||||
|
.It pane\-shell\-prompt
|
||||||
|
Run when an OSC 133 shell prompt starts in a pane.
|
||||||
.It pane\-title\-changed
|
.It pane\-title\-changed
|
||||||
Run when a pane title is changed.
|
Run when a pane title is changed.
|
||||||
.It session\-closed
|
.It session\-closed
|
||||||
@@ -6425,7 +6438,7 @@ Run when a window is unlinked from a session.
|
|||||||
Hooks are managed with these commands:
|
Hooks are managed with these commands:
|
||||||
.Bl -tag -width Ds
|
.Bl -tag -width Ds
|
||||||
.It Xo Ic set\-hook
|
.It Xo Ic set\-hook
|
||||||
.Op Fl agpERuw
|
.Op Fl agpERTuw
|
||||||
.Op Fl B Ar name:what:format
|
.Op Fl B Ar name:what:format
|
||||||
.Op Fl t Ar target\-pane
|
.Op Fl t Ar target\-pane
|
||||||
.Ar hook\-name
|
.Ar hook\-name
|
||||||
@@ -6456,6 +6469,11 @@ is the hook to run,
|
|||||||
selects the session, pane, all panes, window, or all windows, and
|
selects the session, pane, all panes, window, or all windows, and
|
||||||
.Ar format
|
.Ar format
|
||||||
is expanded once a second.
|
is expanded once a second.
|
||||||
|
With
|
||||||
|
.Fl T ,
|
||||||
|
the hook is run only when
|
||||||
|
.Ar format
|
||||||
|
is true.
|
||||||
For monitor hooks,
|
For monitor hooks,
|
||||||
.Ar name
|
.Ar name
|
||||||
must begin with
|
must begin with
|
||||||
@@ -7191,6 +7209,11 @@ The following variables are available, where appropriate:
|
|||||||
.It Li "pane_at_top" Ta "" Ta "1 if pane is at the top of window"
|
.It Li "pane_at_top" Ta "" Ta "1 if pane is at the top of window"
|
||||||
.It Li "pane_bg" Ta "" Ta "Pane background colour"
|
.It Li "pane_bg" Ta "" Ta "Pane background colour"
|
||||||
.It Li "pane_bottom" Ta "" Ta "Bottom of pane"
|
.It Li "pane_bottom" Ta "" Ta "Bottom of pane"
|
||||||
|
.It Li "pane_command_duration" Ta "" Ta "Current or most recent OSC 133 command duration in seconds"
|
||||||
|
.It Li "pane_command_end_time" Ta "" Ta "Time most recent OSC 133 command ended"
|
||||||
|
.It Li "pane_command_running" Ta "" Ta "1 if an OSC 133 command is running"
|
||||||
|
.It Li "pane_command_start_time" Ta "" Ta "Time current or most recent OSC 133 command started"
|
||||||
|
.It Li "pane_command_status" Ta "" Ta "Exit status from most recent OSC 133 command"
|
||||||
.It Li "pane_current_command" Ta "" Ta "Current command if available"
|
.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_current_path" Ta "" Ta "Current path if available"
|
||||||
.It Li "pane_dead" Ta "" Ta "1 if pane is dead"
|
.It Li "pane_dead" Ta "" Ta "1 if pane is dead"
|
||||||
@@ -7208,6 +7231,8 @@ The following variables are available, where appropriate:
|
|||||||
.It Li "pane_input_off" Ta "" Ta "1 if input to pane is disabled"
|
.It Li "pane_input_off" Ta "" Ta "1 if input to pane is disabled"
|
||||||
.It Li "pane_key_mode" Ta "" Ta "Extended key reporting mode in this pane"
|
.It Li "pane_key_mode" Ta "" Ta "Extended key reporting mode in this pane"
|
||||||
.It Li "pane_last" Ta "" Ta "1 if last pane"
|
.It Li "pane_last" Ta "" Ta "1 if last pane"
|
||||||
|
.It Li "pane_last_output_time" Ta "" Ta "Time pane last produced output"
|
||||||
|
.It Li "pane_last_prompt_time" Ta "" Ta "Time most recent OSC 133 prompt began"
|
||||||
.It Li "pane_left" Ta "" Ta "Left of pane"
|
.It Li "pane_left" Ta "" Ta "Left of pane"
|
||||||
.It Li "pane_marked" Ta "" Ta "1 if this is the marked pane"
|
.It Li "pane_marked" Ta "" Ta "1 if this is the marked pane"
|
||||||
.It Li "pane_marked_set" Ta "" Ta "1 if a marked pane is set"
|
.It Li "pane_marked_set" Ta "" Ta "1 if a marked pane is set"
|
||||||
|
|||||||
14
tmux.h
14
tmux.h
@@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: tmux.h,v 1.1394 2026/07/10 13:38:45 nicm Exp $ */
|
/* $OpenBSD: tmux.h,v 1.1395 2026/07/10 15:20:06 nicm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||||
@@ -1267,6 +1267,7 @@ struct window_pane {
|
|||||||
#define PANE_UNSEENCHANGES 0x4000
|
#define PANE_UNSEENCHANGES 0x4000
|
||||||
#define PANE_REDRAWSCROLLBAR 0x8000
|
#define PANE_REDRAWSCROLLBAR 0x8000
|
||||||
#define PANE_DESTROYED 0x10000
|
#define PANE_DESTROYED 0x10000
|
||||||
|
#define PANE_CMDRUNNING 0x20000
|
||||||
|
|
||||||
bitstr_t *sync_dirty;
|
bitstr_t *sync_dirty;
|
||||||
u_int sync_dirty_size;
|
u_int sync_dirty_size;
|
||||||
@@ -1289,6 +1290,12 @@ struct window_pane {
|
|||||||
struct cmdq_item *wait_item; /* new-pane -W: waiting for pane exit */
|
struct cmdq_item *wait_item; /* new-pane -W: waiting for pane exit */
|
||||||
struct spawn_editor_state *editor;
|
struct spawn_editor_state *editor;
|
||||||
|
|
||||||
|
time_t last_output_time;
|
||||||
|
time_t last_prompt_time;
|
||||||
|
time_t cmd_start_time;
|
||||||
|
time_t cmd_end_time;
|
||||||
|
int cmd_status;
|
||||||
|
|
||||||
int fd;
|
int fd;
|
||||||
struct bufferevent *event;
|
struct bufferevent *event;
|
||||||
|
|
||||||
@@ -2293,6 +2300,7 @@ enum monitor_type {
|
|||||||
MONITOR_ALL_WINDOWS
|
MONITOR_ALL_WINDOWS
|
||||||
};
|
};
|
||||||
#define MONITOR_NOTIFY_INITIAL 0x1
|
#define MONITOR_NOTIFY_INITIAL 0x1
|
||||||
|
#define MONITOR_NOTIFY_TRUE 0x2
|
||||||
struct monitor_change {
|
struct monitor_change {
|
||||||
const char *name;
|
const char *name;
|
||||||
const char *value;
|
const char *value;
|
||||||
@@ -2699,7 +2707,7 @@ void hooks_build_events(void);
|
|||||||
void hooks_run(struct cmdq_item *, const char *);
|
void hooks_run(struct cmdq_item *, const char *);
|
||||||
void hooks_monitor_add(struct cmdq_item *, struct options *,
|
void hooks_monitor_add(struct cmdq_item *, struct options *,
|
||||||
const char *, enum monitor_type, int, const char *,
|
const char *, enum monitor_type, int, const char *,
|
||||||
struct cmd_find_state *, struct session *);
|
int, struct cmd_find_state *, struct session *);
|
||||||
void hooks_monitor_remove(struct options *, const char *);
|
void hooks_monitor_remove(struct options *, const char *);
|
||||||
void hooks_monitor_free(void *);
|
void hooks_monitor_free(void *);
|
||||||
char *hooks_monitor_to_string(struct options_entry *);
|
char *hooks_monitor_to_string(struct options_entry *);
|
||||||
@@ -3901,7 +3909,7 @@ void monitor_destroy(struct monitor_set *);
|
|||||||
int monitor_parse(const char *, char **, enum monitor_type *, int *,
|
int monitor_parse(const char *, char **, enum monitor_type *, int *,
|
||||||
char **);
|
char **);
|
||||||
void monitor_add(struct monitor_set *, const char *, enum monitor_type, int,
|
void monitor_add(struct monitor_set *, const char *, enum monitor_type, int,
|
||||||
const char *, u_int);
|
const char *, int);
|
||||||
void monitor_remove(struct monitor_set *, const char *);
|
void monitor_remove(struct monitor_set *, const char *);
|
||||||
|
|
||||||
/* control.c */
|
/* control.c */
|
||||||
|
|||||||
3
window.c
3
window.c
@@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: window.c,v 1.359 2026/07/10 13:38:45 nicm Exp $ */
|
/* $OpenBSD: window.c,v 1.360 2026/07/10 15:20:06 nicm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||||
@@ -1177,6 +1177,7 @@ window_pane_create(struct window *w, u_int sx, u_int sy, u_int hlimit)
|
|||||||
wp->window = w;
|
wp->window = w;
|
||||||
wp->options = options_create(w->options);
|
wp->options = options_create(w->options);
|
||||||
wp->flags = PANE_STYLECHANGED;
|
wp->flags = PANE_STYLECHANGED;
|
||||||
|
wp->cmd_status = -1;
|
||||||
|
|
||||||
wp->id = next_window_pane_id++;
|
wp->id = next_window_pane_id++;
|
||||||
RB_INSERT(window_pane_tree, &all_window_panes, wp);
|
RB_INSERT(window_pane_tree, &all_window_panes, wp);
|
||||||
|
|||||||
Reference in New Issue
Block a user