diff options
Diffstat (limited to 'window-copy.c')
-rw-r--r-- | window-copy.c | 169 |
1 files changed, 118 insertions, 51 deletions
diff --git a/window-copy.c b/window-copy.c index f690c7c4..37b65c87 100644 --- a/window-copy.c +++ b/window-copy.c @@ -18,6 +18,7 @@ #include <sys/types.h> +#include <ctype.h> #include <stdlib.h> #include <string.h> @@ -41,17 +42,17 @@ void window_copy_write_lines( void window_copy_scroll_to(struct window_pane *, u_int, u_int); int window_copy_search_compare( - struct grid *, u_int, u_int, struct grid *, u_int); + struct grid *, u_int, u_int, struct grid *, u_int, int); int window_copy_search_lr( - struct grid *, struct grid *, u_int *, u_int, u_int, u_int); + struct grid *, struct grid *, u_int *, u_int, u_int, u_int, int); int window_copy_search_rl( - struct grid *, struct grid *, u_int *, u_int, u_int, u_int); + struct grid *, struct grid *, u_int *, u_int, u_int, u_int, int); void window_copy_search_up(struct window_pane *, const char *); void window_copy_search_down(struct window_pane *, const char *); void window_copy_goto_line(struct window_pane *, const char *); void window_copy_update_cursor(struct window_pane *, u_int, u_int); void window_copy_start_selection(struct window_pane *); -int window_copy_update_selection(struct window_pane *); +int window_copy_update_selection(struct window_pane *, int); void *window_copy_get_selection(struct window_pane *, size_t *); void window_copy_copy_buffer(struct window_pane *, int, void *, size_t); void window_copy_copy_pipe( @@ -65,6 +66,7 @@ u_int window_copy_find_length(struct window_pane *, u_int); void window_copy_cursor_start_of_line(struct window_pane *); void window_copy_cursor_back_to_indentation(struct window_pane *); void window_copy_cursor_end_of_line(struct window_pane *); +void window_copy_other_end(struct window_pane *); void window_copy_cursor_left(struct window_pane *); void window_copy_cursor_right(struct window_pane *); void window_copy_cursor_up(struct window_pane *, int); @@ -328,7 +330,7 @@ window_copy_pageup(struct window_pane *wp) data->oy = screen_hsize(data->backing); else data->oy += n; - window_copy_update_selection(wp); + window_copy_update_selection(wp, 1); window_copy_redraw_screen(wp); } @@ -415,6 +417,10 @@ window_copy_key(struct window_pane *wp, struct session *sess, int key) case MODEKEYCOPY_CANCEL: window_pane_reset_mode(wp); return; + case MODEKEYCOPY_OTHEREND: + for (; np != 0; np--) + window_copy_other_end(wp); + break; case MODEKEYCOPY_LEFT: for (; np != 0; np--) window_copy_cursor_left(wp); @@ -453,7 +459,7 @@ window_copy_key(struct window_pane *wp, struct session *sess, int key) else data->oy -= n; } - window_copy_update_selection(wp); + window_copy_update_selection(wp, 1); window_copy_redraw_screen(wp); break; case MODEKEYCOPY_HALFPAGEUP: @@ -464,7 +470,7 @@ window_copy_key(struct window_pane *wp, struct session *sess, int key) else data->oy += n; } - window_copy_update_selection(wp); + window_copy_update_selection(wp, 1); window_copy_redraw_screen(wp); break; case MODEKEYCOPY_HALFPAGEDOWN: @@ -475,39 +481,39 @@ window_copy_key(struct window_pane *wp, struct session *sess, int key) else data->oy -= n; } - window_copy_update_selection(wp); + window_copy_update_selection(wp, 1); window_copy_redraw_screen(wp); break; case MODEKEYCOPY_TOPLINE: data->cx = 0; data->cy = 0; - window_copy_update_selection(wp); + window_copy_update_selection(wp, 1); window_copy_redraw_screen(wp); break; case MODEKEYCOPY_MIDDLELINE: data->cx = 0; data->cy = (screen_size_y(s) - 1) / 2; - window_copy_update_selection(wp); + window_copy_update_selection(wp, 1); window_copy_redraw_screen(wp); break; case MODEKEYCOPY_BOTTOMLINE: data->cx = 0; data->cy = screen_size_y(s) - 1; - window_copy_update_selection(wp); + window_copy_update_selection(wp, 1); window_copy_redraw_screen(wp); break; case MODEKEYCOPY_HISTORYTOP: data->cx = 0; data->cy = 0; data->oy = screen_hsize(data->backing); - window_copy_update_selection(wp); + window_copy_update_selection(wp, 1); window_copy_redraw_screen(wp); break; case MODEKEYCOPY_HISTORYBOTTOM: data->cx = 0; data->cy = screen_size_y(s) - 1; data->oy = 0; - window_copy_update_selection(wp); + window_copy_update_selection(wp, 1); window_copy_redraw_screen(wp); break; case MODEKEYCOPY_STARTSELECTION: @@ -860,7 +866,7 @@ window_copy_mouse( if (s->mode & MODE_MOUSE_BUTTON) { if (~m->event & MOUSE_EVENT_UP) { window_copy_update_cursor(wp, m->x, m->y); - if (window_copy_update_selection(wp)) + if (window_copy_update_selection(wp, 1)) window_copy_redraw_screen(wp); return; } @@ -910,13 +916,13 @@ window_copy_scroll_to(struct window_pane *wp, u_int px, u_int py) } data->oy = gd->hsize - offset; - window_copy_update_selection(wp); + window_copy_update_selection(wp, 1); window_copy_redraw_screen(wp); } int window_copy_search_compare( - struct grid *gd, u_int px, u_int py, struct grid *sgd, u_int spx) + struct grid *gd, u_int px, u_int py, struct grid *sgd, u_int spx, int cis) { const struct grid_cell *gc, *sgc; struct utf8_data ud, sud; @@ -928,21 +934,28 @@ window_copy_search_compare( if (ud.size != sud.size || ud.width != sud.width) return (0); + + if (cis && ud.size == 1) + return (tolower(ud.data[0]) == sud.data[0]); + return (memcmp(ud.data, sud.data, ud.size) == 0); } int window_copy_search_lr(struct grid *gd, - struct grid *sgd, u_int *ppx, u_int py, u_int first, u_int last) + struct grid *sgd, u_int *ppx, u_int py, u_int first, u_int last, int cis) { u_int ax, bx, px; + int matched; for (ax = first; ax < last; ax++) { if (ax + sgd->sx >= gd->sx) break; for (bx = 0; bx < sgd->sx; bx++) { px = ax + bx; - if (!window_copy_search_compare(gd, px, py, sgd, bx)) + matched = window_copy_search_compare(gd, px, py, sgd, + bx, cis); + if (!matched) break; } if (bx == sgd->sx) { @@ -955,16 +968,19 @@ window_copy_search_lr(struct grid *gd, int window_copy_search_rl(struct grid *gd, - struct grid *sgd, u_int *ppx, u_int py, u_int first, u_int last) + struct grid *sgd, u_int *ppx, u_int py, u_int first, u_int last, int cis) { u_int ax, bx, px; + int matched; for (ax = last + 1; ax > first; ax--) { if (gd->sx - (ax - 1) < sgd->sx) continue; for (bx = 0; bx < sgd->sx; bx++) { px = ax - 1 + bx; - if (!window_copy_search_compare(gd, px, py, sgd, bx)) + matched = window_copy_search_compare(gd, px, py, sgd, + bx, cis); + if (!matched) break; } if (bx == sgd->sx) { @@ -985,7 +1001,8 @@ window_copy_search_up(struct window_pane *wp, const char *searchstr) struct grid_cell gc; size_t searchlen; u_int i, last, fx, fy, px; - int utf8flag, n, wrapped, wrapflag; + int utf8flag, n, wrapped, wrapflag, cis; + const char *ptr; if (*searchstr == '\0') return; @@ -1011,13 +1028,21 @@ window_copy_search_up(struct window_pane *wp, const char *searchstr) fx--; n = wrapped = 0; + cis = 1; + for (ptr = searchstr; *ptr != '\0'; ptr++) { + if (*ptr != tolower(*ptr)) { + cis = 0; + break; + } + } + retry: sgd = ss.grid; for (i = fy + 1; i > 0; i--) { last = screen_size_x(s); if (i == fy + 1) last = fx; - n = window_copy_search_rl(gd, sgd, &px, i - 1, 0, last); + n = window_copy_search_rl(gd, sgd, &px, i - 1, 0, last, cis); if (n) { window_copy_scroll_to(wp, px, i - 1); break; @@ -1043,7 +1068,8 @@ window_copy_search_down(struct window_pane *wp, const char *searchstr) struct grid_cell gc; size_t searchlen; u_int i, first, fx, fy, px; - int utf8flag, n, wrapped, wrapflag; + int utf8flag, n, wrapped, wrapflag, cis; + const char *ptr; if (*searchstr == '\0') return; @@ -1069,13 +1095,22 @@ window_copy_search_down(struct window_pane *wp, const char *searchstr) fx++; n = wrapped = 0; + cis = 1; + for (ptr = searchstr; *ptr != '\0'; ptr++) { + if (*ptr != tolower(*ptr)) { + cis = 0; + break; + } + } + retry: sgd = ss.grid; for (i = fy + 1; i < gd->hsize + gd->sy + 1; i++) { first = 0; if (i == fy + 1) first = fx; - n = window_copy_search_lr(gd, sgd, &px, i - 1, first, gd->sx); + n = window_copy_search_lr(gd, sgd, &px, i - 1, first, gd->sx, + cis); if (n) { window_copy_scroll_to(wp, px, i - 1); break; @@ -1103,7 +1138,7 @@ window_copy_goto_line(struct window_pane *wp, const char *linestr) return; data->oy = lineno; - window_copy_update_selection(wp); + window_copy_update_selection(wp, 1); window_copy_redraw_screen(wp); } @@ -1216,11 +1251,11 @@ window_copy_start_selection(struct window_pane *wp) data->sely = screen_hsize(data->backing) + data->cy - data->oy; s->sel.flag = 1; - window_copy_update_selection(wp); + window_copy_update_selection(wp, 1); } int -window_copy_update_selection(struct window_pane *wp) +window_copy_update_selection(struct window_pane *wp, int may_redraw) { struct window_copy_mode_data *data = wp->modedata; struct screen *s = &data->screen; @@ -1255,7 +1290,7 @@ window_copy_update_selection(struct window_pane *wp) screen_set_selection(s, sx, sy, data->cx, screen_hsize(s) + data->cy, data->rectflag, &gc); - if (data->rectflag) { + if (data->rectflag && may_redraw) { /* * Can't rely on the caller to redraw the right lines for * rectangle selection - find the highest line and the number @@ -1559,7 +1594,7 @@ window_copy_cursor_start_of_line(struct window_pane *wp) } } window_copy_update_cursor(wp, 0, data->cy); - if (window_copy_update_selection(wp)) + if (window_copy_update_selection(wp, 1)) window_copy_redraw_lines(wp, data->cy, 1); } @@ -1584,7 +1619,7 @@ window_copy_cursor_back_to_indentation(struct window_pane *wp) } window_copy_update_cursor(wp, px, data->cy); - if (window_copy_update_selection(wp)) + if (window_copy_update_selection(wp, 1)) window_copy_redraw_lines(wp, data->cy, 1); } @@ -1614,11 +1649,44 @@ window_copy_cursor_end_of_line(struct window_pane *wp) } window_copy_update_cursor(wp, px, data->cy); - if (window_copy_update_selection(wp)) + if (window_copy_update_selection(wp, 1)) window_copy_redraw_lines(wp, data->cy, 1); } void +window_copy_other_end(struct window_pane *wp) +{ + struct window_copy_mode_data *data = wp->modedata; + struct screen *s = &data->screen; + u_int selx, sely, cx, cy, yy; + + if (!s->sel.flag) + return; + + selx = data->selx; + sely = data->sely; + cx = data->cx; + cy = data->cy; + yy = screen_hsize(data->backing) + data->cy - data->oy; + + data->selx = cx; + data->sely = yy; + data->cx = selx; + + if (sely < screen_hsize(data->backing) - data->oy) { + data->oy = screen_hsize(data->backing) - sely; + data->cy = 0; + } else if (sely > screen_hsize(data->backing) - data->oy + screen_size_y(s)) { + data->oy = screen_hsize(data->backing) - sely + screen_size_y(s) - 1; + data->cy = screen_size_y(s) - 1; + + } else + data->cy = cy + sely - yy; + + window_copy_redraw_screen(wp); +} + +void window_copy_cursor_left(struct window_pane *wp) { struct window_copy_mode_data *data = wp->modedata; @@ -1628,7 +1696,7 @@ window_copy_cursor_left(struct window_pane *wp) window_copy_cursor_end_of_line(wp); } else { window_copy_update_cursor(wp, data->cx - 1, data->cy); - if (window_copy_update_selection(wp)) + if (window_copy_update_selection(wp, 1)) window_copy_redraw_lines(wp, data->cy, 1); } } @@ -1651,7 +1719,7 @@ window_copy_cursor_right(struct window_pane *wp) window_copy_cursor_down(wp, 0); } else { window_copy_update_cursor(wp, data->cx + 1, data->cy); - if (window_copy_update_selection(wp)) + if (window_copy_update_selection(wp, 1)) window_copy_redraw_lines(wp, data->cy, 1); } } @@ -1681,7 +1749,7 @@ window_copy_cursor_up(struct window_pane *wp, int scroll_only) } } else { window_copy_update_cursor(wp, data->cx, data->cy - 1); - if (window_copy_update_selection(wp)) { + if (window_copy_update_selection(wp, 1)) { if (data->cy == screen_size_y(s) - 1) window_copy_redraw_lines(wp, data->cy, 1); else @@ -1719,7 +1787,7 @@ window_copy_cursor_down(struct window_pane *wp, int scroll_only) window_copy_redraw_lines(wp, data->cy - 1, 2); } else { window_copy_update_cursor(wp, data->cx, data->cy + 1); - if (window_copy_update_selection(wp)) + if (window_copy_update_selection(wp, 1)) window_copy_redraw_lines(wp, data->cy - 1, 2); } @@ -1751,7 +1819,7 @@ window_copy_cursor_jump(struct window_pane *wp) if (!(gc->flags & GRID_FLAG_PADDING) && ud.size == 1 && *ud.data == data->jumpchar) { window_copy_update_cursor(wp, px, data->cy); - if (window_copy_update_selection(wp)) + if (window_copy_update_selection(wp, 1)) window_copy_redraw_lines(wp, data->cy, 1); return; } @@ -1780,7 +1848,7 @@ window_copy_cursor_jump_back(struct window_pane *wp) if (!(gc->flags & GRID_FLAG_PADDING) && ud.size == 1 && *ud.data == data->jumpchar) { window_copy_update_cursor(wp, px, data->cy); - if (window_copy_update_selection(wp)) + if (window_copy_update_selection(wp, 1)) window_copy_redraw_lines(wp, data->cy, 1); return; } @@ -1809,7 +1877,7 @@ window_copy_cursor_jump_to(struct window_pane *wp) if (!(gc->flags & GRID_FLAG_PADDING) && ud.size == 1 && *ud.data == data->jumpchar) { window_copy_update_cursor(wp, px - 1, data->cy); - if (window_copy_update_selection(wp)) + if (window_copy_update_selection(wp, 1)) window_copy_redraw_lines(wp, data->cy, 1); return; } @@ -1838,7 +1906,7 @@ window_copy_cursor_jump_to_back(struct window_pane *wp) if (!(gc->flags & GRID_FLAG_PADDING) && ud.size == 1 && *ud.data == data->jumpchar) { window_copy_update_cursor(wp, px + 1, data->cy); - if (window_copy_update_selection(wp)) + if (window_copy_update_selection(wp, 1)) window_copy_redraw_lines(wp, data->cy, 1); return; } @@ -1886,7 +1954,7 @@ window_copy_cursor_next_word(struct window_pane *wp, const char *separators) } while (expected == 1); window_copy_update_cursor(wp, px, data->cy); - if (window_copy_update_selection(wp)) + if (window_copy_update_selection(wp, 1)) window_copy_redraw_lines(wp, data->cy, 1); } @@ -1936,7 +2004,7 @@ window_copy_cursor_next_word_end(struct window_pane *wp, const char *separators) px--; window_copy_update_cursor(wp, px, data->cy); - if (window_copy_update_selection(wp)) + if (window_copy_update_selection(wp, 1)) window_copy_redraw_lines(wp, data->cy, 1); } @@ -1974,7 +2042,7 @@ window_copy_cursor_previous_word(struct window_pane *wp, const char *separators) out: window_copy_update_cursor(wp, px, data->cy); - if (window_copy_update_selection(wp)) + if (window_copy_update_selection(wp, 1)) window_copy_redraw_lines(wp, data->cy, 1); } @@ -1991,6 +2059,8 @@ window_copy_scroll_up(struct window_pane *wp, u_int ny) return; data->oy -= ny; + window_copy_update_selection(wp, 0); + screen_write_start(&ctx, wp, NULL); screen_write_cursormove(&ctx, 0, 0); screen_write_deleteline(&ctx, ny); @@ -2000,12 +2070,9 @@ window_copy_scroll_up(struct window_pane *wp, u_int ny) window_copy_write_line(wp, &ctx, 1); if (screen_size_y(s) > 3) window_copy_write_line(wp, &ctx, screen_size_y(s) - 2); - if (s->sel.flag && screen_size_y(s) > ny) { - window_copy_update_selection(wp); + if (s->sel.flag && screen_size_y(s) > ny) window_copy_write_line(wp, &ctx, screen_size_y(s) - ny - 1); - } screen_write_cursormove(&ctx, data->cx, data->cy); - window_copy_update_selection(wp); screen_write_stop(&ctx); } @@ -2025,17 +2092,17 @@ window_copy_scroll_down(struct window_pane *wp, u_int ny) return; data->oy += ny; + window_copy_update_selection(wp, 0); + screen_write_start(&ctx, wp, NULL); screen_write_cursormove(&ctx, 0, 0); screen_write_insertline(&ctx, ny); window_copy_write_lines(wp, &ctx, 0, ny); - if (s->sel.flag && screen_size_y(s) > ny) { - window_copy_update_selection(wp); + if (s->sel.flag && screen_size_y(s) > ny) window_copy_write_line(wp, &ctx, ny); - } else if (ny == 1) /* nuke position */ + else if (ny == 1) /* nuke position */ window_copy_write_line(wp, &ctx, 1); screen_write_cursormove(&ctx, data->cx, data->cy); - window_copy_update_selection(wp); screen_write_stop(&ctx); } @@ -2052,6 +2119,6 @@ window_copy_rectangle_toggle(struct window_pane *wp) if (data->cx > px) window_copy_update_cursor(wp, px, data->cy); - window_copy_update_selection(wp); + window_copy_update_selection(wp, 1); window_copy_redraw_screen(wp); } |