From 9e21f426c0d5f24bda6c8a2e066c71388824716f Mon Sep 17 00:00:00 2001 From: nicm Date: Wed, 12 Nov 2025 07:53:22 +0000 Subject: [PATCH 1/3] Add a command to explcitly set the selection mode in copy mode, GitHub issue 3842. --- tmux.1 | 5 +++++ window-copy.c | 28 +++++++++++++++++++++++++--- 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/tmux.1 b/tmux.1 index 8b057120..e4c55d33 100644 --- a/tmux.1 +++ b/tmux.1 @@ -2293,6 +2293,11 @@ Select the current line. .Xc Select the current word. .It Xo +.Ic selection-mode +.Op Ic char | word | line +.Xc +Change the selection mode. +.It Xo .Ic set-mark (vi: X) (emacs: X) diff --git a/window-copy.c b/window-copy.c index 137c97b2..f056cebb 100644 --- a/window-copy.c +++ b/window-copy.c @@ -1970,6 +1970,24 @@ window_copy_cmd_other_end(struct window_copy_cmd_state *cs) return (WINDOW_COPY_CMD_NOTHING); } +static enum window_copy_cmd_action +window_copy_cmd_selection_mode(struct window_copy_cmd_state *cs) +{ + struct window_mode_entry *wme = cs->wme; + struct options *so = cs->s->options; + struct window_copy_mode_data *data = wme->data; + const char *s = args_string(cs->wargs, 0); + + if (s == NULL || strcasecmp(s, "char") == 0 || strcasecmp(s, "c") == 0) + data->selflag = SEL_CHAR; + else if (strcasecmp(s, "word") == 0 || strcasecmp(s, "w") == 0) { + data->separators = options_get_string(so, "word-separators"); + data->selflag = SEL_WORD; + } else if (strcasecmp(s, "line") == 0 || strcasecmp(s, "l") == 0) + data->selflag = SEL_LINE; + return (WINDOW_COPY_CMD_NOTHING); +} + static enum window_copy_cmd_action window_copy_cmd_page_down(struct window_copy_cmd_state *cs) { @@ -2186,7 +2204,7 @@ static enum window_copy_cmd_action window_copy_cmd_select_word(struct window_copy_cmd_state *cs) { struct window_mode_entry *wme = cs->wme; - struct options *session_options = cs->s->options; + struct options *so = cs->s->options; struct window_copy_mode_data *data = wme->data; u_int px, py, nextx, nexty; @@ -2196,8 +2214,7 @@ window_copy_cmd_select_word(struct window_copy_cmd_state *cs) data->dx = data->cx; data->dy = screen_hsize(data->backing) + data->cy - data->oy; - data->separators = options_get_string(session_options, - "word-separators"); + data->separators = options_get_string(so, "word-separators"); window_copy_cursor_previous_word(wme, data->separators, 0); px = data->cx; py = screen_hsize(data->backing) + data->cy - data->oy; @@ -3087,6 +3104,11 @@ static const struct { .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .f = window_copy_cmd_select_word }, + { .command = "selection-mode", + .args = { "", 0, 1, NULL }, + .clear = 0, + .f = window_copy_cmd_selection_mode + }, { .command = "set-mark", .args = { "", 0, 0, NULL }, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, From 12497ecadeb6d28c9b393016a822fe3c32217238 Mon Sep 17 00:00:00 2001 From: nicm Date: Wed, 12 Nov 2025 07:54:52 +0000 Subject: [PATCH 2/3] Convert all keys for backspace, not just A-Z. --- input-keys.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/input-keys.c b/input-keys.c index 91415064..7d7263fb 100644 --- a/input-keys.c +++ b/input-keys.c @@ -606,7 +606,9 @@ input_key(struct screen *s, struct bufferevent *bev, key_code key) ud.data[0] = newkey; else if ((newkey & KEYC_MASK_MODIFIERS) == KEYC_CTRL) { newkey &= KEYC_MASK_KEY; - if (newkey >= 'A' && newkey <= 'Z') + if (newkey == '?') + ud.data[0] = 0x7f; + else if (newkey >= '@' && newkey <= '_') ud.data[0] = newkey - 0x40; else if (newkey >= 'a' && newkey <= 'z') ud.data[0] = newkey - 0x60; From 40600eebfaedef4bbae633308241d5d2f70edfdb Mon Sep 17 00:00:00 2001 From: nicm Date: Wed, 12 Nov 2025 08:06:33 +0000 Subject: [PATCH 3/3] Do not send theme updates to panes that have exited, GitHub issue 4671. --- window.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/window.c b/window.c index 2429d7b7..16f1ecb3 100644 --- a/window.c +++ b/window.c @@ -1922,6 +1922,8 @@ window_pane_get_theme(struct window_pane *wp) void window_pane_send_theme_update(struct window_pane *wp) { + if (wp == NULL || window_pane_exited(wp)) + return; if (~wp->flags & PANE_THEMECHANGED) return; if (~wp->screen->mode & MODE_THEME_UPDATES)