diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 3a589484..48171136 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -14,8 +14,8 @@ Before opening an issue, please ensure that: - Your question or issue is not covered [in the manual](https://man.openbsd.org/tmux.1) (run `man tmux`). -- Your problem is not mentioned in the [CHANGES - file](https://raw.githubusercontent.com/tmux/tmux/master/CHANGES) file. +- Your problem is not mentioned in [the CHANGES + file](https://raw.githubusercontent.com/tmux/tmux/master/CHANGES). - Nobody else has opened the same issue recently. diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index c4f1ae0d..fe405298 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1 +1,2 @@ +github: nicm liberapay: tmux diff --git a/.github/lock.yml b/.github/lock.yml new file mode 100644 index 00000000..89126482 --- /dev/null +++ b/.github/lock.yml @@ -0,0 +1,10 @@ +daysUntilLock: 180 +skipCreatedBefore: false +exemptLabels: [] +lockLabel: false +lockComment: > + This thread has been automatically locked since there has not been + any recent activity after it was closed. Please open a new issue for + related bugs. +setLockReason: false +#only: issues diff --git a/CHANGES b/CHANGES index d6806e49..70bf61ae 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,8 @@ -CHANGES FROM 3.0 to X.X +CHANGES FROM 3.1 TO 3.2 + +XXX + +CHANGES FROM 3.0a to 3.1 * Add support for adding a note to a key binding (with bind-key -N) and use this to add descriptions to the default key bindings. A new -N flag to @@ -10,7 +14,7 @@ CHANGES FROM 3.0 to X.X * Add support for the iTerm2 DSR 1337 sequence to get the terminal version. * Treat plausible but invalid keys (like C-BSpace) as literal like any other - unrecognised string passed to send-keys + unrecognised string passed to send-keys. * Detect iTerm2 and enable use of DECSLRM (much faster with horizontally split windows). @@ -42,11 +46,6 @@ CHANGES FROM 3.0 to X.X * Add push-default to status-left and status-right in status-format[0]. -* Add -F flag to send-keys to expand formats in search-backward and forward - copy mode commands and copy_cursor_word and copy_cursor_line formats for word - and line at cursor in copy mode. Use for default # and * binding with vi(1) - keys. - * Do not clear search marks on cursor movement with vi(1) keys. * Add p format modifier for padding to width and allow multiple substitutions @@ -54,32 +53,9 @@ CHANGES FROM 3.0 to X.X * Add -f for full size to join-pane (like split-window). -* Handle OSC 7 (a VTE extension) and put the result in a new format (pane_path). - -* Change new-session -A without a session name (that is, no -s option also) to - attach to the best existing session like attach-session rather than creating - a new one. - -* Add an option to set the key sent by backspace for those whose system uses ^H - rather than ^?. - -* Add formats for cursor and selection position in copy mode. - -* Add support for percentage sizes for resize-pane ("-x 10%"). Also change - split-window and join-pane -l to accept similar percentages and no longer - document -p. - -* Turn automatic-rename back on if the rename escape sequence is used with an - empty name. - -* Make select-pane -P set window-active-style also to match previous behaviour. - * Do not use bright when emulating 256 colours on an 8 colour terminal because it is also bold on some terminals. -* Add a "latest" window-size option which tries to size windows based on the - most recently used client. This is now the default. - * Make select-pane -P set window-active-style also to match previous behaviour. * Do not truncate list-keys output. @@ -92,17 +68,18 @@ CHANGES FROM 3.0 to X.X -p flag. * Add -F flag to send-keys to expand formats in search-backward and forward - copy mode commands, this makes it easier to use the cursor_word and - cursor_line formats. + copy mode commands and copy_cursor_word and copy_cursor_line formats for word + and line at cursor in copy mode. Use for default # and * binding with vi(1) + keys. * Add formats for word and line at cursor position in copy mode. -* Add formats for cursor and selection position in copy mode +* Add formats for cursor and selection position in copy mode. * Support all the forms of RGB colour strings in OSC sequences rather than requiring two digits. -* Limit lazy resize to panes in attached sessions only +* Limit lazy resize to panes in attached sessions only. * Add an option to set the key sent by backspace for those whose system uses ^H rather than ^?. @@ -111,7 +88,8 @@ CHANGES FROM 3.0 to X.X attach to the best existing session like attach-session rather than a new one. -* Change window-size default from smallest to latest. +* Add a "latest" window-size option which tries to size windows based on the + most recently used client. This is now the default. * Add simple support for OSC 7 (result is available in the pane_path format). @@ -133,7 +111,7 @@ CHANGES FROM 3.0 to X.X * Add reverse sorting in tree, client and buffer modes. -CHANGES FROM 3.0 to 3.0a +CHANGES FROM 3.0 TO 3.0a * Do not require REG_STARTEND. @@ -147,7 +125,7 @@ CHANGES FROM 3.0 to 3.0a * Do not crash when restoring a layout with only one pane. -CHANGES FROM 2.9 to 3.0 +CHANGES FROM 2.9 TO 3.0 * Workaround invalid layout strings generated by older tmux versions and add some additional sanity checks @@ -272,11 +250,11 @@ CHANGES FROM 2.9 to 3.0 * Add the ability to infer an option type (server, session, window) from its name to show-options (it was already present in set-option). -CHANGES FROM 2.9 to 2.9a +CHANGES FROM 2.9 TO 2.9a * Fix bugs in select-pane and the main-horizontal and main-vertical layouts. -CHANGES FROM 2.8 to 2.9 +CHANGES FROM 2.8 TO 2.9 * Attempt to preserve horizontal cursor position as well as vertical with reflow. @@ -401,7 +379,7 @@ CHANGES FROM 2.8 to 2.9 moves up, down, left or right and -c returns to automatic cursor tracking. The position is reset when the current window is changed. -CHANGES FROM 2.7 to 2.8 +CHANGES FROM 2.7 TO 2.8 * Make display-panes block the client until a pane is chosen or it times out. diff --git a/cmd-bind-key.c b/cmd-bind-key.c index 27f75dd0..bc6a3d40 100644 --- a/cmd-bind-key.c +++ b/cmd-bind-key.c @@ -33,8 +33,8 @@ const struct cmd_entry cmd_bind_key_entry = { .name = "bind-key", .alias = "bind", - .args = { "cnrN:T:", 2, -1 }, - .usage = "[-cnr] [-T key-table] [-N note] key " + .args = { "nrN:T:", 2, -1 }, + .usage = "[-nr] [-T key-table] [-N note] key " "command [arguments]", .flags = CMD_AFTERHOOK, diff --git a/cmd-list-keys.c b/cmd-list-keys.c index e9e75a72..34ed43bf 100644 --- a/cmd-list-keys.c +++ b/cmd-list-keys.c @@ -36,8 +36,8 @@ const struct cmd_entry cmd_list_keys_entry = { .name = "list-keys", .alias = "lsk", - .args = { "1NP:T:", 0, 1 }, - .usage = "[-1N] [-P prefix-string] [-T key-table] [key]", + .args = { "1aNP:T:", 0, 1 }, + .usage = "[-1aN] [-P prefix-string] [-T key-table] [key]", .flags = CMD_STARTSERVER|CMD_AFTERHOOK, .exec = cmd_list_keys_exec @@ -89,7 +89,7 @@ cmd_list_keys_print_notes(struct cmdq_item *item, struct args *args, struct key_table *table; struct key_binding *bd; const char *key; - char *tmp; + char *tmp, *note; int found = 0; table = key_bindings_get_table(tablename, 0); @@ -99,19 +99,24 @@ cmd_list_keys_print_notes(struct cmdq_item *item, struct args *args, while (bd != NULL) { if ((only != KEYC_UNKNOWN && bd->key != only) || KEYC_IS_MOUSE(bd->key) || - bd->note == NULL) { + (bd->note == NULL && !args_has(args, 'a'))) { bd = key_bindings_next(table, bd); continue; } found = 1; key = key_string_lookup_key(bd->key); + if (bd->note == NULL) + note = cmd_list_print(bd->cmdlist, 1); + else + note = xstrdup(bd->note); tmp = utf8_padcstr(key, keywidth + 1); if (args_has(args, '1') && c != NULL) - status_message_set(c, "%s%s%s", prefix, tmp, bd->note); + status_message_set(c, "%s%s%s", prefix, tmp, note); else - cmdq_print(item, "%s%s%s", prefix, tmp, bd->note); + cmdq_print(item, "%s%s%s", prefix, tmp, note); free(tmp); + free(note); if (args_has(args, '1')) break; diff --git a/cmd-select-pane.c b/cmd-select-pane.c index 6542c919..c63c7e61 100644 --- a/cmd-select-pane.c +++ b/cmd-select-pane.c @@ -197,8 +197,8 @@ cmd_select_pane_exec(struct cmd *self, struct cmdq_item *item) if (args_has(self->args, 'T')) { pane_title = format_single(item, args_get(self->args, 'T'), c, s, wl, wp); - screen_set_title(&wp->base, pane_title); - server_status_window(wp->window); + if (screen_set_title(&wp->base, pane_title)) + server_status_window(wp->window); free(pane_title); return (CMD_RETURN_NORMAL); } diff --git a/configure.ac b/configure.ac index 5fba1eaf..380eea73 100644 --- a/configure.ac +++ b/configure.ac @@ -1,6 +1,6 @@ # configure.ac -AC_INIT([tmux], next-3.1) +AC_INIT([tmux], next-3.2) AC_PREREQ([2.60]) AC_CONFIG_AUX_DIR(etc) diff --git a/format.c b/format.c index 0d3e26d7..79e99b61 100644 --- a/format.c +++ b/format.c @@ -895,6 +895,44 @@ format_cb_pane_in_mode(struct format_tree *ft, struct format_entry *fe) xasprintf(&fe->value, "%u", n); } +/* Callback for pane_at_top. */ +static void +format_cb_pane_at_top(struct format_tree *ft, struct format_entry *fe) +{ + struct window_pane *wp = ft->wp; + struct window *w = wp->window; + int status, flag; + + if (wp == NULL) + return; + + status = options_get_number(w->options, "pane-border-status"); + if (status == PANE_STATUS_TOP) + flag = (wp->yoff == 1); + else + flag = (wp->yoff == 0); + xasprintf(&fe->value, "%d", flag); +} + +/* Callback for pane_at_bottom. */ +static void +format_cb_pane_at_bottom(struct format_tree *ft, struct format_entry *fe) +{ + struct window_pane *wp = ft->wp; + struct window *w = wp->window; + int status, flag; + + if (wp == NULL) + return; + + status = options_get_number(w->options, "pane-border-status"); + if (status == PANE_STATUS_BOTTOM) + flag = (wp->yoff + wp->sy == w->sy - 1); + else + flag = (wp->yoff + wp->sy == w->sy); + xasprintf(&fe->value, "%d", flag); +} + /* Callback for cursor_character. */ static void format_cb_cursor_character(struct format_tree *ft, struct format_entry *fe) @@ -2546,9 +2584,9 @@ format_defaults_pane(struct format_tree *ft, struct window_pane *wp) format_add(ft, "pane_right", "%u", wp->xoff + wp->sx - 1); format_add(ft, "pane_bottom", "%u", wp->yoff + wp->sy - 1); format_add(ft, "pane_at_left", "%d", wp->xoff == 0); - format_add(ft, "pane_at_top", "%d", wp->yoff == 0); + format_add_cb(ft, "pane_at_top", format_cb_pane_at_top); format_add(ft, "pane_at_right", "%d", wp->xoff + wp->sx == w->sx); - format_add(ft, "pane_at_bottom", "%d", wp->yoff + wp->sy == w->sy); + format_add_cb(ft, "pane_at_bottom", format_cb_pane_at_bottom); wme = TAILQ_FIRST(&wp->modes); if (wme != NULL) { diff --git a/input.c b/input.c index b2b874e0..13bedc34 100644 --- a/input.c +++ b/input.c @@ -2225,10 +2225,8 @@ input_exit_osc(struct input_ctx *ictx) switch (option) { case 0: case 2: - if (utf8_isvalid(p)) { - screen_set_title(sctx->s, p); + if (screen_set_title(sctx->s, p)) server_status_window(ictx->wp->window); - } break; case 4: input_osc_4(ictx, p); @@ -2286,10 +2284,8 @@ input_exit_apc(struct input_ctx *ictx) return; log_debug("%s: \"%s\"", __func__, ictx->input_buf); - if (!utf8_isvalid(ictx->input_buf)) - return; - screen_set_title(sctx->s, ictx->input_buf); - server_status_window(ictx->wp->window); + if (screen_set_title(sctx->s, ictx->input_buf)) + server_status_window(ictx->wp->window); } /* Rename string started. */ diff --git a/key-string.c b/key-string.c index 0505623e..d2b31e03 100644 --- a/key-string.c +++ b/key-string.c @@ -242,53 +242,90 @@ key_string_lookup_string(const char *string) const char * key_string_lookup_key(key_code key) { - static char out[32]; - char tmp[8]; - u_int i; - struct utf8_data ud; - size_t off; + static char out[32]; + char tmp[8]; + const char *s; + u_int i; + struct utf8_data ud; + size_t off; *out = '\0'; + /* Literal keys are themselves. */ + if (key & KEYC_LITERAL) { + snprintf(out, sizeof out, "%c", (int)(key & 0xff)); + return (out); + } + + /* Fill in the modifiers. */ + if (key & KEYC_CTRL) + strlcat(out, "C-", sizeof out); + if (key & KEYC_ESCAPE) + strlcat(out, "M-", sizeof out); + if (key & KEYC_SHIFT) + strlcat(out, "S-", sizeof out); + key &= KEYC_MASK_KEY; + /* Handle no key. */ if (key == KEYC_NONE) return ("None"); /* Handle special keys. */ - if (key == KEYC_UNKNOWN) - return ("Unknown"); - if (key == KEYC_ANY) - return ("Any"); - if (key == KEYC_FOCUS_IN) - return ("FocusIn"); - if (key == KEYC_FOCUS_OUT) - return ("FocusOut"); - if (key == KEYC_PASTE_START) - return ("PasteStart"); - if (key == KEYC_PASTE_END) - return ("PasteEnd"); - if (key == KEYC_MOUSE) - return ("Mouse"); - if (key == KEYC_DRAGGING) - return ("Dragging"); - if (key == KEYC_MOUSEMOVE_PANE) - return ("MouseMovePane"); - if (key == KEYC_MOUSEMOVE_STATUS) - return ("MouseMoveStatus"); - if (key == KEYC_MOUSEMOVE_STATUS_LEFT) - return ("MouseMoveStatusLeft"); - if (key == KEYC_MOUSEMOVE_STATUS_RIGHT) - return ("MouseMoveStatusRight"); - if (key == KEYC_MOUSEMOVE_BORDER) - return ("MouseMoveBorder"); - if (key >= KEYC_USER && key < KEYC_USER + KEYC_NUSER) { - snprintf(out, sizeof out, "User%u", (u_int)(key - KEYC_USER)); - return (out); + if (key == KEYC_UNKNOWN) { + s = "Unknown"; + goto append; } - - /* Literal keys are themselves. */ - if (key & KEYC_LITERAL) { - snprintf(out, sizeof out, "%c", (int)(key & 0xff)); + if (key == KEYC_ANY) { + s = "Any"; + goto append; + } + if (key == KEYC_FOCUS_IN) { + s = "FocusIn"; + goto append; + } + if (key == KEYC_FOCUS_OUT) { + s = "FocusOut"; + goto append; + } + if (key == KEYC_PASTE_START) { + s = "PasteStart"; + goto append; + } + if (key == KEYC_PASTE_END) { + s = "PasteEnd"; + goto append; + } + if (key == KEYC_MOUSE) { + s = "Mouse"; + goto append; + } + if (key == KEYC_DRAGGING) { + s = "Dragging"; + goto append; + } + if (key == KEYC_MOUSEMOVE_PANE) { + s = "MouseMovePane"; + goto append; + } + if (key == KEYC_MOUSEMOVE_STATUS) { + s = "MouseMoveStatus"; + goto append; + } + if (key == KEYC_MOUSEMOVE_STATUS_LEFT) { + s = "MouseMoveStatusLeft"; + goto append; + } + if (key == KEYC_MOUSEMOVE_STATUS_RIGHT) { + s = "MouseMoveStatusRight"; + goto append; + } + if (key == KEYC_MOUSEMOVE_BORDER) { + s = "MouseMoveBorder"; + goto append; + } + if (key >= KEYC_USER && key < KEYC_USER + KEYC_NUSER) { + snprintf(tmp, sizeof tmp, "User%u", (u_int)(key - KEYC_USER)); + strlcat(out, tmp, sizeof out); return (out); } @@ -301,15 +338,6 @@ key_string_lookup_key(key_code key) if ((key & KEYC_MASK_KEY) == 0) key = ' ' | KEYC_CTRL | (key & KEYC_MASK_MOD); - /* Fill in the modifiers. */ - if (key & KEYC_CTRL) - strlcat(out, "C-", sizeof out); - if (key & KEYC_ESCAPE) - strlcat(out, "M-", sizeof out); - if (key & KEYC_SHIFT) - strlcat(out, "S-", sizeof out); - key &= KEYC_MASK_KEY; - /* Try the key against the string table. */ for (i = 0; i < nitems(key_string_table); i++) { if (key == key_string_table[i].key) @@ -352,4 +380,8 @@ key_string_lookup_key(key_code key) strlcat(out, tmp, sizeof out); return (out); + +append: + strlcat(out, s, sizeof out); + return (out); } diff --git a/screen.c b/screen.c index afb9415b..4ffd2cca 100644 --- a/screen.c +++ b/screen.c @@ -155,11 +155,14 @@ screen_set_cursor_colour(struct screen *s, const char *colour) } /* Set screen title. */ -void +int screen_set_title(struct screen *s, const char *title) { + if (!utf8_isvalid(title)) + return (0); free(s->title); - utf8_stravis(&s->title, title, VIS_OCTAL|VIS_CSTYLE|VIS_TAB|VIS_NL); + s->title = xstrdup(title); + return (1); } /* Set screen path. */ diff --git a/server-client.c b/server-client.c index 5527b6e8..497397d3 100644 --- a/server-client.c +++ b/server-client.c @@ -660,8 +660,7 @@ have_event: break; } c->tty.mouse_drag_flag = 0; - - return (key); + goto out; } /* Convert to a key binding. */ @@ -956,6 +955,7 @@ have_event: if (key == KEYC_UNKNOWN) return (KEYC_UNKNOWN); +out: /* Apply modifiers if any. */ if (b & MOUSE_MASK_META) key |= KEYC_ESCAPE; @@ -964,6 +964,8 @@ have_event: if (b & MOUSE_MASK_SHIFT) key |= KEYC_SHIFT; + if (log_get_level() != 0) + log_debug("mouse key is %s", key_string_lookup_key (key)); return (key); } @@ -1057,7 +1059,7 @@ server_client_key_callback(struct cmdq_item *item, void *data) * Mouse drag is in progress, so fire the callback (now that * the mouse event is valid). */ - if (key == KEYC_DRAGGING) { + if ((key & KEYC_MASK_KEY) == KEYC_DRAGGING) { c->tty.mouse_drag_update(c, m); goto out; } @@ -1704,7 +1706,6 @@ static void server_client_dispatch(struct imsg *imsg, void *arg) { struct client *c = arg; - const char *data; ssize_t datalen; struct session *s; @@ -1716,7 +1717,6 @@ server_client_dispatch(struct imsg *imsg, void *arg) return; } - data = imsg->data; datalen = imsg->hdr.len - IMSG_HEADER_SIZE; switch (imsg->hdr.type) { diff --git a/tmux.1 b/tmux.1 index 59cac594..4f7b693c 100644 --- a/tmux.1 +++ b/tmux.1 @@ -2686,37 +2686,40 @@ To view the default bindings and possible commands, see the .Ic list-keys command. .It Xo Ic list-keys -.Op Fl 1N +.Op Fl 1aN .Op Fl P Ar prefix-string Fl T Ar key-table .Op key .Xc .D1 (alias: Ic lsk ) -List all key bindings. -By default this shows all keys or any bindings for -.Ar key -in the syntax of the +List key bindings. +There are two forms: the default lists keys as .Ic bind-key -command. +commands; .Fl N -instead show keys and attached notes, i -.Ar key-table -if given or in the +lists only keys with attached notes and shows only the key and note for each +key. +.Pp +With the default form, all key tables are listed by default. +.Fl T +lists only keys in +.Ar key-table . +.Pp +With the +.Fl N +form, only keys in the .Em root and .Em prefix -key tables by default. -.Fl P -specifies a prefix to print before each key. -With -.Fl 1 -only the first matching key and note is shown. -.Pp -Without -.Fl N , +key tables are listed by default; .Fl T -prints only keys in -.Ar key-table , -otherwise all key tables are printed. +also lists only keys in +.Ar key-table . +.Fl P +specifies a prefix to print before each key and +.Fl 1 +lists only the first matching key. +.Fl a +lists the command for keys that do have a note rather than skipping them. .It Xo Ic send-keys .Op Fl FHlMRX .Op Fl N Ar repeat-count @@ -4348,6 +4351,7 @@ The following variables are available, where appropriate: .It Li "scroll_position" Ta "" Ta "Scroll position in copy mode" .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 "selection_active" Ta "" Ta "1 if selection started and changes with the cursor in copy mode" .It Li "selection_end_x" Ta "" Ta "X position of the end of the selection" .It Li "selection_end_y" Ta "" Ta "Y position of the end of the selection" .It Li "selection_present" Ta "" Ta "1 if selection started in copy mode" diff --git a/tmux.h b/tmux.h index e5341f19..1418d0bd 100644 --- a/tmux.h +++ b/tmux.h @@ -2450,7 +2450,7 @@ void screen_free(struct screen *); void screen_reset_tabs(struct screen *); void screen_set_cursor_style(struct screen *, u_int); void screen_set_cursor_colour(struct screen *, const char *); -void screen_set_title(struct screen *, const char *); +int screen_set_title(struct screen *, const char *); void screen_set_path(struct screen *, const char *); void screen_push_title(struct screen *); void screen_pop_title(struct screen *); diff --git a/window-buffer.c b/window-buffer.c index 39d98608..a1939b0f 100644 --- a/window-buffer.c +++ b/window-buffer.c @@ -209,7 +209,7 @@ window_buffer_draw(__unused void *modedata, void *itemdata, struct paste_buffer *pb; const char *pdata, *start, *end; char *buf = NULL; - size_t psize, len; + size_t psize; u_int i, cx = ctx->s->cx, cy = ctx->s->cy; pb = paste_get_name(item->name); @@ -222,7 +222,7 @@ window_buffer_draw(__unused void *modedata, void *itemdata, while (end != pdata + psize && *end != '\n') end++; buf = xreallocarray(buf, 4, end - start + 1); - len = utf8_strvis(buf, start, end - start, VIS_OCTAL|VIS_TAB); + utf8_strvis(buf, start, end - start, VIS_OCTAL|VIS_TAB); if (*buf != '\0') { screen_write_cursormove(ctx, cx, cy + i, 0); screen_write_nputs(ctx, sx, &grid_default_cell, "%s", diff --git a/window-copy.c b/window-copy.c index 6e80daad..301fc16e 100644 --- a/window-copy.c +++ b/window-copy.c @@ -590,7 +590,10 @@ window_copy_formats(struct window_mode_entry *wme, struct format_tree *ft) format_add(ft, "selection_start_y", "%d", data->sely); format_add(ft, "selection_end_x", "%d", data->endselx); format_add(ft, "selection_end_y", "%d", data->endsely); - } + format_add(ft, "selection_active", "%d", + data->cursordrag != CURSORDRAG_NONE); + } else + format_add(ft, "selection_active", "%d", 0); s = format_grid_word(data->screen.grid, data->cx, data->cy); if (s != NULL) { @@ -1521,14 +1524,26 @@ window_copy_cmd_select_word(struct window_copy_cmd_state *cs) struct session *s = cs->s; struct window_copy_mode_data *data = wme->data; const char *ws; + u_int px, py, xx; data->lineflag = LINE_SEL_LEFT_RIGHT; data->rectflag = 0; + px = data->cx; + py = screen_hsize(data->backing) + data->cy - data->oy; + xx = window_copy_find_length(wme, py); + ws = options_get_string(s->options, "word-separators"); window_copy_cursor_previous_word(wme, ws, 0); window_copy_start_selection(wme); - window_copy_cursor_next_word_end(wme, ws); + + if (px >= xx || !window_copy_in_set(wme, px + 1, py, ws)) + window_copy_cursor_next_word_end(wme, ws); + else { + window_copy_update_cursor(wme, px, data->cy); + if (window_copy_update_selection(wme, 1)) + window_copy_redraw_lines(wme, data->cy, 1); + } return (WINDOW_COPY_CMD_REDRAW); } diff --git a/window.c b/window.c index 015738c9..f911f186 100644 --- a/window.c +++ b/window.c @@ -548,31 +548,38 @@ window_get_active_at(struct window *w, u_int x, u_int y) struct window_pane * window_find_string(struct window *w, const char *s) { - u_int x, y; + u_int x, y, top = 0, bottom = w->sy - 1; + int status; x = w->sx / 2; y = w->sy / 2; + status = options_get_number(w->options, "pane-border-status"); + if (status == PANE_STATUS_TOP) + top++; + else if (status == PANE_STATUS_BOTTOM) + bottom--; + if (strcasecmp(s, "top") == 0) - y = 0; + y = top; else if (strcasecmp(s, "bottom") == 0) - y = w->sy - 1; + y = bottom; else if (strcasecmp(s, "left") == 0) x = 0; else if (strcasecmp(s, "right") == 0) x = w->sx - 1; else if (strcasecmp(s, "top-left") == 0) { x = 0; - y = 0; + y = top; } else if (strcasecmp(s, "top-right") == 0) { x = w->sx - 1; - y = 0; + y = top; } else if (strcasecmp(s, "bottom-left") == 0) { x = 0; - y = w->sy - 1; + y = bottom; } else if (strcasecmp(s, "bottom-right") == 0) { x = w->sx - 1; - y = w->sy - 1; + y = bottom; } else return (NULL);