mirror of
https://github.com/tmux/tmux.git
synced 2025-04-22 12:28:48 +00:00
Sync OpenBSD patchset 636:
Rectangle copy support, from Robin Lee Powell.
This commit is contained in:
parent
a32d095c97
commit
3c37b09272
@ -1,4 +1,4 @@
|
|||||||
/* $Id: mode-key.c,v 1.42 2010-02-05 01:34:08 tcunha Exp $ */
|
/* $Id: mode-key.c,v 1.43 2010-02-08 18:13:17 tcunha Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
|
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||||
@ -89,6 +89,7 @@ struct mode_key_cmdstr mode_key_cmdstr_copy[] = {
|
|||||||
{ MODEKEYCOPY_HISTORYBOTTOM, "history-bottom" },
|
{ MODEKEYCOPY_HISTORYBOTTOM, "history-bottom" },
|
||||||
{ MODEKEYCOPY_HISTORYTOP, "history-top" },
|
{ MODEKEYCOPY_HISTORYTOP, "history-top" },
|
||||||
{ MODEKEYCOPY_LEFT, "cursor-left" },
|
{ MODEKEYCOPY_LEFT, "cursor-left" },
|
||||||
|
{ MODEKEYCOPY_RECTANGLETOGGLE, "rectangle-toggle" },
|
||||||
{ MODEKEYCOPY_MIDDLELINE, "middle-line" },
|
{ MODEKEYCOPY_MIDDLELINE, "middle-line" },
|
||||||
{ MODEKEYCOPY_NEXTPAGE, "page-down" },
|
{ MODEKEYCOPY_NEXTPAGE, "page-down" },
|
||||||
{ MODEKEYCOPY_NEXTSPACE, "next-space" },
|
{ MODEKEYCOPY_NEXTSPACE, "next-space" },
|
||||||
@ -207,6 +208,7 @@ const struct mode_key_entry mode_key_vi_copy[] = {
|
|||||||
{ 'l', 0, MODEKEYCOPY_RIGHT },
|
{ 'l', 0, MODEKEYCOPY_RIGHT },
|
||||||
{ 'n', 0, MODEKEYCOPY_SEARCHAGAIN },
|
{ 'n', 0, MODEKEYCOPY_SEARCHAGAIN },
|
||||||
{ 'q', 0, MODEKEYCOPY_CANCEL },
|
{ 'q', 0, MODEKEYCOPY_CANCEL },
|
||||||
|
{ 'v', 0, MODEKEYCOPY_RECTANGLETOGGLE },
|
||||||
{ 'w', 0, MODEKEYCOPY_NEXTWORD },
|
{ 'w', 0, MODEKEYCOPY_NEXTWORD },
|
||||||
{ KEYC_BSPACE, 0, MODEKEYCOPY_LEFT },
|
{ KEYC_BSPACE, 0, MODEKEYCOPY_LEFT },
|
||||||
{ KEYC_DOWN | KEYC_CTRL,0, MODEKEYCOPY_SCROLLDOWN },
|
{ KEYC_DOWN | KEYC_CTRL,0, MODEKEYCOPY_SCROLLDOWN },
|
||||||
@ -276,9 +278,10 @@ struct mode_key_tree mode_key_tree_emacs_choice;
|
|||||||
/* emacs copy mode keys. */
|
/* emacs copy mode keys. */
|
||||||
const struct mode_key_entry mode_key_emacs_copy[] = {
|
const struct mode_key_entry mode_key_emacs_copy[] = {
|
||||||
{ ' ', 0, MODEKEYCOPY_NEXTPAGE },
|
{ ' ', 0, MODEKEYCOPY_NEXTPAGE },
|
||||||
{ '<' | KEYC_ESCAPE,0, MODEKEYCOPY_HISTORYTOP },
|
{ '<' | KEYC_ESCAPE, 0, MODEKEYCOPY_HISTORYTOP },
|
||||||
{ '>' | KEYC_ESCAPE, 0, MODEKEYCOPY_HISTORYBOTTOM },
|
{ '>' | KEYC_ESCAPE, 0, MODEKEYCOPY_HISTORYBOTTOM },
|
||||||
{ 'R' | KEYC_ESCAPE, 0, MODEKEYCOPY_TOPLINE },
|
{ 'R' | KEYC_ESCAPE, 0, MODEKEYCOPY_TOPLINE },
|
||||||
|
{ 'R', 0, MODEKEYCOPY_RECTANGLETOGGLE },
|
||||||
{ '\000' /* C-Space */, 0, MODEKEYCOPY_STARTSELECTION },
|
{ '\000' /* C-Space */, 0, MODEKEYCOPY_STARTSELECTION },
|
||||||
{ '\001' /* C-a */, 0, MODEKEYCOPY_STARTOFLINE },
|
{ '\001' /* C-a */, 0, MODEKEYCOPY_STARTOFLINE },
|
||||||
{ '\002' /* C-b */, 0, MODEKEYCOPY_LEFT },
|
{ '\002' /* C-b */, 0, MODEKEYCOPY_LEFT },
|
||||||
|
115
screen.c
115
screen.c
@ -1,4 +1,4 @@
|
|||||||
/* $Id: screen.c,v 1.98 2010-01-05 23:54:53 tcunha Exp $ */
|
/* $Id: screen.c,v 1.99 2010-02-08 18:13:17 tcunha Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||||
@ -227,41 +227,17 @@ screen_resize_y(struct screen *s, u_int sy)
|
|||||||
|
|
||||||
/* Set selection. */
|
/* Set selection. */
|
||||||
void
|
void
|
||||||
screen_set_selection(struct screen *s,
|
screen_set_selection(struct screen *s, u_int sx, u_int sy,
|
||||||
u_int sx, u_int sy, u_int ex, u_int ey, struct grid_cell *gc)
|
u_int ex, u_int ey, u_int rectflag, struct grid_cell *gc)
|
||||||
{
|
{
|
||||||
struct screen_sel *sel = &s->sel;
|
struct screen_sel *sel = &s->sel;
|
||||||
|
|
||||||
memcpy(&sel->cell, gc, sizeof sel->cell);
|
memcpy(&sel->cell, gc, sizeof sel->cell);
|
||||||
sel->flag = 1;
|
sel->flag = 1;
|
||||||
|
sel->rectflag = rectflag;
|
||||||
|
|
||||||
/* starting line < ending line -- downward selection. */
|
sel->sx = sx; sel->sy = sy;
|
||||||
if (sy < ey) {
|
sel->ex = ex; sel->ey = ey;
|
||||||
sel->sx = sx; sel->sy = sy;
|
|
||||||
sel->ex = ex; sel->ey = ey;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* starting line > ending line -- upward selection. */
|
|
||||||
if (sy > ey) {
|
|
||||||
if (sx > 0) {
|
|
||||||
sel->sx = ex; sel->sy = ey;
|
|
||||||
sel->ex = sx - 1; sel->ey = sy;
|
|
||||||
} else {
|
|
||||||
sel->sx = ex; sel->sy = ey;
|
|
||||||
sel->ex = -1; sel->ey = sy - 1;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* starting line == ending line. */
|
|
||||||
if (ex < sx) {
|
|
||||||
sel->sx = ex; sel->sy = ey;
|
|
||||||
sel->ex = sx - 1; sel->ey = sy;
|
|
||||||
} else {
|
|
||||||
sel->sx = sx; sel->sy = sy;
|
|
||||||
sel->ex = ex; sel->ey = ey;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Clear selection. */
|
/* Clear selection. */
|
||||||
@ -279,16 +255,81 @@ screen_check_selection(struct screen *s, u_int px, u_int py)
|
|||||||
{
|
{
|
||||||
struct screen_sel *sel = &s->sel;
|
struct screen_sel *sel = &s->sel;
|
||||||
|
|
||||||
if (!sel->flag || py < sel->sy || py > sel->ey)
|
if (!sel->flag)
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
if (py == sel->sy && py == sel->ey) {
|
if (sel->rectflag) {
|
||||||
if (px < sel->sx || px > sel->ex)
|
if (sel->sy < sel->ey) {
|
||||||
return (0);
|
/* start line < end line -- downward selection. */
|
||||||
return (1);
|
if (py < sel->sy || py > sel->ey)
|
||||||
|
return (0);
|
||||||
|
} else if (sel->sy > sel->ey) {
|
||||||
|
/* start line > end line -- upward selection. */
|
||||||
|
if (py > sel->sy || py < sel->ey)
|
||||||
|
return (0);
|
||||||
|
} else {
|
||||||
|
/* starting line == ending line. */
|
||||||
|
if (py != sel->sy)
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Need to include the selection start row, but not the cursor
|
||||||
|
* row, which means the selection changes depending on which
|
||||||
|
* one is on the left.
|
||||||
|
*/
|
||||||
|
if (sel->ex < sel->sx) {
|
||||||
|
/* Cursor (ex) is on the left. */
|
||||||
|
if (px <= sel->ex)
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
if (px > sel->sx)
|
||||||
|
return (0);
|
||||||
|
} else {
|
||||||
|
/* Selection start (sx) is on the left. */
|
||||||
|
if (px < sel->sx)
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
if (px >= sel->ex)
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* Like emacs, keep the top-left-most character, and drop the
|
||||||
|
* bottom-right-most, regardless of copy direction.
|
||||||
|
*/
|
||||||
|
if (sel->sy < sel->ey) {
|
||||||
|
/* starting line < ending line -- downward selection. */
|
||||||
|
if (py < sel->sy || py > sel->ey)
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
if ((py == sel->sy && px < sel->sx)
|
||||||
|
|| (py == sel->ey && px > sel->ex))
|
||||||
|
return (0);
|
||||||
|
} else if (sel->sy > sel->ey) {
|
||||||
|
/* starting line > ending line -- upward selection. */
|
||||||
|
if (py > sel->sy || py < sel->ey)
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
if ((py == sel->sy && px >= sel->sx)
|
||||||
|
|| (py == sel->ey && px < sel->ex))
|
||||||
|
return (0);
|
||||||
|
} else {
|
||||||
|
/* starting line == ending line. */
|
||||||
|
if (py != sel->sy)
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
if (sel->ex < sel->sx) {
|
||||||
|
/* cursor (ex) is on the left */
|
||||||
|
if (px > sel->sx || px < sel->ex)
|
||||||
|
return (0);
|
||||||
|
} else {
|
||||||
|
/* selection start (sx) is on the left */
|
||||||
|
if (px < sel->sx || px > sel->ex)
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((py == sel->sy && px < sel->sx) || (py == sel->ey && px > sel->ex))
|
|
||||||
return (0);
|
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
5
tmux.1
5
tmux.1
@ -1,4 +1,4 @@
|
|||||||
.\" $Id: tmux.1,v 1.228 2010-02-05 01:34:08 tcunha Exp $
|
.\" $Id: tmux.1,v 1.229 2010-02-08 18:13:17 tcunha Exp $
|
||||||
.\"
|
.\"
|
||||||
.\" Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
.\" Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||||
.\"
|
.\"
|
||||||
@ -14,7 +14,7 @@
|
|||||||
.\" IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
.\" IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||||
.\" OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
.\" OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
.\"
|
.\"
|
||||||
.Dd $Mdocdate: February 4 2010 $
|
.Dd $Mdocdate: February 6 2010 $
|
||||||
.Dt TMUX 1
|
.Dt TMUX 1
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -564,6 +564,7 @@ The following keys are supported as appropriate for the mode:
|
|||||||
.It Li "Previous word" Ta "b" Ta "M-b"
|
.It Li "Previous word" Ta "b" Ta "M-b"
|
||||||
.It Li "Previous space" Ta "B" Ta ""
|
.It Li "Previous space" Ta "B" Ta ""
|
||||||
.It Li "Quit mode" Ta "q" Ta "Escape"
|
.It Li "Quit mode" Ta "q" Ta "Escape"
|
||||||
|
.It Li "Rectangle toggle" Ta "v" Ta "R"
|
||||||
.It Li "Scroll down" Ta "C-Down or C-e" Ta "C-Down"
|
.It Li "Scroll down" Ta "C-Down or C-e" Ta "C-Down"
|
||||||
.It Li "Scroll up" Ta "C-Up or C-y" Ta "C-Up"
|
.It Li "Scroll up" Ta "C-Up or C-y" Ta "C-Up"
|
||||||
.It Li "Search again" Ta "n" Ta "n"
|
.It Li "Search again" Ta "n" Ta "n"
|
||||||
|
8
tmux.h
8
tmux.h
@ -1,4 +1,4 @@
|
|||||||
/* $Id: tmux.h,v 1.541 2010-02-08 18:10:07 tcunha Exp $ */
|
/* $Id: tmux.h,v 1.542 2010-02-08 18:13:17 tcunha Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||||
@ -468,6 +468,7 @@ enum mode_key_cmd {
|
|||||||
MODEKEYCOPY_PREVIOUSPAGE,
|
MODEKEYCOPY_PREVIOUSPAGE,
|
||||||
MODEKEYCOPY_PREVIOUSSPACE,
|
MODEKEYCOPY_PREVIOUSSPACE,
|
||||||
MODEKEYCOPY_PREVIOUSWORD,
|
MODEKEYCOPY_PREVIOUSWORD,
|
||||||
|
MODEKEYCOPY_RECTANGLETOGGLE,
|
||||||
MODEKEYCOPY_RIGHT,
|
MODEKEYCOPY_RIGHT,
|
||||||
MODEKEYCOPY_SCROLLDOWN,
|
MODEKEYCOPY_SCROLLDOWN,
|
||||||
MODEKEYCOPY_SCROLLUP,
|
MODEKEYCOPY_SCROLLUP,
|
||||||
@ -673,6 +674,7 @@ SLIST_HEAD(joblist, job);
|
|||||||
/* Screen selection. */
|
/* Screen selection. */
|
||||||
struct screen_sel {
|
struct screen_sel {
|
||||||
int flag;
|
int flag;
|
||||||
|
int rectflag;
|
||||||
|
|
||||||
u_int sx;
|
u_int sx;
|
||||||
u_int sy;
|
u_int sy;
|
||||||
@ -1773,8 +1775,8 @@ void screen_free(struct screen *);
|
|||||||
void screen_reset_tabs(struct screen *);
|
void screen_reset_tabs(struct screen *);
|
||||||
void screen_set_title(struct screen *, const char *);
|
void screen_set_title(struct screen *, const char *);
|
||||||
void screen_resize(struct screen *, u_int, u_int);
|
void screen_resize(struct screen *, u_int, u_int);
|
||||||
void screen_set_selection(
|
void screen_set_selection(struct screen *,
|
||||||
struct screen *, u_int, u_int, u_int, u_int, struct grid_cell *);
|
u_int, u_int, u_int, u_int, u_int, struct grid_cell *);
|
||||||
void screen_clear_selection(struct screen *);
|
void screen_clear_selection(struct screen *);
|
||||||
int screen_check_selection(struct screen *, u_int, u_int);
|
int screen_check_selection(struct screen *, u_int, u_int);
|
||||||
|
|
||||||
|
114
window-copy.c
114
window-copy.c
@ -1,4 +1,4 @@
|
|||||||
/* $Id: window-copy.c,v 1.100 2010-02-05 01:34:08 tcunha Exp $ */
|
/* $Id: window-copy.c,v 1.101 2010-02-08 18:13:17 tcunha Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||||
@ -68,6 +68,7 @@ void window_copy_cursor_next_word_end(struct window_pane *, const char *);
|
|||||||
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,
|
||||||
@ -95,6 +96,8 @@ struct window_copy_mode_data {
|
|||||||
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;
|
||||||
|
|
||||||
@ -126,6 +129,8 @@ window_copy_init(struct window_pane *wp)
|
|||||||
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("");
|
||||||
@ -379,6 +384,9 @@ window_copy_key(struct window_pane *wp, struct client *c, int key)
|
|||||||
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;
|
||||||
}
|
}
|
||||||
@ -823,7 +831,7 @@ window_copy_update_selection(struct window_pane *wp)
|
|||||||
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);
|
||||||
@ -841,17 +849,33 @@ window_copy_update_selection(struct window_pane *wp)
|
|||||||
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -861,8 +885,9 @@ window_copy_copy_selection(struct window_pane *wp, struct client *c)
|
|||||||
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;
|
||||||
@ -893,17 +918,53 @@ window_copy_copy_selection(struct window_pane *wp, struct client *c)
|
|||||||
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. */
|
||||||
@ -1288,7 +1349,6 @@ window_copy_scroll_up(struct window_pane *wp, u_int ny)
|
|||||||
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);
|
||||||
@ -1299,9 +1359,12 @@ window_copy_scroll_up(struct window_pane *wp, u_int ny)
|
|||||||
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1320,16 +1383,29 @@ window_copy_scroll_down(struct window_pane *wp, u_int ny)
|
|||||||
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user