=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/tmux/window-copy.c,v retrieving revision 1.314 retrieving revision 1.315 diff -c -r1.314 -r1.315 *** src/usr.bin/tmux/window-copy.c 2021/02/08 14:46:53 1.314 --- src/usr.bin/tmux/window-copy.c 2021/02/22 06:53:04 1.315 *************** *** 1,4 **** ! /* $OpenBSD: window-copy.c,v 1.314 2021/02/08 14:46:53 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott --- 1,4 ---- ! /* $OpenBSD: window-copy.c,v 1.315 2021/02/22 06:53:04 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott *************** *** 135,140 **** --- 135,144 ---- static void window_copy_drag_update(struct client *, struct mouse_event *); static void window_copy_drag_release(struct client *, struct mouse_event *); static void window_copy_jump_to_mark(struct window_mode_entry *); + static void window_copy_acquire_cursor_up(struct window_mode_entry *, + u_int, u_int, u_int, u_int, u_int); + static void window_copy_acquire_cursor_down(struct window_mode_entry *, + u_int, u_int, u_int, u_int, u_int, u_int, int); const struct window_mode window_copy_mode = { .name = "copy-mode", *************** *** 284,291 **** #define WINDOW_COPY_SEARCH_TIMEOUT 10000 #define WINDOW_COPY_SEARCH_ALL_TIMEOUT 200 ! int jumptype; ! char jumpchar; struct event dragtimer; #define WINDOW_COPY_DRAG_REPEAT_TIME 50000 --- 288,295 ---- #define WINDOW_COPY_SEARCH_TIMEOUT 10000 #define WINDOW_COPY_SEARCH_ALL_TIMEOUT 200 ! int jumptype; ! struct utf8_data *jumpchar; struct event dragtimer; #define WINDOW_COPY_DRAG_REPEAT_TIME 50000 *************** *** 401,407 **** data->searchall = 1; data->jumptype = WINDOW_COPY_OFF; ! data->jumpchar = '\0'; screen_init(&data->screen, screen_size_x(base), screen_size_y(base), 0); data->modekeys = options_get_number(wp->window->options, "mode-keys"); --- 405,411 ---- data->searchall = 1; data->jumptype = WINDOW_COPY_OFF; ! data->jumpchar = NULL; screen_init(&data->screen, screen_size_x(base), screen_size_y(base), 0); data->modekeys = options_get_number(wp->window->options, "mode-keys"); *************** *** 482,487 **** --- 486,492 ---- free(data->searchmark); free(data->searchstr); + free(data->jumpchar); screen_free(data->backing); free(data->backing); *************** *** 1935,1941 **** if (*argument != '\0') { data->jumptype = WINDOW_COPY_JUMPBACKWARD; ! data->jumpchar = *argument; for (; np != 0; np--) window_copy_cursor_jump_back(wme); } --- 1940,1947 ---- if (*argument != '\0') { data->jumptype = WINDOW_COPY_JUMPBACKWARD; ! free(data->jumpchar); ! data->jumpchar = utf8_fromcstr(argument); for (; np != 0; np--) window_copy_cursor_jump_back(wme); } *************** *** 1952,1958 **** if (*argument != '\0') { data->jumptype = WINDOW_COPY_JUMPFORWARD; ! data->jumpchar = *argument; for (; np != 0; np--) window_copy_cursor_jump(wme); } --- 1958,1965 ---- if (*argument != '\0') { data->jumptype = WINDOW_COPY_JUMPFORWARD; ! free(data->jumpchar); ! data->jumpchar = utf8_fromcstr(argument); for (; np != 0; np--) window_copy_cursor_jump(wme); } *************** *** 1969,1975 **** if (*argument != '\0') { data->jumptype = WINDOW_COPY_JUMPTOBACKWARD; ! data->jumpchar = *argument; for (; np != 0; np--) window_copy_cursor_jump_to_back(wme); } --- 1976,1983 ---- if (*argument != '\0') { data->jumptype = WINDOW_COPY_JUMPTOBACKWARD; ! free(data->jumpchar); ! data->jumpchar = utf8_fromcstr(argument); for (; np != 0; np--) window_copy_cursor_jump_to_back(wme); } *************** *** 1986,1992 **** if (*argument != '\0') { data->jumptype = WINDOW_COPY_JUMPTOFORWARD; ! data->jumpchar = *argument; for (; np != 0; np--) window_copy_cursor_jump_to(wme); } --- 1994,2001 ---- if (*argument != '\0') { data->jumptype = WINDOW_COPY_JUMPTOFORWARD; ! free(data->jumpchar); ! data->jumpchar = utf8_fromcstr(argument); for (; np != 0; np--) window_copy_cursor_jump_to(wme); } *************** *** 4074,4080 **** struct window_copy_mode_data *data = wme->data; struct screen *back_s = data->backing; struct grid_reader gr; ! u_int px, py, cy, oldy, yy, ny, nd, hsize; px = data->cx; hsize = screen_hsize(back_s); --- 4083,4089 ---- struct window_copy_mode_data *data = wme->data; struct screen *back_s = data->backing; struct grid_reader gr; ! u_int px, py, oldy, hsize; px = data->cx; hsize = screen_hsize(back_s); *************** *** 4084,4108 **** grid_reader_start(&gr, back_s->grid, px, py); grid_reader_cursor_start_of_line(&gr, 1); grid_reader_get_cursor(&gr, &px, &py); ! ! /* Scroll up if we went off the visible screen. */ ! yy = hsize - data->oy; ! if (py < yy) { ! ny = yy - py; ! cy = 0; ! nd = 1; ! } else { ! ny = 0; ! cy = py - yy; ! nd = oldy - cy + 1; ! } ! while (ny > 0) { ! window_copy_cursor_up(wme, 1); ! ny--; ! } ! window_copy_update_cursor(wme, px, cy); ! if (window_copy_update_selection(wme, 1, 0)) ! window_copy_redraw_lines(wme, data->cy, nd); } static void --- 4093,4099 ---- grid_reader_start(&gr, back_s->grid, px, py); grid_reader_cursor_start_of_line(&gr, 1); grid_reader_get_cursor(&gr, &px, &py); ! window_copy_acquire_cursor_up(wme, hsize, data->oy, oldy, px, py); } static void *************** *** 4134,4140 **** struct window_copy_mode_data *data = wme->data; struct screen *back_s = data->backing; struct grid_reader gr; ! u_int px, py, cy, oldy, yy, ny, nd, hsize; px = data->cx; hsize = screen_hsize(back_s); --- 4125,4131 ---- struct window_copy_mode_data *data = wme->data; struct screen *back_s = data->backing; struct grid_reader gr; ! u_int px, py, oldy, hsize; px = data->cx; hsize = screen_hsize(back_s); *************** *** 4147,4174 **** else grid_reader_cursor_end_of_line(&gr, 1, 0); grid_reader_get_cursor(&gr, &px, &py); ! ! /* Scroll down if we went off the visible screen. */ ! cy = py - hsize + data->oy; ! yy = screen_size_y(back_s) - 1; ! if (cy > yy) { ! ny = cy - yy; ! oldy = yy; ! nd = 1; ! } else { ! ny = 0; ! nd = cy - oldy + 1; ! } ! while (ny > 0) { ! window_copy_cursor_down(wme, 1); ! ny--; ! } ! if (cy > yy) ! window_copy_update_cursor(wme, px, yy); ! else ! window_copy_update_cursor(wme, px, cy); ! if (window_copy_update_selection(wme, 1, 0)) ! window_copy_redraw_lines(wme, oldy, nd); } static void --- 4138,4145 ---- else grid_reader_cursor_end_of_line(&gr, 1, 0); grid_reader_get_cursor(&gr, &px, &py); ! window_copy_acquire_cursor_down(wme, hsize, screen_size_y(back_s), ! data->oy, oldy, px, py, 0); } static void *************** *** 4228,4259 **** struct window_copy_mode_data *data = wme->data; struct screen *back_s = data->backing; struct grid_reader gr; ! u_int px, py, cy, yy, ny, hsize; px = data->cx; hsize = screen_hsize(back_s); py = hsize + data->cy - data->oy; grid_reader_start(&gr, back_s->grid, px, py); grid_reader_cursor_left(&gr); grid_reader_get_cursor(&gr, &px, &py); ! ! /* Scroll up if we went off the visible screen. */ ! yy = hsize - data->oy; ! if (py < yy) { ! ny = yy - py; ! cy = 0; ! } else { ! ny = 0; ! cy = py - yy; ! } ! while (ny > 0) { ! window_copy_cursor_up(wme, 1); ! ny--; ! } ! window_copy_update_cursor(wme, px, cy); ! if (window_copy_update_selection(wme, 1, 0)) ! window_copy_redraw_lines(wme, data->cy, 1); } static void --- 4199,4215 ---- struct window_copy_mode_data *data = wme->data; struct screen *back_s = data->backing; struct grid_reader gr; ! u_int px, py, oldy, hsize; px = data->cx; hsize = screen_hsize(back_s); py = hsize + data->cy - data->oy; + oldy = data->cy; grid_reader_start(&gr, back_s->grid, px, py); grid_reader_cursor_left(&gr); grid_reader_get_cursor(&gr, &px, &py); ! window_copy_acquire_cursor_up(wme, hsize, data->oy, oldy, px, py); } static void *************** *** 4262,4294 **** struct window_copy_mode_data *data = wme->data; struct screen *back_s = data->backing; struct grid_reader gr; ! u_int px, py, cy, yy, ny, hsize; px = data->cx; hsize = screen_hsize(back_s); py = hsize + data->cy - data->oy; grid_reader_start(&gr, back_s->grid, px, py); grid_reader_cursor_right(&gr, 1, all); grid_reader_get_cursor(&gr, &px, &py); ! ! /* Scroll down if we went off the visible screen. */ ! cy = py - hsize + data->oy; ! yy = screen_size_y(back_s) - 1; ! if (cy > yy) ! ny = cy - yy; ! else ! ny = 0; ! while (ny > 0) { ! window_copy_cursor_down(wme, 1); ! ny--; ! } ! if (cy > yy) ! window_copy_update_cursor(wme, px, yy); ! else ! window_copy_update_cursor(wme, px, cy); ! if (window_copy_update_selection(wme, 1, 0)) ! window_copy_redraw_lines(wme, data->cy, 1); } static void --- 4218,4235 ---- struct window_copy_mode_data *data = wme->data; struct screen *back_s = data->backing; struct grid_reader gr; ! u_int px, py, oldy, hsize; px = data->cx; hsize = screen_hsize(back_s); py = hsize + data->cy - data->oy; + oldy = data->cy; grid_reader_start(&gr, back_s->grid, px, py); grid_reader_cursor_right(&gr, 1, all); grid_reader_get_cursor(&gr, &px, &py); ! window_copy_acquire_cursor_down(wme, hsize, screen_size_y(back_s), ! data->oy, oldy, px, py, 0); } static void *************** *** 4422,4444 **** { struct window_copy_mode_data *data = wme->data; struct screen *back_s = data->backing; ! struct grid_cell gc; ! u_int px, py, xx; px = data->cx + 1; ! py = screen_hsize(back_s) + data->cy - data->oy; ! xx = window_copy_find_length(wme, py); ! while (px < xx) { ! grid_get_cell(back_s->grid, px, py, &gc); ! if (!(gc.flags & GRID_FLAG_PADDING) && ! gc.data.size == 1 && *gc.data.data == data->jumpchar) { ! window_copy_update_cursor(wme, px, data->cy); ! if (window_copy_update_selection(wme, 1, 0)) ! window_copy_redraw_lines(wme, data->cy, 1); ! return; ! } ! px++; } } --- 4363,4381 ---- { struct window_copy_mode_data *data = wme->data; struct screen *back_s = data->backing; ! struct grid_reader gr; ! u_int px, py, oldy, hsize; px = data->cx + 1; ! hsize = screen_hsize(back_s); ! py = hsize + data->cy - data->oy; ! oldy = data->cy; ! grid_reader_start(&gr, back_s->grid, px, py); ! if (grid_reader_cursor_jump(&gr, data->jumpchar)) { ! grid_reader_get_cursor(&gr, &px, &py); ! window_copy_acquire_cursor_down(wme, hsize, ! screen_size_y(back_s), data->oy, oldy, px, py, 0); } } *************** *** 4447,4473 **** { struct window_copy_mode_data *data = wme->data; struct screen *back_s = data->backing; ! struct grid_cell gc; ! u_int px, py; px = data->cx; ! py = screen_hsize(back_s) + data->cy - data->oy; if (px > 0) px--; ! for (;;) { ! grid_get_cell(back_s->grid, px, py, &gc); ! if (!(gc.flags & GRID_FLAG_PADDING) && ! gc.data.size == 1 && *gc.data.data == data->jumpchar) { ! window_copy_update_cursor(wme, px, data->cy); ! if (window_copy_update_selection(wme, 1, 0)) ! window_copy_redraw_lines(wme, data->cy, 1); ! return; ! } ! if (px == 0) ! break; ! px--; } } --- 4384,4405 ---- { struct window_copy_mode_data *data = wme->data; struct screen *back_s = data->backing; ! struct grid_reader gr; ! u_int px, py, oldy, hsize; px = data->cx; ! hsize = screen_hsize(back_s); ! py = hsize + data->cy - data->oy; ! oldy = data->cy; if (px > 0) px--; ! grid_reader_start(&gr, back_s->grid, px, py); ! if (grid_reader_cursor_jump_back(&gr, data->jumpchar)) { ! grid_reader_get_cursor(&gr, &px, &py); ! window_copy_acquire_cursor_up(wme, hsize, data->oy, oldy, px, ! py); } } *************** *** 4476,4498 **** { struct window_copy_mode_data *data = wme->data; struct screen *back_s = data->backing; ! struct grid_cell gc; ! u_int px, py, xx; px = data->cx + 2; ! py = screen_hsize(back_s) + data->cy - data->oy; ! xx = window_copy_find_length(wme, py); ! while (px < xx) { ! grid_get_cell(back_s->grid, px, py, &gc); ! if (!(gc.flags & GRID_FLAG_PADDING) && ! gc.data.size == 1 && *gc.data.data == data->jumpchar) { ! window_copy_update_cursor(wme, px - 1, data->cy); ! if (window_copy_update_selection(wme, 1, 0)) ! window_copy_redraw_lines(wme, data->cy, 1); ! return; ! } ! px++; } } --- 4408,4427 ---- { struct window_copy_mode_data *data = wme->data; struct screen *back_s = data->backing; ! struct grid_reader gr; ! u_int px, py, oldy, hsize; px = data->cx + 2; ! hsize = screen_hsize(back_s); ! py = hsize + data->cy - data->oy; ! oldy = data->cy; ! grid_reader_start(&gr, back_s->grid, px, py); ! if (grid_reader_cursor_jump(&gr, data->jumpchar)) { ! grid_reader_cursor_left(&gr); ! grid_reader_get_cursor(&gr, &px, &py); ! window_copy_acquire_cursor_down(wme, hsize, ! screen_size_y(back_s), data->oy, oldy, px, py, 0); } } *************** *** 4501,4511 **** { struct window_copy_mode_data *data = wme->data; struct screen *back_s = data->backing; ! struct grid_cell gc; ! u_int px, py; px = data->cx; ! py = screen_hsize(back_s) + data->cy - data->oy; if (px > 0) px--; --- 4430,4442 ---- { struct window_copy_mode_data *data = wme->data; struct screen *back_s = data->backing; ! struct grid_reader gr; ! u_int px, py, oldy, hsize; px = data->cx; ! hsize = screen_hsize(back_s); ! py = hsize + data->cy - data->oy; ! oldy = data->cy; if (px > 0) px--; *************** *** 4513,4530 **** if (px > 0) px--; ! for (;;) { ! grid_get_cell(back_s->grid, px, py, &gc); ! if (!(gc.flags & GRID_FLAG_PADDING) && ! gc.data.size == 1 && *gc.data.data == data->jumpchar) { ! window_copy_update_cursor(wme, px + 1, data->cy); ! if (window_copy_update_selection(wme, 1, 0)) ! window_copy_redraw_lines(wme, data->cy, 1); ! return; ! } ! if (px == 0) ! break; ! px--; } } --- 4444,4455 ---- if (px > 0) px--; ! grid_reader_start(&gr, back_s->grid, px, py); ! if (grid_reader_cursor_jump_back(&gr, data->jumpchar)) { ! grid_reader_cursor_right(&gr, 1, 0); ! grid_reader_get_cursor(&gr, &px, &py); ! window_copy_acquire_cursor_up(wme, hsize, data->oy, oldy, px, ! py); } } *************** *** 4535,4541 **** struct window_copy_mode_data *data = wme->data; struct screen *back_s = data->backing; struct grid_reader gr; ! u_int px, py, cy, oldy, yy, ny, nd, hsize; px = data->cx; hsize = screen_hsize(back_s); --- 4460,4466 ---- struct window_copy_mode_data *data = wme->data; struct screen *back_s = data->backing; struct grid_reader gr; ! u_int px, py, oldy, hsize; px = data->cx; hsize = screen_hsize(back_s); *************** *** 4545,4572 **** grid_reader_start(&gr, back_s->grid, px, py); grid_reader_cursor_next_word(&gr, separators); grid_reader_get_cursor(&gr, &px, &py); ! ! /* Scroll down if we went off the visible screen. */ ! cy = py - hsize + data->oy; ! yy = screen_size_y(back_s) - 1; ! if (cy > yy) { ! ny = cy - yy; ! oldy = yy; ! nd = 1; ! } else { ! ny = 0; ! nd = cy - oldy + 1; ! } ! while (ny > 0) { ! window_copy_cursor_down(wme, 1); ! ny--; ! } ! if (cy > yy) ! window_copy_update_cursor(wme, px, yy); ! else ! window_copy_update_cursor(wme, px, cy); ! if (window_copy_update_selection(wme, 1, 0)) ! window_copy_redraw_lines(wme, oldy, nd); } static void --- 4470,4477 ---- grid_reader_start(&gr, back_s->grid, px, py); grid_reader_cursor_next_word(&gr, separators); grid_reader_get_cursor(&gr, &px, &py); ! window_copy_acquire_cursor_down(wme, hsize, screen_size_y(back_s), ! data->oy, oldy, px, py, 0); } static void *************** *** 4627,4633 **** struct options *oo = wp->window->options; struct screen *back_s = data->backing; struct grid_reader gr; ! u_int px, py, cy, oldy, yy, ny, nd, hsize; int keys; px = data->cx; --- 4532,4538 ---- struct options *oo = wp->window->options; struct screen *back_s = data->backing; struct grid_reader gr; ! u_int px, py, oldy, hsize; int keys; px = data->cx; *************** *** 4643,4670 **** if (keys == MODEKEY_VI) grid_reader_cursor_left(&gr); grid_reader_get_cursor(&gr, &px, &py); ! ! /* Scroll down if we went off the visible screen. */ ! cy = py - hsize + data->oy; ! yy = screen_size_y(back_s) - 1; ! if (cy > yy) { ! ny = cy - yy; ! oldy = yy; ! nd = 1; ! } else { ! ny = 0; ! nd = cy - oldy + 1; ! } ! while (ny > 0) { ! window_copy_cursor_down(wme, 1); ! ny--; ! } ! if (cy > yy) ! window_copy_update_cursor(wme, px, yy); ! else ! window_copy_update_cursor(wme, px, cy); ! if (window_copy_update_selection(wme, 1, no_reset)) ! window_copy_redraw_lines(wme, oldy, nd); } /* Compute the previous place where a word begins. */ --- 4548,4555 ---- if (keys == MODEKEY_VI) grid_reader_cursor_left(&gr); grid_reader_get_cursor(&gr, &px, &py); ! window_copy_acquire_cursor_down(wme, hsize, screen_size_y(back_s), ! data->oy, oldy, px, py, no_reset); } /* Compute the previous place where a word begins. */ *************** *** 4721,4727 **** struct window_copy_mode_data *data = wme->data; struct screen *back_s = data->backing; struct grid_reader gr; ! u_int px, py, cy, oldy, yy, ny, nd, hsize; px = data->cx; hsize = screen_hsize(back_s); --- 4606,4612 ---- struct window_copy_mode_data *data = wme->data; struct screen *back_s = data->backing; struct grid_reader gr; ! u_int px, py, oldy, hsize; px = data->cx; hsize = screen_hsize(back_s); *************** *** 4731,4755 **** grid_reader_start(&gr, back_s->grid, px, py); grid_reader_cursor_previous_word(&gr, separators, already); grid_reader_get_cursor(&gr, &px, &py); ! ! /* Scroll up if we went off the visible screen. */ ! yy = hsize - data->oy; ! if (py < yy) { ! ny = yy - py; ! cy = 0; ! nd = 1; ! } else { ! ny = 0; ! cy = py - yy; ! nd = oldy - cy + 1; ! } ! while (ny > 0) { ! window_copy_cursor_up(wme, 1); ! ny--; ! } ! window_copy_update_cursor(wme, px, cy); ! if (window_copy_update_selection(wme, 1, 0)) ! window_copy_redraw_lines(wme, data->cy, nd); } static void --- 4616,4622 ---- grid_reader_start(&gr, back_s->grid, px, py); grid_reader_cursor_previous_word(&gr, separators, already); grid_reader_get_cursor(&gr, &px, &py); ! window_copy_acquire_cursor_up(wme, hsize, data->oy, oldy, px, py); } static void *************** *** 4999,5002 **** --- 4866,4924 ---- data->showmark = 1; window_copy_update_selection(wme, 0, 0); window_copy_redraw_screen(wme); + } + + /* Scroll up if the cursor went off the visible screen. */ + static void + window_copy_acquire_cursor_up(struct window_mode_entry *wme, u_int hsize, + u_int oy, u_int oldy, u_int px, u_int py) + { + u_int cy, yy, ny, nd; + + yy = hsize - oy; + if (py < yy) { + ny = yy - py; + cy = 0; + nd = 1; + } else { + ny = 0; + cy = py - yy; + nd = oldy - cy + 1; + } + while (ny > 0) { + window_copy_cursor_up(wme, 1); + ny--; + } + window_copy_update_cursor(wme, px, cy); + if (window_copy_update_selection(wme, 1, 0)) + window_copy_redraw_lines(wme, cy, nd); + } + + /* Scroll down if the cursor went off the visible screen. */ + static void + window_copy_acquire_cursor_down(struct window_mode_entry *wme, u_int hsize, + u_int sy, u_int oy, u_int oldy, u_int px, u_int py, int no_reset) + { + u_int cy, yy, ny, nd; + + cy = py - hsize + oy; + yy = sy - 1; + if (cy > yy) { + ny = cy - yy; + oldy = yy; + nd = 1; + } else { + ny = 0; + nd = cy - oldy + 1; + } + while (ny > 0) { + window_copy_cursor_down(wme, 1); + ny--; + } + if (cy > yy) + window_copy_update_cursor(wme, px, yy); + else + window_copy_update_cursor(wme, px, cy); + if (window_copy_update_selection(wme, 1, no_reset)) + window_copy_redraw_lines(wme, oldy, nd); }