diff --git a/input-keys.c b/input-keys.c index 18f15afa..2f5cfafc 100644 --- a/input-keys.c +++ b/input-keys.c @@ -605,7 +605,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; diff --git a/tmux.1 b/tmux.1 index 6befcf08..755ad4ff 100644 --- a/tmux.1 +++ b/tmux.1 @@ -2295,6 +2295,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, diff --git a/window.c b/window.c index 6f2c19fe..562fcc7d 100644 --- a/window.c +++ b/window.c @@ -1933,6 +1933,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)