version 1.41, 2010/02/04 20:00:26 |
version 1.42, 2010/02/06 17:35:01 |
|
|
void window_copy_cursor_previous_word(struct window_pane *, const char *); |
void window_copy_cursor_previous_word(struct window_pane *, const char *); |
void window_copy_scroll_up(struct window_pane *, u_int); |
void window_copy_scroll_up(struct window_pane *, u_int); |
void window_copy_scroll_down(struct window_pane *, u_int); |
void window_copy_scroll_down(struct window_pane *, u_int); |
|
void window_copy_rectangle_toggle(struct window_pane *); |
|
|
const struct window_mode window_copy_mode = { |
const struct window_mode window_copy_mode = { |
window_copy_init, |
window_copy_init, |
|
|
u_int selx; |
u_int selx; |
u_int sely; |
u_int sely; |
|
|
|
u_int rectflag; /* are we in rectangle copy mode? */ |
|
|
u_int cx; |
u_int cx; |
u_int cy; |
u_int cy; |
|
|
|
|
data->lastcx = 0; |
data->lastcx = 0; |
data->lastsx = 0; |
data->lastsx = 0; |
|
|
|
data->rectflag = 0; |
|
|
data->inputtype = WINDOW_COPY_OFF; |
data->inputtype = WINDOW_COPY_OFF; |
data->inputprompt = NULL; |
data->inputprompt = NULL; |
data->inputstr = xstrdup(""); |
data->inputstr = xstrdup(""); |
|
|
data->inputprompt = "Goto Line"; |
data->inputprompt = "Goto Line"; |
*data->inputstr = '\0'; |
*data->inputstr = '\0'; |
goto input_on; |
goto input_on; |
|
case MODEKEYCOPY_RECTANGLETOGGLE: |
|
window_copy_rectangle_toggle(wp); |
|
return; |
default: |
default: |
break; |
break; |
} |
} |
|
|
struct screen *s = &data->screen; |
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, ty; |
u_int sx, sy, ty, cy; |
|
|
if (!s->sel.flag) |
if (!s->sel.flag) |
return (0); |
return (0); |
|
|
sx = data->selx; |
sx = data->selx; |
sy = data->sely; |
sy = data->sely; |
if (sy < ty) { /* above screen */ |
if (sy < ty) { /* above screen */ |
sx = 0; |
if (!data->rectflag) |
|
sx = 0; |
sy = 0; |
sy = 0; |
} else if (sy > ty + screen_size_y(s) - 1) { /* below screen */ |
} else if (sy > ty + screen_size_y(s) - 1) { /* below screen */ |
sx = screen_size_x(s) - 1; |
if (!data->rectflag) |
|
sx = screen_size_x(s) - 1; |
sy = screen_size_y(s) - 1; |
sy = screen_size_y(s) - 1; |
} else |
} else |
sy -= ty; |
sy -= ty; |
sy = screen_hsize(s) + sy; |
sy = screen_hsize(s) + sy; |
|
|
screen_set_selection( |
screen_set_selection(s, |
s, sx, sy, data->cx, screen_hsize(s) + data->cy, &gc); |
sx, sy, data->cx, screen_hsize(s) + data->cy, data->rectflag, &gc); |
|
|
|
if (data->rectflag) { |
|
/* |
|
* Can't rely on the caller to redraw the right lines for |
|
* rectangle selection - find the highest line and the number |
|
* of lines, and redraw just past that in both directions |
|
*/ |
|
cy = data->cy; |
|
if (sy < cy) |
|
window_copy_redraw_lines(wp, sy, cy - sy + 1); |
|
else |
|
window_copy_redraw_lines(wp, cy, sy - cy + 1); |
|
} |
|
|
return (1); |
return (1); |
} |
} |
|
|
|
|
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; |
char *buf; |
char *buf; |
size_t off; |
size_t off; |
u_int i, xx, yy, sx, sy, ex, ey, limit; |
u_int i, xx, yy, sx, sy, ex, ey, limit; |
|
u_int firstsx, lastex, restex, restsx; |
|
|
if (!s->sel.flag) |
if (!s->sel.flag) |
return; |
return; |
|
|
if (ex > xx) |
if (ex > xx) |
ex = xx; |
ex = xx; |
|
|
|
/* |
|
* Deal with rectangle-copy if necessary; four situations: start of |
|
* first line (firstsx), end of last line (lastex), start (restsx) and |
|
* end (restex) of all other lines. |
|
*/ |
|
xx = screen_size_x(s); |
|
if (data->rectflag) { |
|
/* |
|
* Need to ignore the column with the cursor in it, which for |
|
* rectangular copy means knowing which side the cursor is on. |
|
*/ |
|
if (data->selx < data->cx) { |
|
/* Selection start is on the left. */ |
|
lastex = data->cx; |
|
restex = data->cx; |
|
firstsx = data->selx; |
|
restsx = data->selx; |
|
} else { |
|
/* Cursor is on the left. */ |
|
lastex = data->selx + 1; |
|
restex = data->selx + 1; |
|
firstsx = data->cx + 1; |
|
restsx = data->cx + 1; |
|
} |
|
} else { |
|
/* |
|
* Like emacs, keep the top-left-most character, and drop the |
|
* bottom-right-most, regardless of copy direction. |
|
*/ |
|
lastex = ex; |
|
restex = xx; |
|
firstsx = sx; |
|
restsx = 0; |
|
} |
|
|
/* Copy the lines. */ |
/* Copy the lines. */ |
if (sy == ey) |
if (sy == ey) |
window_copy_copy_line(wp, &buf, &off, sy, sx, ex); |
window_copy_copy_line(wp, &buf, &off, sy, firstsx, lastex); |
else { |
else { |
xx = screen_size_x(s); |
window_copy_copy_line(wp, &buf, &off, sy, firstsx, restex); |
window_copy_copy_line(wp, &buf, &off, sy, sx, xx); |
|
if (ey - sy > 1) { |
if (ey - sy > 1) { |
for (i = sy + 1; i < ey; i++) |
for (i = sy + 1; i < ey; i++) { |
window_copy_copy_line(wp, &buf, &off, i, 0, xx); |
window_copy_copy_line( |
|
wp, &buf, &off, i, restsx, restex); |
|
} |
} |
} |
window_copy_copy_line(wp, &buf, &off, ey, 0, ex); |
window_copy_copy_line(wp, &buf, &off, ey, restsx, lastex); |
} |
} |
|
|
/* Don't bother if no data. */ |
/* Don't bother if no data. */ |
|
|
if (ny == 0) |
if (ny == 0) |
return; |
return; |
data->oy -= ny; |
data->oy -= ny; |
window_copy_update_selection(wp); |
|
|
|
screen_write_start(&ctx, wp, NULL); |
screen_write_start(&ctx, wp, NULL); |
screen_write_cursormove(&ctx, 0, 0); |
screen_write_cursormove(&ctx, 0, 0); |
|
|
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.flag && screen_size_y(s) > ny) { |
|
window_copy_update_selection(wp); |
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); |
|
window_copy_update_selection(wp); |
screen_write_stop(&ctx); |
screen_write_stop(&ctx); |
} |
} |
|
|
|
|
if (ny == 0) |
if (ny == 0) |
return; |
return; |
data->oy += ny; |
data->oy += ny; |
window_copy_update_selection(wp); |
|
|
|
screen_write_start(&ctx, wp, NULL); |
screen_write_start(&ctx, wp, NULL); |
screen_write_cursormove(&ctx, 0, 0); |
screen_write_cursormove(&ctx, 0, 0); |
screen_write_insertline(&ctx, ny); |
screen_write_insertline(&ctx, ny); |
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.flag && screen_size_y(s) > ny) { |
|
window_copy_update_selection(wp); |
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); |
screen_write_cursormove(&ctx, data->cx, data->cy); |
screen_write_cursormove(&ctx, data->cx, data->cy); |
|
window_copy_update_selection(wp); |
screen_write_stop(&ctx); |
screen_write_stop(&ctx); |
} |
} |
|
|
|
void |
|
window_copy_rectangle_toggle(struct window_pane *wp) |
|
{ |
|
struct window_copy_mode_data *data = wp->modedata; |
|
|
|
data->rectflag = !data->rectflag; |
|
|
|
window_copy_update_selection(wp); |
|
window_copy_redraw_screen(wp); |
|
} |
|
|