Merge branch 'obsd-master'

This commit is contained in:
Thomas Adam
2026-06-08 22:00:07 +01:00
10 changed files with 117 additions and 40 deletions

View File

@@ -33,8 +33,8 @@ const struct cmd_entry cmd_choose_tree_entry = {
.name = "choose-tree",
.alias = NULL,
.args = { "F:f:GK:NO:rst:wyZ", 0, 1, cmd_choose_tree_args_parse },
.usage = "[-GNrswZ] [-F format] [-f filter] [-K key-format] "
.args = { "F:f:GK:kNO:rst:wyZ", 0, 1, cmd_choose_tree_args_parse },
.usage = "[-GkNrswZ] [-F format] [-f filter] [-K key-format] "
"[-O sort-order] " CMD_TARGET_PANE_USAGE " [template]",
.target = { 't', CMD_FIND_PANE, 0 },
@@ -47,8 +47,8 @@ const struct cmd_entry cmd_choose_client_entry = {
.name = "choose-client",
.alias = NULL,
.args = { "F:f:K:NO:rt:yZ", 0, 1, cmd_choose_tree_args_parse },
.usage = "[-NrZ] [-F format] [-f filter] [-K key-format] "
.args = { "F:f:K:kNO:rt:yZ", 0, 1, cmd_choose_tree_args_parse },
.usage = "[-kNrZ] [-F format] [-f filter] [-K key-format] "
"[-O sort-order] " CMD_TARGET_PANE_USAGE " [template]",
.target = { 't', CMD_FIND_PANE, 0 },
@@ -61,8 +61,8 @@ const struct cmd_entry cmd_choose_buffer_entry = {
.name = "choose-buffer",
.alias = NULL,
.args = { "F:f:K:NO:rt:yZ", 0, 1, cmd_choose_tree_args_parse },
.usage = "[-NrZ] [-F format] [-f filter] [-K key-format] "
.args = { "F:f:K:kNO:rt:yZ", 0, 1, cmd_choose_tree_args_parse },
.usage = "[-kNrZ] [-F format] [-f filter] [-K key-format] "
"[-O sort-order] " CMD_TARGET_PANE_USAGE " [template]",
.target = { 't', CMD_FIND_PANE, 0 },
@@ -75,8 +75,8 @@ const struct cmd_entry cmd_customize_mode_entry = {
.name = "customize-mode",
.alias = NULL,
.args = { "F:f:Nt:yZ", 0, 0, NULL },
.usage = "[-NZ] [-F format] [-f filter] " CMD_TARGET_PANE_USAGE,
.args = { "F:f:kNt:yZ", 0, 0, NULL },
.usage = "[-kNZ] [-F format] [-f filter] " CMD_TARGET_PANE_USAGE,
.target = { 't', CMD_FIND_PANE, 0 },

View File

@@ -76,6 +76,40 @@ cmd_display_panes_put(struct screen_redraw_ctx *ctx,
}
}
static void
cmd_display_panes_draw_format(struct screen_redraw_ctx *ctx,
struct window_pane *wp, u_int xoff, u_int yoff, u_int sx,
const struct grid_cell *gc)
{
struct client *c = ctx->c;
struct tty *tty = &c->tty;
struct session *s = c->session;
struct screen screen;
struct screen_write_ctx sctx;
struct visible_ranges *r;
struct visible_range *ri;
const char *format;
char *expanded;
u_int i, px = ctx->ox + xoff;
format = options_get_string(s->options, "display-panes-format");
expanded = format_single(NULL, format, c, s, s->curw, wp);
screen_init(&screen, sx, 1, 0);
screen_write_start(&sctx, &screen);
format_draw(&sctx, gc, sx, expanded, NULL, 0);
screen_write_stop(&sctx);
free(expanded);
r = screen_redraw_get_visible_ranges(wp, px, wp->yoff, sx, NULL);
for (i = 0; i < r->used; i++) {
ri = &r->ranges[i];
tty_draw_line(tty, &screen, ri->px - px, 0, ri->nx,
ri->px - ctx->ox, yoff, gc, NULL);
}
screen_free(&screen);
}
static void
cmd_display_panes_draw_pane(struct screen_redraw_ctx *ctx,
struct window_pane *wp)
@@ -89,8 +123,8 @@ cmd_display_panes_draw_pane(struct screen_redraw_ctx *ctx,
u_int pane, idx, px, py, i, j, xoff, yoff, sx, sy;
u_int cx, cy;
int colour, active_colour;
char buf[16], lbuf[16], rbuf[16], *ptr;
size_t len, llen, rlen;
char buf[16], lbuf[16], *ptr;
size_t len, llen;
if (wp->xoff + (int)wp->sx <= ctx->ox ||
wp->xoff >= ctx->ox + (int)ctx->sx ||
@@ -159,7 +193,6 @@ cmd_display_panes_draw_pane(struct screen_redraw_ctx *ctx,
bgc.bg = colour;
}
rlen = xsnprintf(rbuf, sizeof rbuf, "%ux%u", wp->sx, wp->sy);
if (pane > 9 && pane < 35)
llen = xsnprintf(lbuf, sizeof lbuf, "%c", 'a' + (pane - 10));
else
@@ -207,13 +240,9 @@ cmd_display_panes_draw_pane(struct screen_redraw_ctx *ctx,
if (sy <= 6)
goto out;
tty_attributes(tty, &fgc, &grid_default_cell, NULL, NULL);
if (rlen != 0 && sx >= rlen) {
cx = xoff + sx - rlen;
cy = yoff;
cmd_display_panes_put(ctx, wp, cx, cy, rbuf, rlen);
}
cmd_display_panes_draw_format(ctx, wp, xoff, yoff, sx, &fgc);
if (llen != 0) {
tty_attributes(tty, &fgc, &grid_default_cell, NULL, NULL);
cx = xoff + sx / 2 + len * 3 - llen - 1;
cy = yoff + py + 5;
cmd_display_panes_put(ctx, wp, cx, cy, lbuf, llen);

View File

@@ -38,11 +38,11 @@ const struct cmd_entry cmd_new_pane_entry = {
.name = "new-pane",
.alias = "newp",
.args = { "bc:de:EfF:hIkl:Lm:p:PR:s:S:t:vx:X:y:Y:Z", 0, -1, NULL },
.args = { "bc:de:EfF:hIkl:Lm:p:PR:s:S:t:T:vx:X:y:Y:Z", 0, -1, NULL },
.usage = "[-bdefhIklPvZ] [-c start-directory] [-e environment] "
"[-F format] [-l size] [-m message] [-p percentage] "
"[-s style] [-S active-border-style] "
"[-R inactive-border-style] [-x width] [-y height] "
"[-R inactive-border-style] [-T title] [-x width] [-y height] "
"[-X x-position] [-Y y-position] " CMD_TARGET_PANE_USAGE " "
"[shell-command [argument ...]]",
@@ -56,11 +56,11 @@ const struct cmd_entry cmd_split_window_entry = {
.name = "split-window",
.alias = "splitw",
.args = { "bc:de:EfF:hIkl:m:p:PR:s:S:t:vZ", 0, -1, NULL },
.args = { "bc:de:EfF:hIkl:m:p:PR:s:S:t:T:vZ", 0, -1, NULL },
.usage = "[-bdefhIklPvZ] [-c start-directory] [-e environment] "
"[-F format] [-l size] [-m message] [-p percentage] "
"[-s style] [-S active-border-style] "
"[-R inactive-border-style] " CMD_TARGET_PANE_USAGE " "
"[-R inactive-border-style] [-T title] " CMD_TARGET_PANE_USAGE " "
"[shell-command [argument ...]]",
.target = { 't', CMD_FIND_PANE, 0 },
@@ -85,7 +85,7 @@ cmd_split_window_exec(struct cmd *self, struct cmdq_item *item)
struct cmd_find_state fs;
int input, empty, is_floating, flags = 0;
const char *template, *style;
char *cause = NULL, *cp;
char *cause = NULL, *cp, *title;
struct args_value *av;
u_int count = args_count(args);
@@ -194,6 +194,12 @@ cmd_split_window_exec(struct cmd *self, struct cmdq_item *item)
"remain-on-exit-format",
0, "%s", args_get(args, 'm'));
}
if (args_has(args, 'T')) {
title = format_single_from_target(item, args_get(args, 'T'));
screen_set_title(&new_wp->base, title);
notify_pane("pane-title-changed", new_wp);
free(title);
}
if (input) {
switch (window_pane_start_input(new_wp, item, &cause)) {

View File

@@ -647,6 +647,14 @@ const struct options_table_entry options_table[] = {
.text = "Colour of not active panes for 'display-panes'."
},
{ .name = "display-panes-format",
.type = OPTIONS_TABLE_STRING,
.scope = OPTIONS_TABLE_SESSION,
.default_str = "#[align=right]#{pane_width}x#{pane_height}",
.text = "Format of text shown by 'display-panes', expanded for each "
"pane."
},
{ .name = "display-panes-time",
.type = OPTIONS_TABLE_NUMBER,
.scope = OPTIONS_TABLE_SESSION,

View File

@@ -2916,16 +2916,22 @@ void
screen_write_alternateon(struct screen_write_ctx *ctx, struct grid_cell *gc,
int cursor)
{
struct tty_ctx ttyctx;
struct window_pane *wp = ctx->wp;
struct tty_ctx ttyctx;
struct window_pane *wp = ctx->wp;
struct window_pane_resize *r, *r1;
if (wp != NULL && !options_get_number(wp->options, "alternate-screen"))
return;
screen_write_collect_flush(ctx, 0, __func__);
screen_alternate_on(ctx->s, gc, cursor);
if (!screen_alternate_on(ctx->s, gc, cursor))
return;
if (wp != NULL) {
TAILQ_FOREACH_SAFE (r, &wp->resize_queue, entry, r1) {
TAILQ_REMOVE(&wp->resize_queue, r, entry);
free(r);
}
layout_fix_panes(wp->window, NULL);
server_redraw_window_borders(wp->window);
}
@@ -2947,7 +2953,8 @@ screen_write_alternateoff(struct screen_write_ctx *ctx, struct grid_cell *gc,
return;
screen_write_collect_flush(ctx, 0, __func__);
screen_alternate_off(ctx->s, gc, cursor);
if (!screen_alternate_off(ctx->s, gc, cursor))
return;
if (wp != NULL) {
layout_fix_panes(wp->window, NULL);

View File

@@ -672,7 +672,7 @@ screen_reflow(struct screen *s, u_int new_x, u_int *cx, u_int *cy, int cursor)
* Enter alternative screen mode. A copy of the visible screen is saved and the
* history is not updated.
*/
void
int
screen_alternate_on(struct screen *s, struct grid_cell *gc, int cursor)
{
u_int sx, sy;
@@ -681,7 +681,7 @@ screen_alternate_on(struct screen *s, struct grid_cell *gc, int cursor)
#endif
if (SCREEN_IS_ALTERNATE(s))
return;
return 0;
sx = screen_size_x(s);
sy = screen_size_y(s);
@@ -703,10 +703,12 @@ screen_alternate_on(struct screen *s, struct grid_cell *gc, int cursor)
s->saved_flags = s->grid->flags;
s->grid->flags &= ~GRID_HISTORY;
return 1;
}
/* Exit alternate screen mode and restore the copied grid. */
void
int
screen_alternate_off(struct screen *s, struct grid_cell *gc, int cursor)
{
u_int sx = screen_size_x(s), sy = screen_size_y(s);
@@ -738,7 +740,7 @@ screen_alternate_off(struct screen *s, struct grid_cell *gc, int cursor)
s->cx = screen_size_x(s) - 1;
if (s->cy > screen_size_y(s) - 1)
s->cy = screen_size_y(s) - 1;
return;
return 0;
}
/* Restore the saved grid. */
@@ -767,6 +769,8 @@ screen_alternate_off(struct screen *s, struct grid_cell *gc, int cursor)
s->cx = screen_size_x(s) - 1;
if (s->cy > screen_size_y(s) - 1)
s->cy = screen_size_y(s) - 1;
return 1;
}
/* Get mode as a string. */

View File

@@ -1586,10 +1586,7 @@ server_client_resize_timer(__unused int fd, __unused short events, void *data)
static void
server_client_check_pane_resize(struct window_pane *wp)
{
struct window_pane_resize *r;
struct window_pane_resize *r1;
struct window_pane_resize *first;
struct window_pane_resize *last;
struct window_pane_resize *r, *r1, *first, *last;
struct timeval tv = { .tv_usec = 250000 };
if (TAILQ_EMPTY(&wp->resize_queue))

26
tmux.1
View File

@@ -2743,7 +2743,7 @@ the end of the visible pane.
The default is to capture only the visible contents of the pane.
.It Xo
.Ic choose\-client
.Op Fl NryZ
.Op Fl kNryZ
.Op Fl F Ar format
.Op Fl f Ar filter
.Op Fl K Ar key\-format
@@ -2816,10 +2816,12 @@ specifies the format for each item in the list and
a format for each shortcut key; both are evaluated once for each line.
.Fl N
starts without the preview or if given twice with the larger preview.
.Fl k
kills the pane when the mode is exited.
This command works only if at least one client is attached.
.It Xo
.Ic choose\-tree
.Op Fl GNrswyZ
.Op Fl GkNrswyZ
.Op Fl F Ar format
.Op Fl f Ar filter
.Op Fl K Ar key\-format
@@ -2909,10 +2911,12 @@ starts without the preview or if given twice with the larger preview.
.Fl G
includes all sessions in any session groups in the tree rather than only the
first.
.Fl k
kills the pane when the mode is exited.
This command works only if at least one client is attached.
.It Xo
.Ic customize\-mode
.Op Fl NZ
.Op Fl kNZ
.Op Fl F Ar format
.Op Fl f Ar filter
.Op Fl t Ar target\-pane
@@ -2960,6 +2964,8 @@ If a filter would lead to an empty list, it is ignored.
specifies the format for each item in the tree.
.Fl N
starts without the option information.
.Fl k
kills the pane when the mode is exited.
This command works only if at least one client is attached.
.It Xo
.Tg displayp
@@ -3341,6 +3347,7 @@ but a different format may be specified with
.Op Fl s Ar style
.Op Fl S Ar active\-border\-style
.Op Fl t Ar target\-pane
.Op Fl T Ar title
.Op Ar shell\-command Op Ar argument ...
.Xc
.D1 Pq alias: Ic newp
@@ -3359,6 +3366,8 @@ sets the border style when the pane is active and
.Fl R
sets the border style when the pane is inactive (see
.Sx STYLES ) .
.Fl T
sets the pane title.
.Pp
.Fl h
does a horizontal split and
@@ -3756,6 +3765,7 @@ the command behaves like
.Op Fl s Ar style
.Op Fl S Ar active\-border\-style
.Op Fl t Ar target\-pane
.Op Fl T Ar title
.Op Ar shell\-command Op Ar argument ...
.Xc
.D1 Pq alias: Ic splitw
@@ -4794,6 +4804,12 @@ command to show the indicator for the active pane.
Set the colour used by the
.Ic display\-panes
command to show the indicators for inactive panes.
.It Ic display\-panes\-format Ar format
Set the
.Ar format
of the text shown by the
.Ic display\-panes
command, expanded for each pane.
.It Ic display\-panes\-time Ar time
Set the time in milliseconds for which the indicators shown by the
.Ic display\-panes
@@ -7617,7 +7633,7 @@ The buffer commands are as follows:
.Bl -tag -width Ds
.It Xo
.Ic choose\-buffer
.Op Fl NryZ
.Op Fl kNryZ
.Op Fl F Ar format
.Op Fl f Ar filter
.Op Fl K Ar key\-format
@@ -7688,6 +7704,8 @@ specifies the format for each item in the list and
a format for each shortcut key; both are evaluated once for each line.
.Fl N
starts without the preview.
.Fl k
kills the pane when the mode is exited.
This command works only if at least one client is attached.
.Tg clearhist
.It Xo Ic clear\-history

6
tmux.h
View File

@@ -1181,6 +1181,8 @@ struct window_mode_entry {
struct screen *screen;
u_int prefix;
int kill;
TAILQ_ENTRY(window_mode_entry) entry;
};
@@ -3388,8 +3390,8 @@ void screen_hide_selection(struct screen *);
int screen_check_selection(struct screen *, u_int, u_int);
int screen_select_cell(struct screen *, struct grid_cell *,
const struct grid_cell *);
void screen_alternate_on(struct screen *, struct grid_cell *, int);
void screen_alternate_off(struct screen *, struct grid_cell *, int);
int screen_alternate_on(struct screen *, struct grid_cell *, int);
int screen_alternate_off(struct screen *, struct grid_cell *, int);
const char *screen_mode_to_string(int);
const char *screen_print(struct screen *, int);

View File

@@ -1224,6 +1224,7 @@ window_pane_set_mode(struct window_pane *wp, struct window_pane *swp,
TAILQ_INSERT_HEAD(&wp->modes, wme, entry);
wme->screen = wme->mode->init(wme, fs, args);
}
wme->kill = args_has(args, 'k');
wp->screen = wme->screen;
wp->flags |= (PANE_REDRAW|PANE_REDRAWSCROLLBAR|PANE_CHANGED);
@@ -1241,11 +1242,13 @@ window_pane_reset_mode(struct window_pane *wp)
{
struct window_mode_entry *wme, *next;
struct window *w = wp->window;
int kill;
if (TAILQ_EMPTY(&wp->modes))
return;
wme = TAILQ_FIRST(&wp->modes);
kill = wme->kill;
TAILQ_REMOVE(&wp->modes, wme, entry);
wme->mode->free(wme);
free(wme);
@@ -1268,6 +1271,9 @@ window_pane_reset_mode(struct window_pane *wp)
server_redraw_window_borders(wp->window);
server_status_window(wp->window);
notify_pane("pane-mode-changed", wp);
if (kill)
server_kill_pane(wp);
}
void