diff options
author | Nicholas Marriott <nicm@openbsd.org> | 2010-02-06 17:35:01 +0000 |
---|---|---|
committer | Nicholas Marriott <nicm@openbsd.org> | 2010-02-06 17:35:01 +0000 |
commit | 3ef3802629ffea0bad310e662e52db46763dd582 (patch) | |
tree | 93fced61f4d9eab6ead49bf3c4cd9023a6ee3942 /screen.c | |
parent | 8aba77b7be489a93dc843d7ef4378bd73b5385b1 (diff) |
Rectangle copy support, from Robin Lee Powell.
Diffstat (limited to 'screen.c')
-rw-r--r-- | screen.c | 113 |
1 files changed, 77 insertions, 36 deletions
@@ -228,41 +228,17 @@ screen_resize_y(struct screen *s, u_int sy) /* Set selection. */ void -screen_set_selection(struct screen *s, - u_int sx, u_int sy, u_int ex, u_int ey, struct grid_cell *gc) +screen_set_selection(struct screen *s, u_int sx, u_int sy, + u_int ex, u_int ey, u_int rectflag, struct grid_cell *gc) { struct screen_sel *sel = &s->sel; memcpy(&sel->cell, gc, sizeof sel->cell); sel->flag = 1; + sel->rectflag = rectflag; - /* starting line < ending line -- downward selection. */ - if (sy < 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; - } + sel->sx = sx; sel->sy = sy; + sel->ex = ex; sel->ey = ey; } /* Clear selection. */ @@ -280,16 +256,81 @@ screen_check_selection(struct screen *s, u_int px, u_int py) { struct screen_sel *sel = &s->sel; - if (!sel->flag || py < sel->sy || py > sel->ey) + if (!sel->flag) return (0); - if (py == sel->sy && py == sel->ey) { - if (px < sel->sx || px > sel->ex) - return (0); - return (1); + if (sel->rectflag) { + if (sel->sy < sel->ey) { + /* start line < end line -- downward selection. */ + 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); } |