version 1.191, 2018/07/06 07:11:23 |
version 1.192, 2018/07/31 11:49:26 |
|
|
static void window_copy_start_selection(struct window_pane *); |
static void window_copy_start_selection(struct window_pane *); |
static int window_copy_adjust_selection(struct window_pane *, u_int *, |
static int window_copy_adjust_selection(struct window_pane *, u_int *, |
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 int window_copy_update_selection(struct window_pane *, int); |
static void window_copy_synchronize_cursor(struct window_pane *wp); |
static void window_copy_synchronize_cursor(struct window_pane *); |
static void *window_copy_get_selection(struct window_pane *, size_t *); |
static void *window_copy_get_selection(struct window_pane *, size_t *); |
static void window_copy_copy_buffer(struct window_pane *, const char *, |
static void window_copy_copy_buffer(struct window_pane *, const char *, |
void *, size_t); |
void *, size_t); |
|
|
struct screen *backing; |
struct screen *backing; |
int backing_written; /* backing display started */ |
int backing_written; /* backing display started */ |
|
|
u_int oy; /* number of lines scrolled up */ |
u_int oy; /* number of lines scrolled up */ |
|
|
u_int selx; /* beginning of selection */ |
u_int selx; /* beginning of selection */ |
u_int sely; |
u_int sely; |
|
|
u_int endselx; /* end of selection */ |
u_int endselx; /* end of selection */ |
u_int endsely; |
u_int endsely; |
|
|
enum { |
enum { |
|
|
CURSORDRAG_SEL, /* start is synchronized with cursor */ |
CURSORDRAG_SEL, /* start is synchronized with cursor */ |
} cursordrag; |
} 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 rectflag; /* in rectangle copy mode? */ |
int scroll_exit; /* exit on scroll to end? */ |
int scroll_exit; /* exit on scroll to end? */ |
|
|
u_int cx; |
u_int cx; |
u_int cy; |
u_int cy; |
|
|
u_int lastcx; /* position in last line w/ content */ |
u_int lastcx; /* position in last line w/ content */ |
u_int lastsx; /* size of last line w/ content */ |
u_int lastsx; /* size of last line w/ content */ |
|
|
int searchtype; |
int searchtype; |
char *searchstr; |
char *searchstr; |
|
|
|
|
s = &data->screen; |
s = &data->screen; |
screen_init(s, screen_size_x(&wp->base), screen_size_y(&wp->base), 0); |
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->modekeys = options_get_number(wp->window->options, "mode-keys"); |
|
|
data->backing = NULL; |
data->backing = NULL; |
|
|
|
|
oy = screen_hsize(data->backing) + data->cy - data->oy; |
oy = screen_hsize(data->backing) + data->cy - data->oy; |
ox = window_copy_find_length(wp, oy); |
ox = window_copy_find_length(wp, oy); |
|
|
if (s->sel.lineflag == LINE_SEL_LEFT_RIGHT && oy == data->sely) |
if (data->lineflag == LINE_SEL_LEFT_RIGHT && oy == data->sely) |
window_copy_other_end(wp); |
window_copy_other_end(wp); |
|
|
if (data->cx != ox) { |
if (data->cx != ox) { |
|
|
else |
else |
data->oy += n; |
data->oy += n; |
|
|
if (!data->screen.sel.flag || !data->rectflag) { |
if (data->screen.sel == NULL || !data->rectflag) { |
py = screen_hsize(data->backing) + data->cy - data->oy; |
py = screen_hsize(data->backing) + data->cy - data->oy; |
px = window_copy_find_length(wp, py); |
px = window_copy_find_length(wp, py); |
if ((data->cx >= data->lastsx && data->cx != px) || |
if ((data->cx >= data->lastsx && data->cx != px) || |
|
|
oy = screen_hsize(data->backing) + data->cy - data->oy; |
oy = screen_hsize(data->backing) + data->cy - data->oy; |
ox = window_copy_find_length(wp, oy); |
ox = window_copy_find_length(wp, oy); |
|
|
if (s->sel.lineflag == LINE_SEL_RIGHT_LEFT && oy == data->sely) |
if (data->lineflag == LINE_SEL_RIGHT_LEFT && oy == data->sely) |
window_copy_other_end(wp); |
window_copy_other_end(wp); |
|
|
if (data->cx != ox) { |
if (data->cx != ox) { |
|
|
else |
else |
data->oy -= n; |
data->oy -= n; |
|
|
if (!data->screen.sel.flag || !data->rectflag) { |
if (data->screen.sel == NULL || !data->rectflag) { |
py = screen_hsize(data->backing) + data->cy - data->oy; |
py = screen_hsize(data->backing) + data->cy - data->oy; |
px = window_copy_find_length(wp, py); |
px = window_copy_find_length(wp, py); |
if ((data->cx >= data->lastsx && data->cx != px) || |
if ((data->cx >= data->lastsx && data->cx != px) || |
|
|
if (m != NULL) |
if (m != NULL) |
window_copy_start_drag(c, m); |
window_copy_start_drag(c, m); |
else { |
else { |
sn->sel.lineflag = LINE_SEL_NONE; |
data->lineflag = LINE_SEL_NONE; |
window_copy_start_selection(wp); |
window_copy_start_selection(wp); |
redraw = 1; |
redraw = 1; |
} |
} |
|
|
window_copy_cursor_previous_word(wp, ws); |
window_copy_cursor_previous_word(wp, ws); |
} |
} |
if (strcmp(command, "rectangle-toggle") == 0) { |
if (strcmp(command, "rectangle-toggle") == 0) { |
sn->sel.lineflag = LINE_SEL_NONE; |
data->lineflag = LINE_SEL_NONE; |
window_copy_rectangle_toggle(wp); |
window_copy_rectangle_toggle(wp); |
} |
} |
if (strcmp(command, "scroll-down") == 0 || |
if (strcmp(command, "scroll-down") == 0 || |
|
|
} |
} |
} |
} |
if (strcmp(command, "select-line") == 0) { |
if (strcmp(command, "select-line") == 0) { |
sn->sel.lineflag = LINE_SEL_LEFT_RIGHT; |
data->lineflag = LINE_SEL_LEFT_RIGHT; |
data->rectflag = 0; |
data->rectflag = 0; |
window_copy_cursor_start_of_line(wp); |
window_copy_cursor_start_of_line(wp); |
window_copy_start_selection(wp); |
window_copy_start_selection(wp); |
|
|
redraw = 1; |
redraw = 1; |
} |
} |
if (strcmp(command, "select-word") == 0) { |
if (strcmp(command, "select-word") == 0) { |
sn->sel.lineflag = LINE_SEL_LEFT_RIGHT; |
data->lineflag = LINE_SEL_LEFT_RIGHT; |
data->rectflag = 0; |
data->rectflag = 0; |
ws = options_get_string(s->options, "word-separators"); |
ws = options_get_string(s->options, "word-separators"); |
window_copy_cursor_previous_word(wp, ws); |
window_copy_cursor_previous_word(wp, ws); |
|
|
window_copy_start_selection(struct window_pane *wp) |
window_copy_start_selection(struct window_pane *wp) |
{ |
{ |
struct window_copy_mode_data *data = wp->modedata; |
struct window_copy_mode_data *data = wp->modedata; |
struct screen *s = &data->screen; |
|
|
|
data->selx = data->cx; |
data->selx = data->cx; |
data->sely = screen_hsize(data->backing) + data->cy - data->oy; |
data->sely = screen_hsize(data->backing) + data->cy - data->oy; |
|
|
|
|
data->cursordrag = CURSORDRAG_ENDSEL; |
data->cursordrag = CURSORDRAG_ENDSEL; |
|
|
s->sel.flag = 1; |
window_copy_set_selection(wp, 1); |
window_copy_update_selection(wp, 1); |
|
} |
} |
|
|
static int |
static int |
|
|
{ |
{ |
struct window_copy_mode_data *data = wp->modedata; |
struct window_copy_mode_data *data = wp->modedata; |
struct screen *s = &data->screen; |
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 options *oo = wp->window->options; |
struct grid_cell gc; |
struct grid_cell gc; |
u_int sx, sy, cy, endsx, endsy; |
u_int sx, sy, cy, endsx, endsy; |
int startrelpos, endrelpos; |
int startrelpos, endrelpos; |
|
|
if (!s->sel.flag && s->sel.lineflag == LINE_SEL_NONE) |
|
return (0); |
|
|
|
window_copy_synchronize_cursor(wp); |
window_copy_synchronize_cursor(wp); |
|
|
/* Adjust the selection. */ |
/* Adjust the selection. */ |
|
|
/* Set colours and selection. */ |
/* Set colours and selection. */ |
style_apply(&gc, oo, "mode-style"); |
style_apply(&gc, oo, "mode-style"); |
gc.flags |= GRID_FLAG_NOPALETTE; |
gc.flags |= GRID_FLAG_NOPALETTE; |
screen_set_selection(s, sx, sy, endsx, endsy, data->rectflag, &gc); |
screen_set_selection(s, sx, sy, endsx, endsy, data->rectflag, |
|
data->modekeys, &gc); |
|
|
if (data->rectflag && may_redraw) { |
if (data->rectflag && may_redraw) { |
/* |
/* |
|
|
u_int firstsx, lastex, restex, restsx, selx; |
u_int firstsx, lastex, restex, restsx, selx; |
int keys; |
int keys; |
|
|
if (!s->sel.flag && s->sel.lineflag == LINE_SEL_NONE) |
if (data->screen.sel == NULL && data->lineflag == LINE_SEL_NONE) |
return (NULL); |
return (NULL); |
|
|
buf = xmalloc(1); |
buf = xmalloc(1); |
|
|
{ |
{ |
struct window_copy_mode_data *data = wp->modedata; |
struct window_copy_mode_data *data = wp->modedata; |
struct screen *back_s = data->backing; |
struct screen *back_s = data->backing; |
struct screen *s = &data->screen; |
|
struct grid *gd = back_s->grid; |
struct grid *gd = back_s->grid; |
u_int py; |
u_int py; |
|
|
if (data->cx == 0 && s->sel.lineflag == LINE_SEL_NONE) { |
if (data->cx == 0 && data->lineflag == LINE_SEL_NONE) { |
py = screen_hsize(back_s) + data->cy - data->oy; |
py = screen_hsize(back_s) + data->cy - data->oy; |
while (py > 0 && |
while (py > 0 && |
grid_get_line(gd, py - 1)->flags & GRID_LINE_WRAPPED) { |
grid_get_line(gd, py - 1)->flags & GRID_LINE_WRAPPED) { |
|
|
{ |
{ |
struct window_copy_mode_data *data = wp->modedata; |
struct window_copy_mode_data *data = wp->modedata; |
struct screen *back_s = data->backing; |
struct screen *back_s = data->backing; |
struct screen *s = &data->screen; |
|
struct grid *gd = back_s->grid; |
struct grid *gd = back_s->grid; |
struct grid_line *gl; |
struct grid_line *gl; |
u_int px, py; |
u_int px, py; |
|
|
py = screen_hsize(back_s) + data->cy - data->oy; |
py = screen_hsize(back_s) + data->cy - data->oy; |
px = window_copy_find_length(wp, py); |
px = window_copy_find_length(wp, py); |
|
|
if (data->cx == px && s->sel.lineflag == LINE_SEL_NONE) { |
if (data->cx == px && data->lineflag == LINE_SEL_NONE) { |
if (data->screen.sel.flag && data->rectflag) |
if (data->screen.sel != NULL && data->rectflag) |
px = screen_size_x(back_s); |
px = screen_size_x(back_s); |
gl = grid_get_line(gd, py); |
gl = grid_get_line(gd, py); |
if (gl->flags & GRID_LINE_WRAPPED) { |
if (gl->flags & GRID_LINE_WRAPPED) { |
|
|
struct screen *s = &data->screen; |
struct screen *s = &data->screen; |
u_int selx, sely, cy, yy, hsize; |
u_int selx, sely, cy, yy, hsize; |
|
|
if (!s->sel.flag && s->sel.lineflag == LINE_SEL_NONE) |
if (s->sel == NULL && data->lineflag == LINE_SEL_NONE) |
return; |
return; |
|
|
if (s->sel.lineflag == LINE_SEL_LEFT_RIGHT) |
if (data->lineflag == LINE_SEL_LEFT_RIGHT) |
s->sel.lineflag = LINE_SEL_RIGHT_LEFT; |
data->lineflag = LINE_SEL_RIGHT_LEFT; |
else if (s->sel.lineflag == LINE_SEL_RIGHT_LEFT) |
else if (data->lineflag == LINE_SEL_RIGHT_LEFT) |
s->sel.lineflag = LINE_SEL_LEFT_RIGHT; |
data->lineflag = LINE_SEL_LEFT_RIGHT; |
|
|
switch (data->cursordrag) { |
switch (data->cursordrag) { |
case CURSORDRAG_NONE: |
case CURSORDRAG_NONE: |
|
|
|
|
py = screen_hsize(data->backing) + data->cy - data->oy; |
py = screen_hsize(data->backing) + data->cy - data->oy; |
yy = screen_hsize(data->backing) + screen_size_y(data->backing) - 1; |
yy = screen_hsize(data->backing) + screen_size_y(data->backing) - 1; |
if (data->screen.sel.flag && data->rectflag) |
if (data->screen.sel != NULL && data->rectflag) |
px = screen_size_x(&data->screen); |
px = screen_size_x(&data->screen); |
else |
else |
px = window_copy_find_length(wp, py); |
px = window_copy_find_length(wp, py); |
|
|
data->lastsx = ox; |
data->lastsx = ox; |
} |
} |
|
|
if (s->sel.lineflag == LINE_SEL_LEFT_RIGHT && oy == data->sely) |
if (data->lineflag == LINE_SEL_LEFT_RIGHT && oy == data->sely) |
window_copy_other_end(wp); |
window_copy_other_end(wp); |
|
|
data->cx = data->lastcx; |
data->cx = data->lastcx; |
|
|
} |
} |
} |
} |
|
|
if (!data->screen.sel.flag || !data->rectflag) { |
if (data->screen.sel != NULL || !data->rectflag) { |
py = screen_hsize(data->backing) + data->cy - data->oy; |
py = screen_hsize(data->backing) + data->cy - data->oy; |
px = window_copy_find_length(wp, py); |
px = window_copy_find_length(wp, py); |
if ((data->cx >= data->lastsx && data->cx != px) || |
if ((data->cx >= data->lastsx && data->cx != px) || |
|
|
window_copy_cursor_end_of_line(wp); |
window_copy_cursor_end_of_line(wp); |
} |
} |
|
|
if (s->sel.lineflag == LINE_SEL_LEFT_RIGHT) |
if (data->lineflag == LINE_SEL_LEFT_RIGHT) |
window_copy_cursor_end_of_line(wp); |
window_copy_cursor_end_of_line(wp); |
else if (s->sel.lineflag == LINE_SEL_RIGHT_LEFT) |
else if (data->lineflag == LINE_SEL_RIGHT_LEFT) |
window_copy_cursor_start_of_line(wp); |
window_copy_cursor_start_of_line(wp); |
} |
} |
|
|
|
|
data->lastsx = ox; |
data->lastsx = ox; |
} |
} |
|
|
if (s->sel.lineflag == LINE_SEL_RIGHT_LEFT && oy == data->endsely) |
if (data->lineflag == LINE_SEL_RIGHT_LEFT && oy == data->endsely) |
window_copy_other_end(wp); |
window_copy_other_end(wp); |
|
|
data->cx = data->lastcx; |
data->cx = data->lastcx; |
|
|
window_copy_redraw_lines(wp, data->cy - 1, 2); |
window_copy_redraw_lines(wp, data->cy - 1, 2); |
} |
} |
|
|
if (!data->screen.sel.flag || !data->rectflag) { |
if (data->screen.sel == NULL || !data->rectflag) { |
py = screen_hsize(data->backing) + data->cy - data->oy; |
py = screen_hsize(data->backing) + data->cy - data->oy; |
px = window_copy_find_length(wp, py); |
px = window_copy_find_length(wp, py); |
if ((data->cx >= data->lastsx && data->cx != px) || |
if ((data->cx >= data->lastsx && data->cx != px) || |
|
|
window_copy_cursor_end_of_line(wp); |
window_copy_cursor_end_of_line(wp); |
} |
} |
|
|
if (s->sel.lineflag == LINE_SEL_LEFT_RIGHT) |
if (data->lineflag == LINE_SEL_LEFT_RIGHT) |
window_copy_cursor_end_of_line(wp); |
window_copy_cursor_end_of_line(wp); |
else if (s->sel.lineflag == LINE_SEL_RIGHT_LEFT) |
else if (data->lineflag == LINE_SEL_RIGHT_LEFT) |
window_copy_cursor_start_of_line(wp); |
window_copy_cursor_start_of_line(wp); |
} |
} |
|
|
|
|
window_copy_write_line(wp, &ctx, 1); |
window_copy_write_line(wp, &ctx, 1); |
if (screen_size_y(s) > 3) |
if (screen_size_y(s) > 3) |
window_copy_write_line(wp, &ctx, screen_size_y(s) - 2); |
window_copy_write_line(wp, &ctx, screen_size_y(s) - 2); |
if (s->sel.flag && screen_size_y(s) > ny) |
if (s->sel != NULL && screen_size_y(s) > ny) |
window_copy_write_line(wp, &ctx, screen_size_y(s) - ny - 1); |
window_copy_write_line(wp, &ctx, screen_size_y(s) - ny - 1); |
screen_write_cursormove(&ctx, data->cx, data->cy); |
screen_write_cursormove(&ctx, data->cx, data->cy); |
screen_write_stop(&ctx); |
screen_write_stop(&ctx); |
|
|
screen_write_cursormove(&ctx, 0, 0); |
screen_write_cursormove(&ctx, 0, 0); |
screen_write_insertline(&ctx, ny, 8); |
screen_write_insertline(&ctx, ny, 8); |
window_copy_write_lines(wp, &ctx, 0, ny); |
window_copy_write_lines(wp, &ctx, 0, ny); |
if (s->sel.flag && screen_size_y(s) > ny) |
if (s->sel != NULL && screen_size_y(s) > ny) |
window_copy_write_line(wp, &ctx, 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); |
window_copy_write_line(wp, &ctx, 1); |
|
|
if (wp->mode != &window_copy_mode) |
if (wp->mode != &window_copy_mode) |
return; |
return; |
|
|
format_add(ft, "selection_present", "%d", data->screen.sel.flag); |
format_add(ft, "selection_present", "%d", data->screen.sel != NULL); |
format_add(ft, "scroll_position", "%d", data->oy); |
format_add(ft, "scroll_position", "%d", data->oy); |
format_add(ft, "rectangle_toggle", "%d", data->rectflag); |
format_add(ft, "rectangle_toggle", "%d", data->rectflag); |
} |
} |