version 1.314, 2021/02/08 14:46:53 |
version 1.315, 2021/02/22 06:53:04 |
|
|
static void window_copy_drag_update(struct client *, struct mouse_event *); |
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_drag_release(struct client *, struct mouse_event *); |
static void window_copy_jump_to_mark(struct window_mode_entry *); |
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 = { |
const struct window_mode window_copy_mode = { |
.name = "copy-mode", |
.name = "copy-mode", |
|
|
#define WINDOW_COPY_SEARCH_TIMEOUT 10000 |
#define WINDOW_COPY_SEARCH_TIMEOUT 10000 |
#define WINDOW_COPY_SEARCH_ALL_TIMEOUT 200 |
#define WINDOW_COPY_SEARCH_ALL_TIMEOUT 200 |
|
|
int jumptype; |
int jumptype; |
char jumpchar; |
struct utf8_data *jumpchar; |
|
|
struct event dragtimer; |
struct event dragtimer; |
#define WINDOW_COPY_DRAG_REPEAT_TIME 50000 |
#define WINDOW_COPY_DRAG_REPEAT_TIME 50000 |
|
|
data->searchall = 1; |
data->searchall = 1; |
|
|
data->jumptype = WINDOW_COPY_OFF; |
data->jumptype = WINDOW_COPY_OFF; |
data->jumpchar = '\0'; |
data->jumpchar = NULL; |
|
|
screen_init(&data->screen, screen_size_x(base), screen_size_y(base), 0); |
screen_init(&data->screen, screen_size_x(base), screen_size_y(base), 0); |
data->modekeys = options_get_number(wp->window->options, "mode-keys"); |
data->modekeys = options_get_number(wp->window->options, "mode-keys"); |
|
|
|
|
free(data->searchmark); |
free(data->searchmark); |
free(data->searchstr); |
free(data->searchstr); |
|
free(data->jumpchar); |
|
|
screen_free(data->backing); |
screen_free(data->backing); |
free(data->backing); |
free(data->backing); |
|
|
|
|
if (*argument != '\0') { |
if (*argument != '\0') { |
data->jumptype = WINDOW_COPY_JUMPBACKWARD; |
data->jumptype = WINDOW_COPY_JUMPBACKWARD; |
data->jumpchar = *argument; |
free(data->jumpchar); |
|
data->jumpchar = utf8_fromcstr(argument); |
for (; np != 0; np--) |
for (; np != 0; np--) |
window_copy_cursor_jump_back(wme); |
window_copy_cursor_jump_back(wme); |
} |
} |
|
|
|
|
if (*argument != '\0') { |
if (*argument != '\0') { |
data->jumptype = WINDOW_COPY_JUMPFORWARD; |
data->jumptype = WINDOW_COPY_JUMPFORWARD; |
data->jumpchar = *argument; |
free(data->jumpchar); |
|
data->jumpchar = utf8_fromcstr(argument); |
for (; np != 0; np--) |
for (; np != 0; np--) |
window_copy_cursor_jump(wme); |
window_copy_cursor_jump(wme); |
} |
} |
|
|
|
|
if (*argument != '\0') { |
if (*argument != '\0') { |
data->jumptype = WINDOW_COPY_JUMPTOBACKWARD; |
data->jumptype = WINDOW_COPY_JUMPTOBACKWARD; |
data->jumpchar = *argument; |
free(data->jumpchar); |
|
data->jumpchar = utf8_fromcstr(argument); |
for (; np != 0; np--) |
for (; np != 0; np--) |
window_copy_cursor_jump_to_back(wme); |
window_copy_cursor_jump_to_back(wme); |
} |
} |
|
|
|
|
if (*argument != '\0') { |
if (*argument != '\0') { |
data->jumptype = WINDOW_COPY_JUMPTOFORWARD; |
data->jumptype = WINDOW_COPY_JUMPTOFORWARD; |
data->jumpchar = *argument; |
free(data->jumpchar); |
|
data->jumpchar = utf8_fromcstr(argument); |
for (; np != 0; np--) |
for (; np != 0; np--) |
window_copy_cursor_jump_to(wme); |
window_copy_cursor_jump_to(wme); |
} |
} |
|
|
struct window_copy_mode_data *data = wme->data; |
struct window_copy_mode_data *data = wme->data; |
struct screen *back_s = data->backing; |
struct screen *back_s = data->backing; |
struct grid_reader gr; |
struct grid_reader gr; |
u_int px, py, cy, oldy, yy, ny, nd, hsize; |
u_int px, py, oldy, hsize; |
|
|
px = data->cx; |
px = data->cx; |
hsize = screen_hsize(back_s); |
hsize = screen_hsize(back_s); |
|
|
grid_reader_start(&gr, back_s->grid, px, py); |
grid_reader_start(&gr, back_s->grid, px, py); |
grid_reader_cursor_start_of_line(&gr, 1); |
grid_reader_cursor_start_of_line(&gr, 1); |
grid_reader_get_cursor(&gr, &px, &py); |
grid_reader_get_cursor(&gr, &px, &py); |
|
window_copy_acquire_cursor_up(wme, hsize, data->oy, oldy, 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 |
static void |
|
|
struct window_copy_mode_data *data = wme->data; |
struct window_copy_mode_data *data = wme->data; |
struct screen *back_s = data->backing; |
struct screen *back_s = data->backing; |
struct grid_reader gr; |
struct grid_reader gr; |
u_int px, py, cy, oldy, yy, ny, nd, hsize; |
u_int px, py, oldy, hsize; |
|
|
px = data->cx; |
px = data->cx; |
hsize = screen_hsize(back_s); |
hsize = screen_hsize(back_s); |
|
|
else |
else |
grid_reader_cursor_end_of_line(&gr, 1, 0); |
grid_reader_cursor_end_of_line(&gr, 1, 0); |
grid_reader_get_cursor(&gr, &px, &py); |
grid_reader_get_cursor(&gr, &px, &py); |
|
window_copy_acquire_cursor_down(wme, hsize, screen_size_y(back_s), |
/* Scroll down if we went off the visible screen. */ |
data->oy, oldy, px, py, 0); |
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 |
static void |
|
|
struct window_copy_mode_data *data = wme->data; |
struct window_copy_mode_data *data = wme->data; |
struct screen *back_s = data->backing; |
struct screen *back_s = data->backing; |
struct grid_reader gr; |
struct grid_reader gr; |
u_int px, py, cy, yy, ny, hsize; |
u_int px, py, oldy, hsize; |
|
|
px = data->cx; |
px = data->cx; |
hsize = screen_hsize(back_s); |
hsize = screen_hsize(back_s); |
py = hsize + data->cy - data->oy; |
py = hsize + data->cy - data->oy; |
|
oldy = data->cy; |
|
|
grid_reader_start(&gr, back_s->grid, px, py); |
grid_reader_start(&gr, back_s->grid, px, py); |
grid_reader_cursor_left(&gr); |
grid_reader_cursor_left(&gr); |
grid_reader_get_cursor(&gr, &px, &py); |
grid_reader_get_cursor(&gr, &px, &py); |
|
window_copy_acquire_cursor_up(wme, hsize, data->oy, oldy, 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 |
static void |
|
|
struct window_copy_mode_data *data = wme->data; |
struct window_copy_mode_data *data = wme->data; |
struct screen *back_s = data->backing; |
struct screen *back_s = data->backing; |
struct grid_reader gr; |
struct grid_reader gr; |
u_int px, py, cy, yy, ny, hsize; |
u_int px, py, oldy, hsize; |
|
|
px = data->cx; |
px = data->cx; |
hsize = screen_hsize(back_s); |
hsize = screen_hsize(back_s); |
py = hsize + data->cy - data->oy; |
py = hsize + data->cy - data->oy; |
|
oldy = data->cy; |
|
|
grid_reader_start(&gr, back_s->grid, px, py); |
grid_reader_start(&gr, back_s->grid, px, py); |
grid_reader_cursor_right(&gr, 1, all); |
grid_reader_cursor_right(&gr, 1, all); |
grid_reader_get_cursor(&gr, &px, &py); |
grid_reader_get_cursor(&gr, &px, &py); |
|
window_copy_acquire_cursor_down(wme, hsize, screen_size_y(back_s), |
/* Scroll down if we went off the visible screen. */ |
data->oy, oldy, px, py, 0); |
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 |
static void |
|
|
{ |
{ |
struct window_copy_mode_data *data = wme->data; |
struct window_copy_mode_data *data = wme->data; |
struct screen *back_s = data->backing; |
struct screen *back_s = data->backing; |
struct grid_cell gc; |
struct grid_reader gr; |
u_int px, py, xx; |
u_int px, py, oldy, hsize; |
|
|
px = data->cx + 1; |
px = data->cx + 1; |
py = screen_hsize(back_s) + data->cy - data->oy; |
hsize = screen_hsize(back_s); |
xx = window_copy_find_length(wme, py); |
py = hsize + data->cy - data->oy; |
|
oldy = data->cy; |
|
|
while (px < xx) { |
grid_reader_start(&gr, back_s->grid, px, py); |
grid_get_cell(back_s->grid, px, py, &gc); |
if (grid_reader_cursor_jump(&gr, data->jumpchar)) { |
if (!(gc.flags & GRID_FLAG_PADDING) && |
grid_reader_get_cursor(&gr, &px, &py); |
gc.data.size == 1 && *gc.data.data == data->jumpchar) { |
window_copy_acquire_cursor_down(wme, hsize, |
window_copy_update_cursor(wme, px, data->cy); |
screen_size_y(back_s), data->oy, oldy, px, py, 0); |
if (window_copy_update_selection(wme, 1, 0)) |
|
window_copy_redraw_lines(wme, data->cy, 1); |
|
return; |
|
} |
|
px++; |
|
} |
} |
} |
} |
|
|
|
|
{ |
{ |
struct window_copy_mode_data *data = wme->data; |
struct window_copy_mode_data *data = wme->data; |
struct screen *back_s = data->backing; |
struct screen *back_s = data->backing; |
struct grid_cell gc; |
struct grid_reader gr; |
u_int px, py; |
u_int px, py, oldy, hsize; |
|
|
px = data->cx; |
px = data->cx; |
py = screen_hsize(back_s) + data->cy - data->oy; |
hsize = screen_hsize(back_s); |
|
py = hsize + data->cy - data->oy; |
|
oldy = data->cy; |
|
|
if (px > 0) |
if (px > 0) |
px--; |
px--; |
|
|
for (;;) { |
grid_reader_start(&gr, back_s->grid, px, py); |
grid_get_cell(back_s->grid, px, py, &gc); |
if (grid_reader_cursor_jump_back(&gr, data->jumpchar)) { |
if (!(gc.flags & GRID_FLAG_PADDING) && |
grid_reader_get_cursor(&gr, &px, &py); |
gc.data.size == 1 && *gc.data.data == data->jumpchar) { |
window_copy_acquire_cursor_up(wme, hsize, data->oy, oldy, px, |
window_copy_update_cursor(wme, px, data->cy); |
py); |
if (window_copy_update_selection(wme, 1, 0)) |
|
window_copy_redraw_lines(wme, data->cy, 1); |
|
return; |
|
} |
|
if (px == 0) |
|
break; |
|
px--; |
|
} |
} |
} |
} |
|
|
|
|
{ |
{ |
struct window_copy_mode_data *data = wme->data; |
struct window_copy_mode_data *data = wme->data; |
struct screen *back_s = data->backing; |
struct screen *back_s = data->backing; |
struct grid_cell gc; |
struct grid_reader gr; |
u_int px, py, xx; |
u_int px, py, oldy, hsize; |
|
|
px = data->cx + 2; |
px = data->cx + 2; |
py = screen_hsize(back_s) + data->cy - data->oy; |
hsize = screen_hsize(back_s); |
xx = window_copy_find_length(wme, py); |
py = hsize + data->cy - data->oy; |
|
oldy = data->cy; |
|
|
while (px < xx) { |
grid_reader_start(&gr, back_s->grid, px, py); |
grid_get_cell(back_s->grid, px, py, &gc); |
if (grid_reader_cursor_jump(&gr, data->jumpchar)) { |
if (!(gc.flags & GRID_FLAG_PADDING) && |
grid_reader_cursor_left(&gr); |
gc.data.size == 1 && *gc.data.data == data->jumpchar) { |
grid_reader_get_cursor(&gr, &px, &py); |
window_copy_update_cursor(wme, px - 1, data->cy); |
window_copy_acquire_cursor_down(wme, hsize, |
if (window_copy_update_selection(wme, 1, 0)) |
screen_size_y(back_s), data->oy, oldy, px, py, 0); |
window_copy_redraw_lines(wme, data->cy, 1); |
|
return; |
|
} |
|
px++; |
|
} |
} |
} |
} |
|
|
|
|
{ |
{ |
struct window_copy_mode_data *data = wme->data; |
struct window_copy_mode_data *data = wme->data; |
struct screen *back_s = data->backing; |
struct screen *back_s = data->backing; |
struct grid_cell gc; |
struct grid_reader gr; |
u_int px, py; |
u_int px, py, oldy, hsize; |
|
|
px = data->cx; |
px = data->cx; |
py = screen_hsize(back_s) + data->cy - data->oy; |
hsize = screen_hsize(back_s); |
|
py = hsize + data->cy - data->oy; |
|
oldy = data->cy; |
|
|
if (px > 0) |
if (px > 0) |
px--; |
px--; |
|
|
if (px > 0) |
if (px > 0) |
px--; |
px--; |
|
|
for (;;) { |
grid_reader_start(&gr, back_s->grid, px, py); |
grid_get_cell(back_s->grid, px, py, &gc); |
if (grid_reader_cursor_jump_back(&gr, data->jumpchar)) { |
if (!(gc.flags & GRID_FLAG_PADDING) && |
grid_reader_cursor_right(&gr, 1, 0); |
gc.data.size == 1 && *gc.data.data == data->jumpchar) { |
grid_reader_get_cursor(&gr, &px, &py); |
window_copy_update_cursor(wme, px + 1, data->cy); |
window_copy_acquire_cursor_up(wme, hsize, data->oy, oldy, px, |
if (window_copy_update_selection(wme, 1, 0)) |
py); |
window_copy_redraw_lines(wme, data->cy, 1); |
|
return; |
|
} |
|
if (px == 0) |
|
break; |
|
px--; |
|
} |
} |
} |
} |
|
|
|
|
struct window_copy_mode_data *data = wme->data; |
struct window_copy_mode_data *data = wme->data; |
struct screen *back_s = data->backing; |
struct screen *back_s = data->backing; |
struct grid_reader gr; |
struct grid_reader gr; |
u_int px, py, cy, oldy, yy, ny, nd, hsize; |
u_int px, py, oldy, hsize; |
|
|
px = data->cx; |
px = data->cx; |
hsize = screen_hsize(back_s); |
hsize = screen_hsize(back_s); |
|
|
grid_reader_start(&gr, back_s->grid, px, py); |
grid_reader_start(&gr, back_s->grid, px, py); |
grid_reader_cursor_next_word(&gr, separators); |
grid_reader_cursor_next_word(&gr, separators); |
grid_reader_get_cursor(&gr, &px, &py); |
grid_reader_get_cursor(&gr, &px, &py); |
|
window_copy_acquire_cursor_down(wme, hsize, screen_size_y(back_s), |
/* Scroll down if we went off the visible screen. */ |
data->oy, oldy, px, py, 0); |
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 |
static void |
|
|
struct options *oo = wp->window->options; |
struct options *oo = wp->window->options; |
struct screen *back_s = data->backing; |
struct screen *back_s = data->backing; |
struct grid_reader gr; |
struct grid_reader gr; |
u_int px, py, cy, oldy, yy, ny, nd, hsize; |
u_int px, py, oldy, hsize; |
int keys; |
int keys; |
|
|
px = data->cx; |
px = data->cx; |
|
|
if (keys == MODEKEY_VI) |
if (keys == MODEKEY_VI) |
grid_reader_cursor_left(&gr); |
grid_reader_cursor_left(&gr); |
grid_reader_get_cursor(&gr, &px, &py); |
grid_reader_get_cursor(&gr, &px, &py); |
|
window_copy_acquire_cursor_down(wme, hsize, screen_size_y(back_s), |
/* Scroll down if we went off the visible screen. */ |
data->oy, oldy, px, py, no_reset); |
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. */ |
/* Compute the previous place where a word begins. */ |
|
|
struct window_copy_mode_data *data = wme->data; |
struct window_copy_mode_data *data = wme->data; |
struct screen *back_s = data->backing; |
struct screen *back_s = data->backing; |
struct grid_reader gr; |
struct grid_reader gr; |
u_int px, py, cy, oldy, yy, ny, nd, hsize; |
u_int px, py, oldy, hsize; |
|
|
px = data->cx; |
px = data->cx; |
hsize = screen_hsize(back_s); |
hsize = screen_hsize(back_s); |
|
|
grid_reader_start(&gr, back_s->grid, px, py); |
grid_reader_start(&gr, back_s->grid, px, py); |
grid_reader_cursor_previous_word(&gr, separators, already); |
grid_reader_cursor_previous_word(&gr, separators, already); |
grid_reader_get_cursor(&gr, &px, &py); |
grid_reader_get_cursor(&gr, &px, &py); |
|
window_copy_acquire_cursor_up(wme, hsize, data->oy, oldy, 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 |
static void |
|
|
data->showmark = 1; |
data->showmark = 1; |
window_copy_update_selection(wme, 0, 0); |
window_copy_update_selection(wme, 0, 0); |
window_copy_redraw_screen(wme); |
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); |
} |
} |