diff --git a/format.c b/format.c index edb0120c..d9da0fd7 100644 --- a/format.c +++ b/format.c @@ -5192,6 +5192,16 @@ format_defaults_paste_buffer(struct format_tree *ft, struct paste_buffer *pb) ft->pb = pb; } +static int +format_is_word_separator(const char *ws, const struct grid_cell *gc) +{ + if (utf8_cstrhas(ws, &gc->data)) + return (1); + if (gc->flags & GRID_FLAG_TAB) + return (1); + return gc->data.size == 1 && *gc->data.data == ' '; +} + /* Return word at given coordinates. Caller frees. */ char * format_grid_word(struct grid *gd, u_int x, u_int y) @@ -5211,8 +5221,7 @@ format_grid_word(struct grid *gd, u_int x, u_int y) grid_get_cell(gd, x, y, &gc); if (gc.flags & GRID_FLAG_PADDING) break; - if (utf8_cstrhas(ws, &gc.data) || - (gc.data.size == 1 && *gc.data.data == ' ')) { + if (format_is_word_separator(ws, &gc)) { found = 1; break; } @@ -5249,8 +5258,7 @@ format_grid_word(struct grid *gd, u_int x, u_int y) grid_get_cell(gd, x, y, &gc); if (gc.flags & GRID_FLAG_PADDING) break; - if (utf8_cstrhas(ws, &gc.data) || - (gc.data.size == 1 && *gc.data.data == ' ')) + if (format_is_word_separator(ws, &gc)) break; ud = xreallocarray(ud, size + 2, sizeof *ud); diff --git a/status.c b/status.c index f39c2584..32833f8c 100644 --- a/status.c +++ b/status.c @@ -728,6 +728,55 @@ status_prompt_update(struct client *c, const char *msg, const char *input) format_free(ft); } +/* Redraw character. Return 1 if can continue redrawing, 0 otherwise. */ +static int +status_prompt_redraw_character(struct screen_write_ctx *ctx, u_int offset, + u_int pwidth, u_int *width, struct grid_cell *gc, + const struct utf8_data *ud) +{ + u_char ch; + + if (*width < offset) { + *width += ud->width; + return (1); + } + if (*width >= offset + pwidth) + return (0); + *width += ud->width; + if (*width > offset + pwidth) + return (0); + + ch = *ud->data; + if (ud->size == 1 && (ch <= 0x1f || ch == 0x7f)) { + gc->data.data[0] = '^'; + gc->data.data[1] = (ch == 0x7f) ? '?' : ch|0x40; + gc->data.size = gc->data.have = 2; + gc->data.width = 2; + } else + utf8_copy(&gc->data, ud); + screen_write_cell(ctx, gc); + return (1); +} + +/* + * Redraw quote indicator '^' if necessary. Return 1 if can continue redrawing, + * 0 otherwise. + */ +static int +status_prompt_redraw_quote(const struct client *c, u_int pcursor, + struct screen_write_ctx *ctx, u_int offset, u_int pwidth, u_int *width, + struct grid_cell *gc) +{ + struct utf8_data ud; + + if (c->prompt_flags & PROMPT_QUOTENEXT && ctx->s->cx == pcursor + 1) { + utf8_set(&ud, '^'); + return (status_prompt_redraw_character(ctx, offset, pwidth, + width, gc, &ud)); + } + return (1); +} + /* Draw client prompt on status line of present else on last line. */ int status_prompt_redraw(struct client *c) @@ -740,8 +789,6 @@ status_prompt_redraw(struct client *c) u_int pcursor, pwidth, promptline; struct grid_cell gc; struct format_tree *ft; - u_char ch; - struct utf8_data *ud; if (c->tty.sx == 0 || c->tty.sy == 0) return (0); @@ -788,6 +835,8 @@ status_prompt_redraw(struct client *c) pcursor = utf8_strwidth(c->prompt_buffer, c->prompt_index); pwidth = utf8_strwidth(c->prompt_buffer, -1); + if (c->prompt_flags & PROMPT_QUOTENEXT) + pwidth++; if (pcursor >= left) { /* * The cursor would be outside the screen so start drawing @@ -799,31 +848,19 @@ status_prompt_redraw(struct client *c) offset = 0; if (pwidth > left) pwidth = left; - c->prompt_cursor = start + c->prompt_index - offset; + c->prompt_cursor = start + pcursor - offset; width = 0; for (i = 0; c->prompt_buffer[i].size != 0; i++) { - ud = &c->prompt_buffer[i]; - if (width < offset) { - width += ud->width; - continue; - } - if (width >= offset + pwidth) + if (!status_prompt_redraw_quote(c, pcursor, &ctx, offset, + pwidth, &width, &gc)) break; - width += ud->width; - if (width > offset + pwidth) + if (!status_prompt_redraw_character(&ctx, offset, pwidth, + &width, &gc, &c->prompt_buffer[i])) break; - - ch = *ud->data; - if (ud->size == 1 && (ch <= 0x1f || ch == 0x7f)) { - gc.data.data[0] = '^'; - gc.data.data[1] = (ch == 0x7f) ? '?' : ch|0x40; - gc.data.size = gc.data.have = 2; - gc.data.width = 2; - } else - utf8_copy(&gc.data, ud); - screen_write_cell(&ctx, &gc); } + status_prompt_redraw_quote(c, pcursor, &ctx, offset, pwidth, &width, + &gc); finished: screen_write_stop(&ctx); @@ -1274,7 +1311,6 @@ status_prompt_key(struct client *c, key_code key) key &= ~KEYC_MASK_FLAGS; if (c->prompt_flags & (PROMPT_SINGLE|PROMPT_QUOTENEXT)) { - c->prompt_flags &= ~PROMPT_QUOTENEXT; if ((key & KEYC_MASK_KEY) == KEYC_BSPACE) key = 0x7f; else if ((key & KEYC_MASK_KEY) > 0x7f) { @@ -1283,6 +1319,7 @@ status_prompt_key(struct client *c, key_code key) key &= KEYC_MASK_KEY; } else key &= (key & KEYC_CTRL) ? 0x1f : KEYC_MASK_KEY; + c->prompt_flags &= ~PROMPT_QUOTENEXT; goto append_key; } diff --git a/window-copy.c b/window-copy.c index 7a2734ac..8542092e 100644 --- a/window-copy.c +++ b/window-copy.c @@ -3082,6 +3082,9 @@ window_copy_search_compare(struct grid *gd, u_int px, u_int py, grid_get_cell(sgd, spx, 0, &sgc); sud = &sgc.data; + if (*sud->data == '\t' && sud->size == 1 && gc.flags & GRID_FLAG_TAB) + return (1); + if (ud->size != sud->size || ud->width != sud->width) return (0);