Merge branch 'obsd-master'

pull/1/head
Thomas Adam 2014-11-09 00:15:51 +00:00
commit fc05bf255a
13 changed files with 120 additions and 94 deletions

View File

@ -48,7 +48,6 @@ cmd_paste_buffer_exec(struct cmd *self, struct cmd_q *cmdq)
struct session *s; struct session *s;
struct paste_buffer *pb; struct paste_buffer *pb;
const char *sepstr, *bufname; const char *sepstr, *bufname;
int pflag;
if (cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp) == NULL) if (cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp) == NULL)
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
@ -75,8 +74,7 @@ cmd_paste_buffer_exec(struct cmd *self, struct cmd_q *cmdq)
else else
sepstr = "\r"; sepstr = "\r";
} }
pflag = (wp->screen->mode & MODE_BRACKETPASTE); paste_send_pane(pb, wp, sepstr, args_has(args, 'p'));
paste_send_pane(pb, wp, sepstr, args_has(args, 'p') && pflag);
} }
/* Delete the buffer if -d. */ /* Delete the buffer if -d. */

View File

@ -237,7 +237,8 @@ format_replace(struct format_tree *ft, const char *key, size_t keylen,
*ptr = '\0'; *ptr = '\0';
value = format_find(ft, copy + 1); value = format_find(ft, copy + 1);
if (value != NULL && (value[0] != '0' || value[1] != '\0')) { if (value != NULL && *value != '\0' &&
(value[0] != '0' || value[1] != '\0')) {
value = ptr + 1; value = ptr + 1;
ptr = strchr(value, ','); ptr = strchr(value, ',');
if (ptr == NULL) if (ptr == NULL)

View File

@ -184,7 +184,7 @@ grid_view_insert_cells(struct grid *gd, u_int px, u_int py, u_int nx)
px = grid_view_x(gd, px); px = grid_view_x(gd, px);
py = grid_view_y(gd, py); py = grid_view_y(gd, py);
sx = grid_view_x(gd, gd->sx); sx = grid_view_x(gd, gd->linedata[py].cellsize);
if (px == sx - 1) if (px == sx - 1)
grid_clear(gd, px, py, 1, 1); grid_clear(gd, px, py, 1, 1);
@ -201,7 +201,7 @@ grid_view_delete_cells(struct grid *gd, u_int px, u_int py, u_int nx)
px = grid_view_x(gd, px); px = grid_view_x(gd, px);
py = grid_view_y(gd, py); py = grid_view_y(gd, py);
sx = grid_view_x(gd, gd->sx); sx = grid_view_x(gd, gd->linedata[py].cellsize);
grid_move_cells(gd, px, px + nx, py, sx - px - nx); grid_move_cells(gd, px, px + nx, py, sx - px - nx);
grid_clear(gd, sx - nx, py, px + nx - (sx - nx), 1); grid_clear(gd, sx - nx, py, px + nx - (sx - nx), 1);

View File

@ -204,6 +204,7 @@ input_mouse(struct window_pane *wp, struct session *s, struct mouse_event *m)
char buf[40]; char buf[40];
size_t len; size_t len;
struct paste_buffer *pb; struct paste_buffer *pb;
int event;
if (wp->screen->mode & ALL_MOUSE_MODES) { if (wp->screen->mode & ALL_MOUSE_MODES) {
/* /*
@ -237,19 +238,16 @@ input_mouse(struct window_pane *wp, struct session *s, struct mouse_event *m)
return; return;
} }
if (m->button == 1 && (m->event & MOUSE_EVENT_CLICK) && if (options_get_number(&wp->window->options, "mode-mouse") != 1)
options_get_number(&wp->window->options, "mode-mouse") == 1) { return;
event = m->event & (MOUSE_EVENT_CLICK|MOUSE_EVENT_WHEEL);
if (wp->mode == NULL && m->button == 1 && event == MOUSE_EVENT_CLICK) {
pb = paste_get_top(); pb = paste_get_top();
if (pb != NULL) { if (pb != NULL)
paste_send_pane(pb, wp, "\r", paste_send_pane(pb, wp, "\r", 1);
wp->screen->mode & MODE_BRACKETPASTE); } else if (window_pane_set_mode(wp, &window_copy_mode) == 0) {
}
} else if (m->button != 1 &&
options_get_number(&wp->window->options, "mode-mouse") == 1) {
if (window_pane_set_mode(wp, &window_copy_mode) == 0) {
window_copy_init_from_pane(wp); window_copy_init_from_pane(wp);
if (wp->mode->mouse != NULL) if (wp->mode->mouse != NULL)
wp->mode->mouse(wp, s, m); wp->mode->mouse(wp, s, m);
} }
} }
}

View File

@ -289,6 +289,7 @@ const struct mode_key_entry mode_key_vi_copy[] = {
{ 'M', 0, MODEKEYCOPY_MIDDLELINE }, { 'M', 0, MODEKEYCOPY_MIDDLELINE },
{ 'N', 0, MODEKEYCOPY_SEARCHREVERSE }, { 'N', 0, MODEKEYCOPY_SEARCHREVERSE },
{ 'T', 0, MODEKEYCOPY_JUMPTOBACK }, { 'T', 0, MODEKEYCOPY_JUMPTOBACK },
{ 'V', 0, MODEKEYCOPY_SELECTLINE },
{ 'W', 0, MODEKEYCOPY_NEXTSPACE }, { 'W', 0, MODEKEYCOPY_NEXTSPACE },
{ '\002' /* C-b */, 0, MODEKEYCOPY_PREVIOUSPAGE }, { '\002' /* C-b */, 0, MODEKEYCOPY_PREVIOUSPAGE },
{ '\003' /* C-c */, 0, MODEKEYCOPY_CANCEL }, { '\003' /* C-c */, 0, MODEKEYCOPY_CANCEL },

View File

@ -300,7 +300,7 @@ paste_send_pane(struct paste_buffer *pb, struct window_pane *wp,
if (wp->flags & PANE_INPUTOFF) if (wp->flags & PANE_INPUTOFF)
return; return;
if (bracket) if (bracket && (wp->screen->mode & MODE_BRACKETPASTE))
bufferevent_write(wp->event, "\033[200~", 6); bufferevent_write(wp->event, "\033[200~", 6);
seplen = strlen(sep); seplen = strlen(sep);
@ -314,6 +314,6 @@ paste_send_pane(struct paste_buffer *pb, struct window_pane *wp,
if (end != data) if (end != data)
bufferevent_write(wp->event, data, end - data); bufferevent_write(wp->event, data, end - data);
if (bracket) if (bracket && (wp->screen->mode & MODE_BRACKETPASTE))
bufferevent_write(wp->event, "\033[201~", 6); bufferevent_write(wp->event, "\033[201~", 6);
} }

View File

@ -795,8 +795,6 @@ screen_write_linefeed(struct screen_write_ctx *ctx, int wrapped)
gl = &s->grid->linedata[s->grid->hsize + s->cy]; gl = &s->grid->linedata[s->grid->hsize + s->cy];
if (wrapped) if (wrapped)
gl->flags |= GRID_LINE_WRAPPED; gl->flags |= GRID_LINE_WRAPPED;
else
gl->flags &= ~GRID_LINE_WRAPPED;
if (s->cy == s->rlower) if (s->cy == s->rlower)
grid_view_scroll_region_up(s->grid, s->rupper, s->rlower); grid_view_scroll_region_up(s->grid, s->rupper, s->rlower);

View File

@ -270,6 +270,7 @@ screen_clear_selection(struct screen *s)
struct screen_sel *sel = &s->sel; struct screen_sel *sel = &s->sel;
sel->flag = 0; sel->flag = 0;
sel->lineflag = LINE_SEL_NONE;
} }
/* Check if cell in selection. */ /* Check if cell in selection. */

View File

@ -193,9 +193,9 @@ status_redraw(struct client *c)
*/ */
needed = 0; needed = 0;
if (llen != 0) if (llen != 0)
needed += llen + 1; needed += llen;
if (rlen != 0) if (rlen != 0)
needed += rlen + 1; needed += rlen;
if (c->tty.sx == 0 || c->tty.sx <= needed) if (c->tty.sx == 0 || c->tty.sx <= needed)
goto out; goto out;
wlavailable = c->tty.sx - needed; wlavailable = c->tty.sx - needed;
@ -300,10 +300,8 @@ draw:
/* Draw the left string and arrow. */ /* Draw the left string and arrow. */
screen_write_cursormove(&ctx, 0, 0); screen_write_cursormove(&ctx, 0, 0);
if (llen != 0) { if (llen != 0)
screen_write_cnputs(&ctx, llen, &lgc, utf8flag, "%s", left); screen_write_cnputs(&ctx, llen, &lgc, utf8flag, "%s", left);
screen_write_putc(&ctx, &stdgc, ' ');
}
if (larrow != 0) { if (larrow != 0) {
memcpy(&gc, &stdgc, sizeof gc); memcpy(&gc, &stdgc, sizeof gc);
if (larrow == -1) if (larrow == -1)
@ -313,21 +311,19 @@ draw:
/* Draw the right string and arrow. */ /* Draw the right string and arrow. */
if (rarrow != 0) { if (rarrow != 0) {
screen_write_cursormove(&ctx, c->tty.sx - rlen - 2, 0); screen_write_cursormove(&ctx, c->tty.sx - rlen - 1, 0);
memcpy(&gc, &stdgc, sizeof gc); memcpy(&gc, &stdgc, sizeof gc);
if (rarrow == -1) if (rarrow == -1)
gc.attr ^= GRID_ATTR_REVERSE; gc.attr ^= GRID_ATTR_REVERSE;
screen_write_putc(&ctx, &gc, '>'); screen_write_putc(&ctx, &gc, '>');
} else } else
screen_write_cursormove(&ctx, c->tty.sx - rlen - 1, 0); screen_write_cursormove(&ctx, c->tty.sx - rlen, 0);
if (rlen != 0) { if (rlen != 0)
screen_write_putc(&ctx, &stdgc, ' ');
screen_write_cnputs(&ctx, rlen, &rgc, utf8flag, "%s", right); screen_write_cnputs(&ctx, rlen, &rgc, utf8flag, "%s", right);
}
/* Figure out the offset for the window list. */ /* Figure out the offset for the window list. */
if (llen != 0) if (llen != 0)
wloffset = llen + 1; wloffset = llen;
else else
wloffset = 0; wloffset = 0;
if (wlwidth < wlavailable) { if (wlwidth < wlavailable) {

16
tmux.1
View File

@ -879,10 +879,10 @@ The following keys are supported as appropriate for the mode:
.It Sy "Function" Ta Sy "vi" Ta Sy "emacs" .It Sy "Function" Ta Sy "vi" Ta Sy "emacs"
.It Li "Append selection" Ta "A" Ta "" .It Li "Append selection" Ta "A" Ta ""
.It Li "Back to indentation" Ta "^" Ta "M-m" .It Li "Back to indentation" Ta "^" Ta "M-m"
.It Li "Copy to named buffer" Ta \&" Ta ""
.It Li "Bottom of history" Ta "G" Ta "M-<" .It Li "Bottom of history" Ta "G" Ta "M-<"
.It Li "Clear selection" Ta "Escape" Ta "C-g" .It Li "Clear selection" Ta "Escape" Ta "C-g"
.It Li "Copy selection" Ta "Enter" Ta "M-w" .It Li "Copy selection" Ta "Enter" Ta "M-w"
.It Li "Copy to named buffer" Ta \&" Ta ""
.It Li "Cursor down" Ta "j" Ta "Down" .It Li "Cursor down" Ta "j" Ta "Down"
.It Li "Cursor left" Ta "h" Ta "Left" .It Li "Cursor left" Ta "h" Ta "Left"
.It Li "Cursor right" Ta "l" Ta "Right" .It Li "Cursor right" Ta "l" Ta "Right"
@ -896,12 +896,12 @@ The following keys are supported as appropriate for the mode:
.It Li "Go to line" Ta ":" Ta "g" .It Li "Go to line" Ta ":" Ta "g"
.It Li "Half page down" Ta "C-d" Ta "M-Down" .It Li "Half page down" Ta "C-d" Ta "M-Down"
.It Li "Half page up" Ta "C-u" Ta "M-Up" .It Li "Half page up" Ta "C-u" Ta "M-Up"
.It Li "Jump forward" Ta "f" Ta "f"
.It Li "Jump to forward" Ta "t" Ta ""
.It Li "Jump backward" Ta "F" Ta "F"
.It Li "Jump to backward" Ta "T" Ta ""
.It Li "Jump again" Ta ";" Ta ";" .It Li "Jump again" Ta ";" Ta ";"
.It Li "Jump again in reverse" Ta "," Ta "," .It Li "Jump again in reverse" Ta "," Ta ","
.It Li "Jump backward" Ta "F" Ta "F"
.It Li "Jump forward" Ta "f" Ta "f"
.It Li "Jump to backward" Ta "T" Ta ""
.It Li "Jump to forward" Ta "t" Ta ""
.It Li "Next page" Ta "C-f" Ta "Page down" .It Li "Next page" Ta "C-f" Ta "Page down"
.It Li "Next space" Ta "W" Ta "" .It Li "Next space" Ta "W" Ta ""
.It Li "Next space, end of word" Ta "E" Ta "" .It Li "Next space, end of word" Ta "E" Ta ""
@ -910,8 +910,8 @@ The following keys are supported as appropriate for the mode:
.It Li "Other end of selection" Ta "o" Ta "" .It Li "Other end of selection" Ta "o" Ta ""
.It Li "Paste buffer" Ta "p" Ta "C-y" .It Li "Paste buffer" Ta "p" Ta "C-y"
.It Li "Previous page" Ta "C-b" Ta "Page up" .It Li "Previous page" Ta "C-b" Ta "Page up"
.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 "Previous word" Ta "b" Ta "M-b"
.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 "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"
@ -920,6 +920,7 @@ The following keys are supported as appropriate for the mode:
.It Li "Search again in reverse" Ta "N" Ta "N" .It Li "Search again in reverse" Ta "N" Ta "N"
.It Li "Search backward" Ta "?" Ta "C-r" .It Li "Search backward" Ta "?" Ta "C-r"
.It Li "Search forward" Ta "/" Ta "C-s" .It Li "Search forward" Ta "/" Ta "C-s"
.It Li "Select line" Ta "V" Ta ""
.It Li "Start of line" Ta "0" Ta "C-a" .It Li "Start of line" Ta "0" Ta "C-a"
.It Li "Start selection" Ta "Space" Ta "C-Space" .It Li "Start selection" Ta "Space" Ta "C-Space"
.It Li "Top of history" Ta "g" Ta "M->" .It Li "Top of history" Ta "g" Ta "M->"
@ -2585,6 +2586,9 @@ By default, UTF-8 in
is not interpreted, to enable UTF-8, use the is not interpreted, to enable UTF-8, use the
.Ic status-utf8 .Ic status-utf8
option. option.
.Pp
The default is
.Ql "[#S] " .
.It Ic status-left-length Ar length .It Ic status-left-length Ar length
Set the maximum Set the maximum
.Ar length .Ar length

6
tmux.h
View File

@ -710,6 +710,12 @@ LIST_HEAD(joblist, job);
struct screen_sel { struct screen_sel {
int flag; int flag;
int rectflag; int rectflag;
enum {
LINE_SEL_NONE,
LINE_SEL_LEFT_RIGHT,
LINE_SEL_RIGHT_LEFT,
} lineflag;
int modekeys; int modekeys;
u_int sx; u_int sx;

View File

@ -30,23 +30,23 @@ void window_copy_resize(struct window_pane *, u_int, u_int);
void window_copy_key(struct window_pane *, struct session *, int); void window_copy_key(struct window_pane *, struct session *, int);
int window_copy_key_input(struct window_pane *, int); int window_copy_key_input(struct window_pane *, int);
int window_copy_key_numeric_prefix(struct window_pane *, int); int window_copy_key_numeric_prefix(struct window_pane *, int);
void window_copy_mouse( void window_copy_mouse(struct window_pane *, struct session *,
struct window_pane *, struct session *, struct mouse_event *); struct mouse_event *);
void window_copy_redraw_lines(struct window_pane *, u_int, u_int); void window_copy_redraw_lines(struct window_pane *, u_int, u_int);
void window_copy_redraw_screen(struct window_pane *); void window_copy_redraw_screen(struct window_pane *);
void window_copy_write_line( void window_copy_write_line(struct window_pane *, struct screen_write_ctx *,
struct window_pane *, struct screen_write_ctx *, u_int); u_int);
void window_copy_write_lines( void window_copy_write_lines(struct window_pane *,
struct window_pane *, struct screen_write_ctx *, u_int, u_int); struct screen_write_ctx *, u_int, u_int);
void window_copy_scroll_to(struct window_pane *, u_int, u_int); void window_copy_scroll_to(struct window_pane *, u_int, u_int);
int window_copy_search_compare( int window_copy_search_compare(struct grid *, u_int, u_int, struct grid *,
struct grid *, u_int, u_int, struct grid *, u_int, int); u_int, int);
int window_copy_search_lr( int window_copy_search_lr(struct grid *, struct grid *, u_int *, u_int,
struct grid *, struct grid *, u_int *, u_int, u_int, u_int, int); u_int, u_int, int);
int window_copy_search_rl( int window_copy_search_rl(struct grid *, struct grid *, u_int *, u_int,
struct grid *, struct grid *, u_int *, u_int, u_int, u_int, int); u_int, u_int, int);
void window_copy_search_up(struct window_pane *, const char *); void window_copy_search_up(struct window_pane *, const char *);
void window_copy_search_down(struct window_pane *, const char *); void window_copy_search_down(struct window_pane *, const char *);
void window_copy_goto_line(struct window_pane *, const char *); void window_copy_goto_line(struct window_pane *, const char *);
@ -239,7 +239,6 @@ window_copy_init_for_output(struct window_pane *wp)
data->backing = xmalloc(sizeof *data->backing); data->backing = xmalloc(sizeof *data->backing);
screen_init(data->backing, screen_size_x(&wp->base), screen_init(data->backing, screen_size_x(&wp->base),
screen_size_y(&wp->base), UINT_MAX); screen_size_y(&wp->base), UINT_MAX);
data->backing->mode &= ~MODE_WRAP;
} }
void void
@ -280,7 +279,7 @@ window_copy_vadd(struct window_pane *wp, const char *fmt, va_list ap)
struct screen_write_ctx back_ctx, ctx; struct screen_write_ctx back_ctx, ctx;
struct grid_cell gc; struct grid_cell gc;
int utf8flag; int utf8flag;
u_int old_hsize; u_int old_hsize, old_cy;
if (backing == &wp->base) if (backing == &wp->base)
return; return;
@ -299,6 +298,7 @@ window_copy_vadd(struct window_pane *wp, const char *fmt, va_list ap)
screen_write_linefeed(&back_ctx, 0); screen_write_linefeed(&back_ctx, 0);
} else } else
data->backing_written = 1; data->backing_written = 1;
old_cy = backing->cy;
screen_write_vnputs(&back_ctx, 0, &gc, utf8flag, fmt, ap); screen_write_vnputs(&back_ctx, 0, &gc, utf8flag, fmt, ap);
screen_write_stop(&back_ctx); screen_write_stop(&back_ctx);
@ -313,9 +313,8 @@ window_copy_vadd(struct window_pane *wp, const char *fmt, va_list ap)
if (screen_hsize(data->backing)) if (screen_hsize(data->backing))
window_copy_redraw_lines(wp, 0, 1); window_copy_redraw_lines(wp, 0, 1);
/* Write the line, if it's visible. */ /* Write the new lines. */
if (backing->cy + data->oy < screen_size_y(backing)) window_copy_redraw_lines(wp, old_cy, backing->cy - old_cy + 1);
window_copy_redraw_lines(wp, backing->cy, 1);
screen_write_stop(&ctx); screen_write_stop(&ctx);
} }
@ -345,9 +344,9 @@ window_copy_resize(struct window_pane *wp, u_int sx, u_int sy)
struct screen *s = &data->screen; struct screen *s = &data->screen;
struct screen_write_ctx ctx; struct screen_write_ctx ctx;
screen_resize(s, sx, sy, 0); screen_resize(s, sx, sy, 1);
if (data->backing != &wp->base) if (data->backing != &wp->base)
screen_resize(data->backing, sx, sy, 0); screen_resize(data->backing, sx, sy, 1);
if (data->cy > sy - 1) if (data->cy > sy - 1)
data->cy = sy - 1; data->cy = sy - 1;
@ -374,7 +373,7 @@ window_copy_key(struct window_pane *wp, struct session *sess, int key)
u_int n; u_int n;
int np, keys; int np, keys;
enum mode_key_cmd cmd; enum mode_key_cmd cmd;
const char *arg; const char *arg, *ss;
np = data->numprefix; np = data->numprefix;
if (np <= 0) if (np <= 0)
@ -528,11 +527,15 @@ window_copy_key(struct window_pane *wp, struct session *sess, int key)
window_copy_redraw_screen(wp); window_copy_redraw_screen(wp);
break; break;
case MODEKEYCOPY_STARTSELECTION: case MODEKEYCOPY_STARTSELECTION:
s->sel.lineflag = LINE_SEL_NONE;
window_copy_start_selection(wp); window_copy_start_selection(wp);
window_copy_redraw_screen(wp); window_copy_redraw_screen(wp);
break; break;
case MODEKEYCOPY_COPYLINE:
case MODEKEYCOPY_SELECTLINE: case MODEKEYCOPY_SELECTLINE:
s->sel.lineflag = LINE_SEL_LEFT_RIGHT;
data->rectflag = 0;
/* FALLTHROUGH */
case MODEKEYCOPY_COPYLINE:
window_copy_cursor_start_of_line(wp); window_copy_cursor_start_of_line(wp);
/* FALLTHROUGH */ /* FALLTHROUGH */
case MODEKEYCOPY_COPYENDOFLINE: case MODEKEYCOPY_COPYENDOFLINE:
@ -683,29 +686,23 @@ window_copy_key(struct window_pane *wp, struct session *sess, int key)
case WINDOW_COPY_NUMERICPREFIX: case WINDOW_COPY_NUMERICPREFIX:
break; break;
case WINDOW_COPY_SEARCHUP: case WINDOW_COPY_SEARCHUP:
ss = data->searchstr;
if (cmd == MODEKEYCOPY_SEARCHAGAIN) { if (cmd == MODEKEYCOPY_SEARCHAGAIN) {
for (; np != 0; np--) { for (; np != 0; np--)
window_copy_search_up( window_copy_search_up(wp, ss);
wp, data->searchstr);
}
} else { } else {
for (; np != 0; np--) { for (; np != 0; np--)
window_copy_search_down( window_copy_search_down(wp, ss);
wp, data->searchstr);
}
} }
break; break;
case WINDOW_COPY_SEARCHDOWN: case WINDOW_COPY_SEARCHDOWN:
ss = data->searchstr;
if (cmd == MODEKEYCOPY_SEARCHAGAIN) { if (cmd == MODEKEYCOPY_SEARCHAGAIN) {
for (; np != 0; np--) { for (; np != 0; np--)
window_copy_search_down( window_copy_search_down(wp, ss);
wp, data->searchstr);
}
} else { } else {
for (; np != 0; np--) { for (; np != 0; np--)
window_copy_search_up( window_copy_search_up(wp, ss);
wp, data->searchstr);
}
} }
break; break;
} }
@ -730,6 +727,7 @@ window_copy_key(struct window_pane *wp, struct session *sess, int key)
} }
break; break;
case MODEKEYCOPY_RECTANGLETOGGLE: case MODEKEYCOPY_RECTANGLETOGGLE:
s->sel.lineflag = LINE_SEL_NONE;
window_copy_rectangle_toggle(wp); window_copy_rectangle_toggle(wp);
break; break;
default: default:
@ -871,8 +869,8 @@ window_copy_key_numeric_prefix(struct window_pane *wp, int key)
} }
void void
window_copy_mouse( window_copy_mouse(struct window_pane *wp, struct session *sess,
struct window_pane *wp, struct session *sess, struct mouse_event *m) struct mouse_event *m)
{ {
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;
@ -895,7 +893,8 @@ window_copy_mouse(
* We reached the bottom, leave copy mode, but * We reached the bottom, leave copy mode, but
* only if no selection is in progress. * only if no selection is in progress.
*/ */
if (data->oy == 0 && !s->sel.flag) if (data->oy == 0 && !s->sel.flag &&
s->sel.lineflag == LINE_SEL_NONE)
goto reset_mode; goto reset_mode;
} }
} }
@ -964,8 +963,8 @@ window_copy_scroll_to(struct window_pane *wp, u_int px, u_int py)
} }
int int
window_copy_search_compare( window_copy_search_compare(struct grid *gd, u_int px, u_int py,
struct grid *gd, u_int px, u_int py, struct grid *sgd, u_int spx, int cis) struct grid *sgd, u_int spx, int cis)
{ {
const struct grid_cell *gc, *sgc; const struct grid_cell *gc, *sgc;
struct utf8_data ud, sud; struct utf8_data ud, sud;
@ -1186,8 +1185,8 @@ window_copy_goto_line(struct window_pane *wp, const char *linestr)
} }
void void
window_copy_write_line( window_copy_write_line(struct window_pane *wp, struct screen_write_ctx *ctx,
struct window_pane *wp, struct screen_write_ctx *ctx, u_int py) u_int py)
{ {
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;
@ -1237,8 +1236,8 @@ window_copy_write_line(
} }
void void
window_copy_write_lines( window_copy_write_lines(struct window_pane *wp, struct screen_write_ctx *ctx,
struct window_pane *wp, struct screen_write_ctx *ctx, u_int py, u_int ny) u_int py, u_int ny)
{ {
u_int yy; u_int yy;
@ -1311,7 +1310,7 @@ window_copy_update_selection(struct window_pane *wp, int may_redraw)
struct grid_cell gc; struct grid_cell gc;
u_int sx, sy, ty, cy; u_int sx, sy, ty, cy;
if (!s->sel.flag) if (!s->sel.flag && s->sel.lineflag == LINE_SEL_NONE)
return (0); return (0);
/* Set colours. */ /* Set colours. */
@ -1365,7 +1364,7 @@ window_copy_get_selection(struct window_pane *wp, size_t *len)
u_int firstsx, lastex, restex, restsx; u_int firstsx, lastex, restex, restsx;
int keys; int keys;
if (!s->sel.flag) if (!s->sel.flag && s->sel.lineflag == LINE_SEL_NONE)
return (NULL); return (NULL);
buf = xmalloc(1); buf = xmalloc(1);
@ -1665,12 +1664,14 @@ window_copy_cursor_start_of_line(struct window_pane *wp)
{ {
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) { if (data->cx == 0 && s->sel.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 && gd->linedata[py-1].flags & GRID_LINE_WRAPPED) { while (py > 0 &&
gd->linedata[py-1].flags & GRID_LINE_WRAPPED) {
window_copy_cursor_up(wp, 0); window_copy_cursor_up(wp, 0);
py = screen_hsize(back_s) + data->cy - data->oy; py = screen_hsize(back_s) + data->cy - data->oy;
} }
@ -1710,13 +1711,14 @@ window_copy_cursor_end_of_line(struct window_pane *wp)
{ {
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 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) { if (data->cx == px && s->sel.lineflag == LINE_SEL_NONE) {
if (data->screen.sel.flag && data->rectflag) if (data->screen.sel.flag && data->rectflag)
px = screen_size_x(back_s); px = screen_size_x(back_s);
if (gd->linedata[py].flags & GRID_LINE_WRAPPED) { if (gd->linedata[py].flags & GRID_LINE_WRAPPED) {
@ -1742,9 +1744,14 @@ window_copy_other_end(struct window_pane *wp)
struct screen *s = &data->screen; struct screen *s = &data->screen;
u_int selx, sely, cx, cy, yy; u_int selx, sely, cx, cy, yy;
if (!s->sel.flag) if (!s->sel.flag && s->sel.lineflag == LINE_SEL_NONE)
return; return;
if (s->sel.lineflag == LINE_SEL_LEFT_RIGHT)
s->sel.lineflag = LINE_SEL_RIGHT_LEFT;
else if (s->sel.lineflag == LINE_SEL_RIGHT_LEFT)
s->sel.lineflag = LINE_SEL_LEFT_RIGHT;
selx = data->selx; selx = data->selx;
sely = data->sely; sely = data->sely;
cx = data->cx; cx = data->cx;
@ -1820,6 +1827,9 @@ window_copy_cursor_up(struct window_pane *wp, int scroll_only)
data->lastsx = ox; data->lastsx = ox;
} }
if (s->sel.lineflag == LINE_SEL_LEFT_RIGHT && oy == data->sely)
window_copy_other_end(wp);
data->cx = data->lastcx; data->cx = data->lastcx;
if (scroll_only || data->cy == 0) { if (scroll_only || data->cy == 0) {
window_copy_scroll_down(wp, 1); window_copy_scroll_down(wp, 1);
@ -1846,6 +1856,11 @@ window_copy_cursor_up(struct window_pane *wp, int scroll_only)
data->cx > px) 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)
window_copy_cursor_end_of_line(wp);
else if (s->sel.lineflag == LINE_SEL_RIGHT_LEFT)
window_copy_cursor_start_of_line(wp);
} }
void void
@ -1862,6 +1877,9 @@ window_copy_cursor_down(struct window_pane *wp, int scroll_only)
data->lastsx = ox; data->lastsx = ox;
} }
if (s->sel.lineflag == LINE_SEL_RIGHT_LEFT && oy == data->sely)
window_copy_other_end(wp);
data->cx = data->lastcx; data->cx = data->lastcx;
if (scroll_only || data->cy == screen_size_y(s) - 1) { if (scroll_only || data->cy == screen_size_y(s) - 1) {
window_copy_scroll_up(wp, 1); window_copy_scroll_up(wp, 1);
@ -1880,6 +1898,11 @@ window_copy_cursor_down(struct window_pane *wp, int scroll_only)
data->cx > px) 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)
window_copy_cursor_end_of_line(wp);
else if (s->sel.lineflag == LINE_SEL_RIGHT_LEFT)
window_copy_cursor_start_of_line(wp);
} }
void void