=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/tmux/window-copy.c,v retrieving revision 1.191 retrieving revision 1.192 diff -c -r1.191 -r1.192 *** src/usr.bin/tmux/window-copy.c 2018/07/06 07:11:23 1.191 --- src/usr.bin/tmux/window-copy.c 2018/07/31 11:49:26 1.192 *************** *** 1,4 **** ! /* $OpenBSD: window-copy.c,v 1.191 2018/07/06 07:11:23 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott --- 1,4 ---- ! /* $OpenBSD: window-copy.c,v 1.192 2018/07/31 11:49:26 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott *************** *** 65,72 **** static void window_copy_start_selection(struct window_pane *); static int window_copy_adjust_selection(struct window_pane *, u_int *, u_int *); static int window_copy_update_selection(struct window_pane *, int); ! static void window_copy_synchronize_cursor(struct window_pane *wp); static void *window_copy_get_selection(struct window_pane *, size_t *); static void window_copy_copy_buffer(struct window_pane *, const char *, void *, size_t); --- 65,73 ---- static void window_copy_start_selection(struct window_pane *); static int window_copy_adjust_selection(struct window_pane *, u_int *, u_int *); + static int window_copy_set_selection(struct window_pane *, int); static int window_copy_update_selection(struct window_pane *, int); ! static void window_copy_synchronize_cursor(struct window_pane *); static void *window_copy_get_selection(struct window_pane *, size_t *); static void window_copy_copy_buffer(struct window_pane *, const char *, void *, size_t); *************** *** 151,162 **** struct screen *backing; int backing_written; /* backing display started */ ! u_int oy; /* number of lines scrolled up */ ! u_int selx; /* beginning of selection */ u_int sely; ! u_int endselx; /* end of selection */ u_int endsely; enum { --- 152,163 ---- struct screen *backing; int backing_written; /* backing display started */ ! u_int oy; /* number of lines scrolled up */ ! u_int selx; /* beginning of selection */ u_int sely; ! u_int endselx; /* end of selection */ u_int endsely; enum { *************** *** 165,178 **** CURSORDRAG_SEL, /* start is synchronized with cursor */ } cursordrag; int rectflag; /* in rectangle copy mode? */ int scroll_exit; /* exit on scroll to end? */ u_int cx; u_int cy; ! u_int lastcx; /* position in last line w/ content */ ! u_int lastsx; /* size of last line w/ content */ int searchtype; char *searchstr; --- 166,185 ---- CURSORDRAG_SEL, /* start is synchronized with cursor */ } cursordrag; + int modekeys; + enum { + LINE_SEL_NONE, + LINE_SEL_LEFT_RIGHT, + LINE_SEL_RIGHT_LEFT, + } lineflag; /* line selection mode */ int rectflag; /* in rectangle copy mode? */ int scroll_exit; /* exit on scroll to end? */ u_int cx; u_int cy; ! u_int lastcx; /* position in last line w/ content */ ! u_int lastsx; /* size of last line w/ content */ int searchtype; char *searchstr; *************** *** 228,234 **** s = &data->screen; screen_init(s, screen_size_x(&wp->base), screen_size_y(&wp->base), 0); ! s->sel.modekeys = options_get_number(wp->window->options, "mode-keys"); data->backing = NULL; --- 235,241 ---- s = &data->screen; screen_init(s, screen_size_x(&wp->base), screen_size_y(&wp->base), 0); ! data->modekeys = options_get_number(wp->window->options, "mode-keys"); data->backing = NULL; *************** *** 357,363 **** oy = screen_hsize(data->backing) + data->cy - data->oy; ox = window_copy_find_length(wp, oy); ! if (s->sel.lineflag == LINE_SEL_LEFT_RIGHT && oy == data->sely) window_copy_other_end(wp); if (data->cx != ox) { --- 364,370 ---- oy = screen_hsize(data->backing) + data->cy - data->oy; ox = window_copy_find_length(wp, oy); ! if (data->lineflag == LINE_SEL_LEFT_RIGHT && oy == data->sely) window_copy_other_end(wp); if (data->cx != ox) { *************** *** 379,385 **** else data->oy += n; ! if (!data->screen.sel.flag || !data->rectflag) { py = screen_hsize(data->backing) + data->cy - data->oy; px = window_copy_find_length(wp, py); if ((data->cx >= data->lastsx && data->cx != px) || --- 386,392 ---- else data->oy += n; ! if (data->screen.sel == NULL || !data->rectflag) { py = screen_hsize(data->backing) + data->cy - data->oy; px = window_copy_find_length(wp, py); if ((data->cx >= data->lastsx && data->cx != px) || *************** *** 401,407 **** oy = screen_hsize(data->backing) + data->cy - data->oy; ox = window_copy_find_length(wp, oy); ! if (s->sel.lineflag == LINE_SEL_RIGHT_LEFT && oy == data->sely) window_copy_other_end(wp); if (data->cx != ox) { --- 408,414 ---- oy = screen_hsize(data->backing) + data->cy - data->oy; ox = window_copy_find_length(wp, oy); ! if (data->lineflag == LINE_SEL_RIGHT_LEFT && oy == data->sely) window_copy_other_end(wp); if (data->cx != ox) { *************** *** 423,429 **** else data->oy -= n; ! if (!data->screen.sel.flag || !data->rectflag) { py = screen_hsize(data->backing) + data->cy - data->oy; px = window_copy_find_length(wp, py); if ((data->cx >= data->lastsx && data->cx != px) || --- 430,436 ---- else data->oy -= n; ! if (data->screen.sel == NULL || !data->rectflag) { py = screen_hsize(data->backing) + data->cy - data->oy; px = window_copy_find_length(wp, py); if ((data->cx >= data->lastsx && data->cx != px) || *************** *** 554,560 **** if (m != NULL) window_copy_start_drag(c, m); else { ! sn->sel.lineflag = LINE_SEL_NONE; window_copy_start_selection(wp); redraw = 1; } --- 561,567 ---- if (m != NULL) window_copy_start_drag(c, m); else { ! data->lineflag = LINE_SEL_NONE; window_copy_start_selection(wp); redraw = 1; } *************** *** 763,769 **** window_copy_cursor_previous_word(wp, ws); } if (strcmp(command, "rectangle-toggle") == 0) { ! sn->sel.lineflag = LINE_SEL_NONE; window_copy_rectangle_toggle(wp); } if (strcmp(command, "scroll-down") == 0 || --- 770,776 ---- window_copy_cursor_previous_word(wp, ws); } if (strcmp(command, "rectangle-toggle") == 0) { ! data->lineflag = LINE_SEL_NONE; window_copy_rectangle_toggle(wp); } if (strcmp(command, "scroll-down") == 0 || *************** *** 800,806 **** } } if (strcmp(command, "select-line") == 0) { ! sn->sel.lineflag = LINE_SEL_LEFT_RIGHT; data->rectflag = 0; window_copy_cursor_start_of_line(wp); window_copy_start_selection(wp); --- 807,813 ---- } } if (strcmp(command, "select-line") == 0) { ! data->lineflag = LINE_SEL_LEFT_RIGHT; data->rectflag = 0; window_copy_cursor_start_of_line(wp); window_copy_start_selection(wp); *************** *** 810,816 **** redraw = 1; } if (strcmp(command, "select-word") == 0) { ! sn->sel.lineflag = LINE_SEL_LEFT_RIGHT; data->rectflag = 0; ws = options_get_string(s->options, "word-separators"); window_copy_cursor_previous_word(wp, ws); --- 817,823 ---- redraw = 1; } if (strcmp(command, "select-word") == 0) { ! data->lineflag = LINE_SEL_LEFT_RIGHT; data->rectflag = 0; ws = options_get_string(s->options, "word-separators"); window_copy_cursor_previous_word(wp, ws); *************** *** 1434,1440 **** window_copy_start_selection(struct window_pane *wp) { struct window_copy_mode_data *data = wp->modedata; - struct screen *s = &data->screen; data->selx = data->cx; data->sely = screen_hsize(data->backing) + data->cy - data->oy; --- 1441,1446 ---- *************** *** 1444,1451 **** data->cursordrag = CURSORDRAG_ENDSEL; ! s->sel.flag = 1; ! window_copy_update_selection(wp, 1); } static int --- 1450,1456 ---- data->cursordrag = CURSORDRAG_ENDSEL; ! window_copy_set_selection(wp, 1); } static int *************** *** 1485,1498 **** { struct window_copy_mode_data *data = wp->modedata; struct screen *s = &data->screen; struct options *oo = wp->window->options; struct grid_cell gc; u_int sx, sy, cy, endsx, endsy; int startrelpos, endrelpos; - if (!s->sel.flag && s->sel.lineflag == LINE_SEL_NONE) - return (0); - window_copy_synchronize_cursor(wp); /* Adjust the selection. */ --- 1490,1511 ---- { struct window_copy_mode_data *data = wp->modedata; struct screen *s = &data->screen; + + if (s->sel == NULL && data->lineflag == LINE_SEL_NONE) + return (0); + return (window_copy_set_selection(wp, may_redraw)); + } + + static int + window_copy_set_selection(struct window_pane *wp, int may_redraw) + { + struct window_copy_mode_data *data = wp->modedata; + struct screen *s = &data->screen; struct options *oo = wp->window->options; struct grid_cell gc; u_int sx, sy, cy, endsx, endsy; int startrelpos, endrelpos; window_copy_synchronize_cursor(wp); /* Adjust the selection. */ *************** *** 1515,1521 **** /* Set colours and selection. */ style_apply(&gc, oo, "mode-style"); gc.flags |= GRID_FLAG_NOPALETTE; ! screen_set_selection(s, sx, sy, endsx, endsy, data->rectflag, &gc); if (data->rectflag && may_redraw) { /* --- 1528,1535 ---- /* Set colours and selection. */ style_apply(&gc, oo, "mode-style"); gc.flags |= GRID_FLAG_NOPALETTE; ! screen_set_selection(s, sx, sy, endsx, endsy, data->rectflag, ! data->modekeys, &gc); if (data->rectflag && may_redraw) { /* *************** *** 1551,1557 **** u_int firstsx, lastex, restex, restsx, selx; int keys; ! if (!s->sel.flag && s->sel.lineflag == LINE_SEL_NONE) return (NULL); buf = xmalloc(1); --- 1565,1571 ---- u_int firstsx, lastex, restex, restsx, selx; int keys; ! if (data->screen.sel == NULL && data->lineflag == LINE_SEL_NONE) return (NULL); buf = xmalloc(1); *************** *** 1860,1870 **** { struct window_copy_mode_data *data = wp->modedata; struct screen *back_s = data->backing; - struct screen *s = &data->screen; struct grid *gd = back_s->grid; u_int py; ! if (data->cx == 0 && s->sel.lineflag == LINE_SEL_NONE) { py = screen_hsize(back_s) + data->cy - data->oy; while (py > 0 && grid_get_line(gd, py - 1)->flags & GRID_LINE_WRAPPED) { --- 1874,1883 ---- { struct window_copy_mode_data *data = wp->modedata; struct screen *back_s = data->backing; struct grid *gd = back_s->grid; u_int py; ! if (data->cx == 0 && data->lineflag == LINE_SEL_NONE) { py = screen_hsize(back_s) + data->cy - data->oy; while (py > 0 && grid_get_line(gd, py - 1)->flags & GRID_LINE_WRAPPED) { *************** *** 1905,1911 **** { struct window_copy_mode_data *data = wp->modedata; struct screen *back_s = data->backing; - struct screen *s = &data->screen; struct grid *gd = back_s->grid; struct grid_line *gl; u_int px, py; --- 1918,1923 ---- *************** *** 1913,1920 **** py = screen_hsize(back_s) + data->cy - data->oy; px = window_copy_find_length(wp, py); ! if (data->cx == px && s->sel.lineflag == LINE_SEL_NONE) { ! if (data->screen.sel.flag && data->rectflag) px = screen_size_x(back_s); gl = grid_get_line(gd, py); if (gl->flags & GRID_LINE_WRAPPED) { --- 1925,1932 ---- py = screen_hsize(back_s) + data->cy - data->oy; px = window_copy_find_length(wp, py); ! if (data->cx == px && data->lineflag == LINE_SEL_NONE) { ! if (data->screen.sel != NULL && data->rectflag) px = screen_size_x(back_s); gl = grid_get_line(gd, py); if (gl->flags & GRID_LINE_WRAPPED) { *************** *** 1941,1953 **** struct screen *s = &data->screen; u_int selx, sely, cy, yy, hsize; ! if (!s->sel.flag && s->sel.lineflag == LINE_SEL_NONE) return; ! if (s->sel.lineflag == LINE_SEL_LEFT_RIGHT) ! s->sel.lineflag = LINE_SEL_RIGHT_LEFT; ! else if (s->sel.lineflag == LINE_SEL_RIGHT_LEFT) ! s->sel.lineflag = LINE_SEL_LEFT_RIGHT; switch (data->cursordrag) { case CURSORDRAG_NONE: --- 1953,1965 ---- struct screen *s = &data->screen; u_int selx, sely, cy, yy, hsize; ! if (s->sel == NULL && data->lineflag == LINE_SEL_NONE) return; ! if (data->lineflag == LINE_SEL_LEFT_RIGHT) ! data->lineflag = LINE_SEL_RIGHT_LEFT; ! else if (data->lineflag == LINE_SEL_RIGHT_LEFT) ! data->lineflag = LINE_SEL_LEFT_RIGHT; switch (data->cursordrag) { case CURSORDRAG_NONE: *************** *** 2019,2025 **** py = screen_hsize(data->backing) + data->cy - data->oy; yy = screen_hsize(data->backing) + screen_size_y(data->backing) - 1; ! if (data->screen.sel.flag && data->rectflag) px = screen_size_x(&data->screen); else px = window_copy_find_length(wp, py); --- 2031,2037 ---- py = screen_hsize(data->backing) + data->cy - data->oy; yy = screen_hsize(data->backing) + screen_size_y(data->backing) - 1; ! if (data->screen.sel != NULL && data->rectflag) px = screen_size_x(&data->screen); else px = window_copy_find_length(wp, py); *************** *** 2056,2062 **** data->lastsx = ox; } ! if (s->sel.lineflag == LINE_SEL_LEFT_RIGHT && oy == data->sely) window_copy_other_end(wp); data->cx = data->lastcx; --- 2068,2074 ---- data->lastsx = ox; } ! if (data->lineflag == LINE_SEL_LEFT_RIGHT && oy == data->sely) window_copy_other_end(wp); data->cx = data->lastcx; *************** *** 2078,2084 **** } } ! if (!data->screen.sel.flag || !data->rectflag) { py = screen_hsize(data->backing) + data->cy - data->oy; px = window_copy_find_length(wp, py); if ((data->cx >= data->lastsx && data->cx != px) || --- 2090,2096 ---- } } ! if (data->screen.sel != NULL || !data->rectflag) { py = screen_hsize(data->backing) + data->cy - data->oy; px = window_copy_find_length(wp, py); if ((data->cx >= data->lastsx && data->cx != px) || *************** *** 2086,2094 **** window_copy_cursor_end_of_line(wp); } ! if (s->sel.lineflag == LINE_SEL_LEFT_RIGHT) window_copy_cursor_end_of_line(wp); ! else if (s->sel.lineflag == LINE_SEL_RIGHT_LEFT) window_copy_cursor_start_of_line(wp); } --- 2098,2106 ---- window_copy_cursor_end_of_line(wp); } ! if (data->lineflag == LINE_SEL_LEFT_RIGHT) window_copy_cursor_end_of_line(wp); ! else if (data->lineflag == LINE_SEL_RIGHT_LEFT) window_copy_cursor_start_of_line(wp); } *************** *** 2106,2112 **** data->lastsx = ox; } ! if (s->sel.lineflag == LINE_SEL_RIGHT_LEFT && oy == data->endsely) window_copy_other_end(wp); data->cx = data->lastcx; --- 2118,2124 ---- data->lastsx = ox; } ! if (data->lineflag == LINE_SEL_RIGHT_LEFT && oy == data->endsely) window_copy_other_end(wp); data->cx = data->lastcx; *************** *** 2120,2126 **** window_copy_redraw_lines(wp, data->cy - 1, 2); } ! if (!data->screen.sel.flag || !data->rectflag) { py = screen_hsize(data->backing) + data->cy - data->oy; px = window_copy_find_length(wp, py); if ((data->cx >= data->lastsx && data->cx != px) || --- 2132,2138 ---- window_copy_redraw_lines(wp, data->cy - 1, 2); } ! if (data->screen.sel == NULL || !data->rectflag) { py = screen_hsize(data->backing) + data->cy - data->oy; px = window_copy_find_length(wp, py); if ((data->cx >= data->lastsx && data->cx != px) || *************** *** 2128,2136 **** window_copy_cursor_end_of_line(wp); } ! if (s->sel.lineflag == LINE_SEL_LEFT_RIGHT) window_copy_cursor_end_of_line(wp); ! else if (s->sel.lineflag == LINE_SEL_RIGHT_LEFT) window_copy_cursor_start_of_line(wp); } --- 2140,2148 ---- window_copy_cursor_end_of_line(wp); } ! if (data->lineflag == LINE_SEL_LEFT_RIGHT) window_copy_cursor_end_of_line(wp); ! else if (data->lineflag == LINE_SEL_RIGHT_LEFT) window_copy_cursor_start_of_line(wp); } *************** *** 2401,2407 **** 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_write_line(wp, &ctx, screen_size_y(s) - ny - 1); screen_write_cursormove(&ctx, data->cx, data->cy); screen_write_stop(&ctx); --- 2413,2419 ---- 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 != NULL && 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); screen_write_stop(&ctx); *************** *** 2429,2435 **** screen_write_cursormove(&ctx, 0, 0); screen_write_insertline(&ctx, ny, 8); window_copy_write_lines(wp, &ctx, 0, ny); ! if (s->sel.flag && screen_size_y(s) > ny) window_copy_write_line(wp, &ctx, ny); else if (ny == 1) /* nuke position */ window_copy_write_line(wp, &ctx, 1); --- 2441,2447 ---- screen_write_cursormove(&ctx, 0, 0); screen_write_insertline(&ctx, ny, 8); window_copy_write_lines(wp, &ctx, 0, ny); ! if (s->sel != NULL && screen_size_y(s) > ny) window_copy_write_line(wp, &ctx, ny); else if (ny == 1) /* nuke position */ window_copy_write_line(wp, &ctx, 1); *************** *** 2445,2451 **** if (wp->mode != &window_copy_mode) return; ! format_add(ft, "selection_present", "%d", data->screen.sel.flag); format_add(ft, "scroll_position", "%d", data->oy); format_add(ft, "rectangle_toggle", "%d", data->rectflag); } --- 2457,2463 ---- if (wp->mode != &window_copy_mode) return; ! format_add(ft, "selection_present", "%d", data->screen.sel != NULL); format_add(ft, "scroll_position", "%d", data->oy); format_add(ft, "rectangle_toggle", "%d", data->rectflag); }