mirror of
https://github.com/tmux/tmux.git
synced 2026-10-08 10:54:28 +00:00
Merge remote-tracking branch 'refs/remotes/tmux-openbsd/master'
* refs/remotes/tmux-openbsd/master: Show match count in copy mode, GitHub issue 5399. Add window-default-command option to override default-command per window, from Meriel Sartha Mittelbach. Do not change active pane if joining a pane to the same window. Reported by David le Blanc.
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: cmd-join-pane.c,v 1.76 2026/10/02 12:48:52 nicm Exp $ */
|
||||
/* $OpenBSD: cmd-join-pane.c,v 1.77 2026/10/07 12:02:21 nicm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2011 George Nachman <tmux@georgester.com>
|
||||
@@ -503,7 +503,8 @@ cmd_join_pane_exec(struct cmd *self, struct cmdq_item *item)
|
||||
layout_close_pane(src_wp);
|
||||
|
||||
server_client_remove_pane(src_wp);
|
||||
window_lost_pane(src_w, src_wp);
|
||||
if (src_w != dst_w)
|
||||
window_lost_pane(src_w, src_wp);
|
||||
TAILQ_REMOVE(&src_w->panes, src_wp, entry);
|
||||
TAILQ_REMOVE(&src_w->z_index, src_wp, zentry);
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: options-table.c,v 1.249 2026/10/05 09:03:11 nicm Exp $ */
|
||||
/* $OpenBSD: options-table.c,v 1.251 2026/10/07 12:59:50 nicm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2011 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
@@ -1414,8 +1414,12 @@ const struct options_table_entry options_table[] = {
|
||||
"#{t/p:top_line_time}#{?#{e|>:#{top_line_time},0}, ,}"
|
||||
"[#{copy_position}/#{copy_position_limit}]"
|
||||
"#{?search_timed_out, (timed out),"
|
||||
"#{?search_count, (#{search_count}"
|
||||
"#{?search_count_partial,+,} results),}}",
|
||||
"#{?search_count_present, ("
|
||||
"#{?#{==:#{search_count},0},0 matches,"
|
||||
"#{?search_count_partial,#{search_count}+ matches,"
|
||||
"#{?#{==:#{search_count},1},1 of 1 match,"
|
||||
"#{?search_count_current,#{search_count_current} of "
|
||||
"#{search_count} matches,#{search_count} matches}}}}),}}",
|
||||
.text = "Format of the position indicator in copy mode."
|
||||
},
|
||||
|
||||
@@ -1777,6 +1781,14 @@ const struct options_table_entry options_table[] = {
|
||||
.text = "Default style of the active pane."
|
||||
},
|
||||
|
||||
{ .name = "window-default-command",
|
||||
.type = OPTIONS_TABLE_STRING,
|
||||
.scope = OPTIONS_TABLE_WINDOW,
|
||||
.default_str = "",
|
||||
.text = "Default command to run in new panes. If set, "
|
||||
"overrides 'default-command'."
|
||||
},
|
||||
|
||||
{ .name = "window-pane-current-status-format",
|
||||
.type = OPTIONS_TABLE_STRING,
|
||||
.scope = OPTIONS_TABLE_WINDOW,
|
||||
|
||||
6
spawn.c
6
spawn.c
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: spawn.c,v 1.54 2026/10/02 13:20:42 nicm Exp $ */
|
||||
/* $OpenBSD: spawn.c,v 1.55 2026/10/07 12:55:41 nicm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2019 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
@@ -377,7 +377,9 @@ spawn_pane(struct spawn_context *sc, char **cause)
|
||||
* directory.
|
||||
*/
|
||||
if (sc->argc == 0 && (~sc->flags & SPAWN_RESPAWN)) {
|
||||
cmd = options_get_string(s->options, "default-command");
|
||||
cmd = options_get_string(w->options, "window-default-command");
|
||||
if (cmd == NULL || *cmd == '\0')
|
||||
cmd = options_get_string(s->options, "default-command");
|
||||
if (cmd != NULL && *cmd != '\0') {
|
||||
argc = 1;
|
||||
argv = (char **)&cmd;
|
||||
|
||||
13
tmux.1
13
tmux.1
@@ -1,4 +1,4 @@
|
||||
.\" $OpenBSD: tmux.1,v 1.1177 2026/10/06 17:45:26 schwarze Exp $
|
||||
.\" $OpenBSD: tmux.1,v 1.1179 2026/10/07 12:59:50 nicm Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
.\"
|
||||
@@ -14,7 +14,7 @@
|
||||
.\" IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
.\" OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.Dd $Mdocdate: October 6 2026 $
|
||||
.Dd $Mdocdate: October 7 2026 $
|
||||
.Dt TMUX 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
@@ -3621,6 +3621,8 @@ is the command to execute.
|
||||
If
|
||||
.Ar shell\-command
|
||||
is not specified, the value of the
|
||||
.Ic window\-default\-command
|
||||
or
|
||||
.Ic default\-command
|
||||
option is used.
|
||||
.Fl c
|
||||
@@ -6181,6 +6183,11 @@ see the
|
||||
.Sx STYLES
|
||||
section.
|
||||
.Pp
|
||||
.It Ic window\-default\-command Ar shell\-command
|
||||
Per-window version of the
|
||||
.Ic default\-command
|
||||
option.
|
||||
.Pp
|
||||
.It Ic window\-status\-activity\-style Ar style
|
||||
Set status line style for windows with an activity alert.
|
||||
For how to specify
|
||||
@@ -7483,7 +7490,9 @@ The following variables are available, where appropriate:
|
||||
.It Li "scroll_region_lower" Ta "" Ta "Bottom of scroll region in pane"
|
||||
.It Li "scroll_region_upper" Ta "" Ta "Top of scroll region in pane"
|
||||
.It Li "search_count" Ta "" Ta "Count of search results"
|
||||
.It Li "search_count_current" Ta "" Ta "Index of the current search result"
|
||||
.It Li "search_count_partial" Ta "" Ta "1 if search count is partial count"
|
||||
.It Li "search_count_present" Ta "" Ta "1 if search count is available"
|
||||
.It Li "search_match" Ta "" Ta "Search match if any"
|
||||
.It Li "search_present" Ta "" Ta "1 if search started in copy mode"
|
||||
.It Li "selection_active" Ta "" Ta "1 if selection started and changes with the cursor in copy mode"
|
||||
|
||||
119
window-copy.c
119
window-copy.c
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: window-copy.c,v 1.435 2026/10/06 08:26:23 nicm Exp $ */
|
||||
/* $OpenBSD: window-copy.c,v 1.436 2026/10/07 12:59:50 nicm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
@@ -87,6 +87,10 @@ static int window_copy_last_regex(struct grid *, u_int, u_int, u_int,
|
||||
int);
|
||||
static int window_copy_search_mark_at(struct window_copy_mode_data *,
|
||||
u_int, u_int, u_int *);
|
||||
static int window_copy_grow_searchpos(struct window_copy_mode_data *,
|
||||
u_int, u_int, u_int);
|
||||
static void window_copy_search_set_index(struct window_copy_mode_data *,
|
||||
u_int, u_int);
|
||||
static char *window_copy_stringify(struct grid *, u_int, u_int, u_int,
|
||||
char *, u_int *);
|
||||
static void window_copy_cstrtocellpos(struct grid *, u_int, u_int *,
|
||||
@@ -341,6 +345,10 @@ struct window_copy_mode_data {
|
||||
char *searchstr;
|
||||
u_char *searchmark;
|
||||
int searchcount;
|
||||
int searchindex;
|
||||
u_int *searchpos;
|
||||
u_int searchposcount;
|
||||
u_int searchpossize;
|
||||
int searchmore;
|
||||
int searchall;
|
||||
int searchx;
|
||||
@@ -581,6 +589,8 @@ window_copy_common_init(struct window_mode_entry *wme)
|
||||
data->searchstr = NULL;
|
||||
}
|
||||
data->searchx = data->searchy = data->searcho = -1;
|
||||
data->searchcount = -1;
|
||||
data->searchindex = -1;
|
||||
data->searchall = 1;
|
||||
|
||||
data->jumptype = WINDOW_COPY_OFF;
|
||||
@@ -682,6 +692,7 @@ window_copy_free(struct window_mode_entry *wme)
|
||||
evtimer_del(&data->refresh_timer);
|
||||
|
||||
free(data->searchmark);
|
||||
free(data->searchpos);
|
||||
free(data->searchstr);
|
||||
free(data->jumpchar);
|
||||
|
||||
@@ -1168,8 +1179,12 @@ window_copy_formats(struct window_mode_entry *wme, struct format_tree *ft)
|
||||
format_add(ft, "search_present", "%d", data->searchmark != NULL);
|
||||
format_add(ft, "search_timed_out", "%d", data->timeout);
|
||||
if (data->searchcount != -1) {
|
||||
format_add(ft, "search_count_present", "1");
|
||||
format_add(ft, "search_count", "%d", data->searchcount);
|
||||
format_add(ft, "search_count_partial", "%d", data->searchmore);
|
||||
if (data->searchindex != -1)
|
||||
format_add(ft, "search_count_current", "%d",
|
||||
data->searchindex);
|
||||
}
|
||||
format_add_cb(ft, "search_match", window_copy_search_match_cb);
|
||||
|
||||
@@ -1194,9 +1209,11 @@ window_copy_size_changed(struct window_mode_entry *wme)
|
||||
struct screen *s = &data->screen;
|
||||
struct screen_write_ctx ctx;
|
||||
int search = (data->searchmark != NULL);
|
||||
int searchindex = data->searchindex;
|
||||
|
||||
window_copy_clear_selection(wme);
|
||||
window_copy_clear_marks(wme);
|
||||
data->searchindex = searchindex;
|
||||
|
||||
screen_write_start(&ctx, s);
|
||||
window_copy_write_lines(wme, &ctx, 0, screen_size_y(s));
|
||||
@@ -2983,20 +3000,16 @@ window_copy_cmd_search_backward_incremental(struct window_copy_cmd_state *cs)
|
||||
data->searchregex = 0;
|
||||
free(data->searchstr);
|
||||
data->searchstr = xstrdup(arg0);
|
||||
if (!window_copy_search_up(wme, 0)) {
|
||||
window_copy_clear_marks(wme);
|
||||
if (!window_copy_search_up(wme, 0))
|
||||
return (WINDOW_COPY_CMD_REDRAW);
|
||||
}
|
||||
break;
|
||||
case '+':
|
||||
data->searchtype = WINDOW_COPY_SEARCHDOWN;
|
||||
data->searchregex = 0;
|
||||
free(data->searchstr);
|
||||
data->searchstr = xstrdup(arg0);
|
||||
if (!window_copy_search_down(wme, 0)) {
|
||||
window_copy_clear_marks(wme);
|
||||
if (!window_copy_search_down(wme, 0))
|
||||
return (WINDOW_COPY_CMD_REDRAW);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return (action);
|
||||
@@ -3040,20 +3053,16 @@ window_copy_cmd_search_forward_incremental(struct window_copy_cmd_state *cs)
|
||||
data->searchregex = 0;
|
||||
free(data->searchstr);
|
||||
data->searchstr = xstrdup(arg0);
|
||||
if (!window_copy_search_down(wme, 0)) {
|
||||
window_copy_clear_marks(wme);
|
||||
if (!window_copy_search_down(wme, 0))
|
||||
return (WINDOW_COPY_CMD_REDRAW);
|
||||
}
|
||||
break;
|
||||
case '-':
|
||||
data->searchtype = WINDOW_COPY_SEARCHUP;
|
||||
data->searchregex = 0;
|
||||
free(data->searchstr);
|
||||
data->searchstr = xstrdup(arg0);
|
||||
if (!window_copy_search_up(wme, 0)) {
|
||||
window_copy_clear_marks(wme);
|
||||
if (!window_copy_search_up(wme, 0))
|
||||
return (WINDOW_COPY_CMD_REDRAW);
|
||||
}
|
||||
}
|
||||
return (action);
|
||||
}
|
||||
@@ -4698,6 +4707,7 @@ window_copy_search(struct window_mode_entry *wme, int direction, int regex)
|
||||
return (0);
|
||||
|
||||
if (data->searchall || wp->searchstr == NULL ||
|
||||
data->searchpos == NULL ||
|
||||
wp->searchregex != regex) {
|
||||
visible_only = 0;
|
||||
data->searchall = 0;
|
||||
@@ -4775,8 +4785,8 @@ window_copy_search(struct window_mode_entry *wme, int direction, int regex)
|
||||
fx = data->cx;
|
||||
fy = screen_hsize(data->backing) - data->oy + data->cy;
|
||||
}
|
||||
|
||||
if (direction) {
|
||||
window_copy_search_set_index(data, fx, fy);
|
||||
/*
|
||||
* When in Emacs mode, position the cursor just after
|
||||
* the mark.
|
||||
@@ -4810,8 +4820,12 @@ window_copy_search(struct window_mode_entry *wme, int direction, int regex)
|
||||
window_copy_move_left(s, &fx, &fy, 0);
|
||||
}
|
||||
}
|
||||
fx = data->cx;
|
||||
fy = screen_hsize(data->backing) - data->oy + data->cy;
|
||||
window_copy_search_set_index(data, fx, fy);
|
||||
}
|
||||
}
|
||||
} else if (!visible_only)
|
||||
window_copy_search_marks(wme, &ss, regex, 0);
|
||||
window_copy_redraw_screen(wme);
|
||||
|
||||
screen_free(&ss);
|
||||
@@ -4854,6 +4868,51 @@ window_copy_clip_width(u_int width, u_int b, u_int sx, u_int sy)
|
||||
return ((b + width > sx * sy) ? (sx * sy) - b : width);
|
||||
}
|
||||
|
||||
static int
|
||||
window_copy_grow_searchpos(struct window_copy_mode_data *data, u_int px,
|
||||
u_int py, u_int sx)
|
||||
{
|
||||
u_int pos;
|
||||
|
||||
if (py > (UINT_MAX - px) / sx) {
|
||||
free(data->searchpos);
|
||||
data->searchpos = NULL;
|
||||
data->searchposcount = 0;
|
||||
data->searchpossize = 0;
|
||||
return (0);
|
||||
}
|
||||
if (data->searchposcount == data->searchpossize) {
|
||||
data->searchpossize *= 2;
|
||||
data->searchpos = xreallocarray(data->searchpos,
|
||||
data->searchpossize, sizeof *data->searchpos);
|
||||
}
|
||||
pos = py * sx + px;
|
||||
data->searchpos[data->searchposcount++] = pos;
|
||||
return (1);
|
||||
}
|
||||
|
||||
static void
|
||||
window_copy_search_set_index(struct window_copy_mode_data *data, u_int px,
|
||||
u_int py)
|
||||
{
|
||||
u_int position, left = 0, right = data->searchposcount, middle;
|
||||
u_int sx = data->backing->grid->sx;
|
||||
|
||||
data->searchindex = -1;
|
||||
if (py > (UINT_MAX - px) / sx)
|
||||
return;
|
||||
position = py * sx + px;
|
||||
while (left < right) {
|
||||
middle = left + ((right - left) / 2);
|
||||
if (data->searchpos[middle] < position)
|
||||
left = middle + 1;
|
||||
else
|
||||
right = middle;
|
||||
}
|
||||
if (left < data->searchposcount && data->searchpos[left] == position)
|
||||
data->searchindex = left + 1;
|
||||
}
|
||||
|
||||
static u_int
|
||||
window_copy_search_mark_match(struct window_copy_mode_data *data, u_int px,
|
||||
u_int py, u_int width, int regex)
|
||||
@@ -4894,7 +4953,8 @@ window_copy_search_marks(struct window_mode_entry *wme, struct screen *ssp,
|
||||
struct screen_write_ctx ctx;
|
||||
struct grid *gd = s->grid;
|
||||
struct grid_cell gc;
|
||||
int found, cis, stopped = 0;
|
||||
int found, cis, stopped = 0, oldindex;
|
||||
int trackpos = 0;
|
||||
int cflags = REG_EXTENDED;
|
||||
u_int px, py, nfound = 0, width;
|
||||
u_int ssize = 1, start, end, sx = gd->sx;
|
||||
@@ -4939,6 +4999,14 @@ window_copy_search_marks(struct window_mode_entry *wme, struct screen *ssp,
|
||||
start = 0;
|
||||
end = gd->hsize + sy;
|
||||
stop = get_timer() + WINDOW_COPY_SEARCH_ALL_TIMEOUT;
|
||||
oldindex = data->searchindex;
|
||||
data->searchindex = -1;
|
||||
free(data->searchpos);
|
||||
data->searchpos = xreallocarray(NULL, 64,
|
||||
sizeof *data->searchpos);
|
||||
data->searchposcount = 0;
|
||||
data->searchpossize = 64;
|
||||
trackpos = 1;
|
||||
}
|
||||
|
||||
again:
|
||||
@@ -4964,6 +5032,9 @@ again:
|
||||
break;
|
||||
}
|
||||
nfound++;
|
||||
if (!visible_only && trackpos)
|
||||
trackpos = window_copy_grow_searchpos(data, px, py,
|
||||
sx);
|
||||
px += window_copy_search_mark_match(data, px, py, width,
|
||||
regex);
|
||||
}
|
||||
@@ -4992,6 +5063,14 @@ again:
|
||||
|
||||
if (!visible_only) {
|
||||
if (stopped) {
|
||||
data->searchindex = -1;
|
||||
if (trackpos) {
|
||||
/* Keep this non-NULL to avoid another full search. */
|
||||
data->searchpos = xreallocarray(data->searchpos, 1,
|
||||
sizeof *data->searchpos);
|
||||
data->searchpossize = 1;
|
||||
}
|
||||
data->searchposcount = 0;
|
||||
if (nfound > 1000)
|
||||
data->searchcount = 1000;
|
||||
else if (nfound > 100)
|
||||
@@ -5004,6 +5083,9 @@ again:
|
||||
} else {
|
||||
data->searchcount = nfound;
|
||||
data->searchmore = 0;
|
||||
if (data->searchindex == -1 && oldindex > 0 &&
|
||||
oldindex <= data->searchcount)
|
||||
data->searchindex = oldindex;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5021,7 +5103,12 @@ window_copy_clear_marks(struct window_mode_entry *wme)
|
||||
struct window_copy_mode_data *data = wme->data;
|
||||
|
||||
data->searchcount = -1;
|
||||
data->searchindex = -1;
|
||||
data->searchmore = 0;
|
||||
free(data->searchpos);
|
||||
data->searchpos = NULL;
|
||||
data->searchposcount = 0;
|
||||
data->searchpossize = 0;
|
||||
|
||||
free(data->searchmark);
|
||||
data->searchmark = NULL;
|
||||
|
||||
Reference in New Issue
Block a user