diff options
Diffstat (limited to 'window-copy.c')
-rw-r--r-- | window-copy.c | 376 |
1 files changed, 245 insertions, 131 deletions
diff --git a/window-copy.c b/window-copy.c index 527c95c2..223df88a 100644 --- a/window-copy.c +++ b/window-copy.c @@ -1,4 +1,4 @@ -/* $Id$ */ +/* $OpenBSD$ */ /* * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> @@ -30,23 +30,24 @@ void window_copy_resize(struct window_pane *, u_int, u_int); void window_copy_key(struct window_pane *, struct session *, int); int window_copy_key_input(struct window_pane *, int); int window_copy_key_numeric_prefix(struct window_pane *, int); -void window_copy_mouse( - struct window_pane *, struct session *, struct mouse_event *); +void window_copy_mouse(struct window_pane *, struct session *, + struct mouse_event *); +void window_copy_redraw_selection(struct window_pane *, 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_write_line( - struct window_pane *, struct screen_write_ctx *, u_int); -void window_copy_write_lines( - struct window_pane *, struct screen_write_ctx *, u_int, u_int); +void window_copy_write_line(struct window_pane *, struct screen_write_ctx *, + u_int); +void window_copy_write_lines(struct window_pane *, + struct screen_write_ctx *, u_int, u_int); void window_copy_scroll_to(struct window_pane *, u_int, u_int); -int window_copy_search_compare( - struct grid *, u_int, u_int, struct grid *, u_int, int); -int window_copy_search_lr( - struct grid *, struct grid *, u_int *, u_int, u_int, u_int, int); -int window_copy_search_rl( - struct grid *, struct grid *, u_int *, u_int, u_int, u_int, int); +int window_copy_search_compare(struct grid *, u_int, u_int, struct grid *, + u_int, int); +int window_copy_search_lr(struct grid *, struct grid *, u_int *, u_int, + u_int, u_int, int); +int window_copy_search_rl(struct grid *, struct grid *, u_int *, u_int, + u_int, u_int, int); void window_copy_search_up(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 *); @@ -54,13 +55,15 @@ void window_copy_update_cursor(struct window_pane *, u_int, u_int); void window_copy_start_selection(struct window_pane *); int window_copy_update_selection(struct window_pane *, int); void *window_copy_get_selection(struct window_pane *, size_t *); -void window_copy_copy_buffer(struct window_pane *, int, void *, size_t); -void window_copy_copy_pipe( - struct window_pane *, struct session *, int, const char *); -void window_copy_copy_selection(struct window_pane *, int); +void window_copy_copy_buffer(struct window_pane *, const char *, void *, + size_t); +void window_copy_copy_pipe(struct window_pane *, struct session *, + const char *, const char *); +void window_copy_copy_selection(struct window_pane *, const char *); +void window_copy_append_selection(struct window_pane *, const char *); void window_copy_clear_selection(struct window_pane *); -void window_copy_copy_line( - struct window_pane *, char **, size_t *, u_int, u_int, u_int); +void window_copy_copy_line(struct window_pane *, char **, size_t *, u_int, + u_int, u_int); int window_copy_in_set(struct window_pane *, u_int, u_int, const char *); u_int window_copy_find_length(struct window_pane *, u_int); void window_copy_cursor_start_of_line(struct window_pane *); @@ -93,6 +96,7 @@ const struct window_mode window_copy_mode = { enum window_copy_input_type { WINDOW_COPY_OFF, + WINDOW_COPY_NAMEDBUFFER, WINDOW_COPY_NUMERICPREFIX, WINDOW_COPY_SEARCHUP, WINDOW_COPY_SEARCHDOWN, @@ -196,6 +200,7 @@ window_copy_init(struct window_pane *wp) mode_key_init(&data->mdata, &mode_key_tree_emacs_copy); else mode_key_init(&data->mdata, &mode_key_tree_vi_copy); + s->sel.modekeys = keys; data->backing = NULL; @@ -235,7 +240,6 @@ window_copy_init_for_output(struct window_pane *wp) data->backing = xmalloc(sizeof *data->backing); screen_init(data->backing, screen_size_x(&wp->base), screen_size_y(&wp->base), UINT_MAX); - data->backing->mode &= ~MODE_WRAP; } void @@ -276,7 +280,7 @@ window_copy_vadd(struct window_pane *wp, const char *fmt, va_list ap) struct screen_write_ctx back_ctx, ctx; struct grid_cell gc; int utf8flag; - u_int old_hsize; + u_int old_hsize, old_cy; if (backing == &wp->base) return; @@ -295,6 +299,7 @@ window_copy_vadd(struct window_pane *wp, const char *fmt, va_list ap) screen_write_linefeed(&back_ctx, 0); } else data->backing_written = 1; + old_cy = backing->cy; screen_write_vnputs(&back_ctx, 0, &gc, utf8flag, fmt, ap); screen_write_stop(&back_ctx); @@ -309,9 +314,8 @@ window_copy_vadd(struct window_pane *wp, const char *fmt, va_list ap) if (screen_hsize(data->backing)) window_copy_redraw_lines(wp, 0, 1); - /* Write the line, if it's visible. */ - if (backing->cy + data->oy < screen_size_y(backing)) - window_copy_redraw_lines(wp, backing->cy, 1); + /* Write the new lines. */ + window_copy_redraw_lines(wp, old_cy, backing->cy - old_cy + 1); screen_write_stop(&ctx); } @@ -341,9 +345,9 @@ window_copy_resize(struct window_pane *wp, u_int sx, u_int sy) struct screen *s = &data->screen; struct screen_write_ctx ctx; - screen_resize(s, sx, sy, 0); + screen_resize(s, sx, sy, 1); if (data->backing != &wp->base) - screen_resize(data->backing, sx, sy, 0); + screen_resize(data->backing, sx, sy, 1); if (data->cy > sy - 1) data->cy = sy - 1; @@ -370,7 +374,7 @@ window_copy_key(struct window_pane *wp, struct session *sess, int key) u_int n; int np, keys; enum mode_key_cmd cmd; - const char *arg; + const char *arg, *ss; np = data->numprefix; if (np <= 0) @@ -386,13 +390,16 @@ window_copy_key(struct window_pane *wp, struct session *sess, int key) if (data->inputtype == WINDOW_COPY_JUMPFORWARD) { for (; np != 0; np--) window_copy_cursor_jump(wp); - } else if (data->inputtype == WINDOW_COPY_JUMPBACK) { + } + if (data->inputtype == WINDOW_COPY_JUMPBACK) { for (; np != 0; np--) window_copy_cursor_jump_back(wp); - } else if (data->inputtype == WINDOW_COPY_JUMPTOFORWARD) { + } + if (data->inputtype == WINDOW_COPY_JUMPTOFORWARD) { for (; np != 0; np--) window_copy_cursor_jump_to(wp); - } else if (data->inputtype == WINDOW_COPY_JUMPTOBACK) { + } + if (data->inputtype == WINDOW_COPY_JUMPTOBACK) { for (; np != 0; np--) window_copy_cursor_jump_to_back(wp); } @@ -414,11 +421,18 @@ window_copy_key(struct window_pane *wp, struct session *sess, int key) cmd = mode_key_lookup(&data->mdata, key, &arg); switch (cmd) { + case MODEKEYCOPY_APPENDSELECTION: + if (sess != NULL) { + window_copy_append_selection(wp, NULL); + window_pane_reset_mode(wp); + return; + } + break; case MODEKEYCOPY_CANCEL: window_pane_reset_mode(wp); return; case MODEKEYCOPY_OTHEREND: - for (; np != 0; np--) + if (np % 2) window_copy_other_end(wp); break; case MODEKEYCOPY_LEFT: @@ -517,11 +531,15 @@ window_copy_key(struct window_pane *wp, struct session *sess, int key) window_copy_redraw_screen(wp); break; case MODEKEYCOPY_STARTSELECTION: + s->sel.lineflag = LINE_SEL_NONE; window_copy_start_selection(wp); window_copy_redraw_screen(wp); break; - case MODEKEYCOPY_COPYLINE: case MODEKEYCOPY_SELECTLINE: + s->sel.lineflag = LINE_SEL_LEFT_RIGHT; + data->rectflag = 0; + /* FALLTHROUGH */ + case MODEKEYCOPY_COPYLINE: window_copy_cursor_start_of_line(wp); /* FALLTHROUGH */ case MODEKEYCOPY_COPYENDOFLINE: @@ -535,7 +553,7 @@ window_copy_key(struct window_pane *wp, struct session *sess, int key) if (sess != NULL && (cmd == MODEKEYCOPY_COPYLINE || cmd == MODEKEYCOPY_COPYENDOFLINE)) { - window_copy_copy_selection(wp, -1); + window_copy_copy_selection(wp, NULL); window_pane_reset_mode(wp); return; } @@ -546,14 +564,14 @@ window_copy_key(struct window_pane *wp, struct session *sess, int key) break; case MODEKEYCOPY_COPYPIPE: if (sess != NULL) { - window_copy_copy_pipe(wp, sess, data->numprefix, arg); + window_copy_copy_pipe(wp, sess, NULL, arg); window_pane_reset_mode(wp); return; } break; case MODEKEYCOPY_COPYSELECTION: if (sess != NULL) { - window_copy_copy_selection(wp, data->numprefix); + window_copy_copy_selection(wp, NULL); window_pane_reset_mode(wp); return; } @@ -668,32 +686,27 @@ window_copy_key(struct window_pane *wp, struct session *sess, int key) case WINDOW_COPY_JUMPBACK: case WINDOW_COPY_JUMPTOFORWARD: case WINDOW_COPY_JUMPTOBACK: + case WINDOW_COPY_NAMEDBUFFER: case WINDOW_COPY_NUMERICPREFIX: break; case WINDOW_COPY_SEARCHUP: + ss = data->searchstr; if (cmd == MODEKEYCOPY_SEARCHAGAIN) { - for (; np != 0; np--) { - window_copy_search_up( - wp, data->searchstr); - } + for (; np != 0; np--) + window_copy_search_up(wp, ss); } else { - for (; np != 0; np--) { - window_copy_search_down( - wp, data->searchstr); - } + for (; np != 0; np--) + window_copy_search_down(wp, ss); } break; case WINDOW_COPY_SEARCHDOWN: + ss = data->searchstr; if (cmd == MODEKEYCOPY_SEARCHAGAIN) { - for (; np != 0; np--) { - window_copy_search_down( - wp, data->searchstr); - } + for (; np != 0; np--) + window_copy_search_down(wp, ss); } else { - for (; np != 0; np--) { - window_copy_search_up( - wp, data->searchstr); - } + for (; np != 0; np--) + window_copy_search_up(wp, ss); } break; } @@ -703,6 +716,11 @@ window_copy_key(struct window_pane *wp, struct session *sess, int key) data->inputprompt = "Goto Line"; *data->inputstr = '\0'; goto input_on; + case MODEKEYCOPY_STARTNAMEDBUFFER: + data->inputtype = WINDOW_COPY_NAMEDBUFFER; + data->inputprompt = "Buffer"; + *data->inputstr = '\0'; + goto input_on; case MODEKEYCOPY_STARTNUMBERPREFIX: key &= KEYC_MASK_KEY; if (key >= '0' && key <= '9') { @@ -713,6 +731,7 @@ window_copy_key(struct window_pane *wp, struct session *sess, int key) } break; case MODEKEYCOPY_RECTANGLETOGGLE: + s->sel.lineflag = LINE_SEL_NONE; window_copy_rectangle_toggle(wp); break; default: @@ -768,7 +787,7 @@ window_copy_key_input(struct window_pane *wp, int key) *data->inputstr = '\0'; break; case MODEKEYEDIT_PASTE: - if ((pb = paste_get_top(&global_buffers)) == NULL) + if ((pb = paste_get_top()) == NULL) break; for (n = 0; n < pb->size; n++) { ch = (u_char) pb->data[n]; @@ -777,7 +796,7 @@ window_copy_key_input(struct window_pane *wp, int key) } inputlen = strlen(data->inputstr); - data->inputstr = xrealloc(data->inputstr, 1, inputlen + n + 1); + data->inputstr = xrealloc(data->inputstr, inputlen + n + 1); memcpy(data->inputstr + inputlen, pb->data, n); data->inputstr[inputlen + n] = '\0'; break; @@ -806,6 +825,11 @@ window_copy_key_input(struct window_pane *wp, int key) data->searchtype = data->inputtype; data->searchstr = xstrdup(data->inputstr); break; + case WINDOW_COPY_NAMEDBUFFER: + window_copy_copy_selection(wp, data->inputstr); + *data->inputstr = '\0'; + window_pane_reset_mode(wp); + return (0); case WINDOW_COPY_GOTOLINE: window_copy_goto_line(wp, data->inputstr); *data->inputstr = '\0'; @@ -818,7 +842,7 @@ window_copy_key_input(struct window_pane *wp, int key) break; inputlen = strlen(data->inputstr) + 2; - data->inputstr = xrealloc(data->inputstr, 1, inputlen); + data->inputstr = xrealloc(data->inputstr, inputlen); data->inputstr[inputlen - 2] = key; data->inputstr[inputlen - 1] = '\0'; break; @@ -849,12 +873,12 @@ window_copy_key_numeric_prefix(struct window_pane *wp, int key) } void -window_copy_mouse( - struct window_pane *wp, struct session *sess, struct mouse_event *m) +window_copy_mouse(struct window_pane *wp, struct session *sess, + struct mouse_event *m) { struct window_copy_mode_data *data = wp->modedata; struct screen *s = &data->screen; - u_int i; + u_int i, old_cy; if (m->x >= screen_size_x(s)) return; @@ -863,18 +887,20 @@ window_copy_mouse( /* If mouse wheel (buttons 4 and 5), scroll. */ if (m->event == MOUSE_EVENT_WHEEL) { - if (m->wheel == MOUSE_WHEEL_UP) { - for (i = 0; i < 5; i++) + for (i = 0; i < m->scroll; i++) { + if (m->wheel == MOUSE_WHEEL_UP) window_copy_cursor_up(wp, 1); - } else if (m->wheel == MOUSE_WHEEL_DOWN) { - for (i = 0; i < 5; i++) + else { window_copy_cursor_down(wp, 1); - /* - * We reached the bottom, leave copy mode, - * but only if no selection is in progress. - */ - if (data->oy == 0 && !s->sel.flag) - goto reset_mode; + + /* + * We reached the bottom, leave copy mode, but + * only if no selection is in progress. + */ + if (data->oy == 0 && !s->sel.flag && + s->sel.lineflag == LINE_SEL_NONE) + goto reset_mode; + } } return; } @@ -885,9 +911,10 @@ window_copy_mouse( */ if (s->mode & MODE_MOUSE_BUTTON) { if (~m->event & MOUSE_EVENT_UP) { + old_cy = data->cy; window_copy_update_cursor(wp, m->x, m->y); if (window_copy_update_selection(wp, 1)) - window_copy_redraw_screen(wp); + window_copy_redraw_selection(wp, old_cy); return; } goto reset_mode; @@ -909,7 +936,7 @@ reset_mode: s->mode &= ~MODE_MOUSE_BUTTON; s->mode |= MODE_MOUSE_STANDARD; if (sess != NULL) { - window_copy_copy_selection(wp, -1); + window_copy_copy_selection(wp, NULL); window_pane_reset_mode(wp); } } @@ -941,8 +968,8 @@ window_copy_scroll_to(struct window_pane *wp, u_int px, u_int py) } int -window_copy_search_compare( - struct grid *gd, u_int px, u_int py, struct grid *sgd, u_int spx, int cis) +window_copy_search_compare(struct grid *gd, u_int px, u_int py, + struct grid *sgd, u_int spx, int cis) { const struct grid_cell *gc, *sgc; struct utf8_data ud, sud; @@ -1163,8 +1190,8 @@ window_copy_goto_line(struct window_pane *wp, const char *linestr) } void -window_copy_write_line( - struct window_pane *wp, struct screen_write_ctx *ctx, u_int py) +window_copy_write_line(struct window_pane *wp, struct screen_write_ctx *ctx, + u_int py) { struct window_copy_mode_data *data = wp->modedata; struct screen *s = &data->screen; @@ -1185,8 +1212,8 @@ window_copy_write_line( screen_write_puts(ctx, &gc, "%s", hdr); } else if (py == last && data->inputtype != WINDOW_COPY_OFF) { limit = sizeof hdr; - if (limit > screen_size_x(s)) - limit = screen_size_x(s); + if (limit > screen_size_x(s) + 1) + limit = screen_size_x(s) + 1; if (data->inputtype == WINDOW_COPY_NUMERICPREFIX) { xoff = size = xsnprintf(hdr, limit, "Repeat: %u", data->numprefix); @@ -1199,10 +1226,12 @@ window_copy_write_line( } else size = 0; - screen_write_cursormove(ctx, xoff, py); - screen_write_copy(ctx, data->backing, xoff, - (screen_hsize(data->backing) - data->oy) + py, - screen_size_x(s) - size, 1); + if (size < screen_size_x(s)) { + screen_write_cursormove(ctx, xoff, py); + screen_write_copy(ctx, data->backing, xoff, + (screen_hsize(data->backing) - data->oy) + py, + screen_size_x(s) - size, 1); + } if (py == data->cy && data->cx == screen_size_x(s)) { memcpy(&gc, &grid_default_cell, sizeof gc); @@ -1212,8 +1241,8 @@ window_copy_write_line( } void -window_copy_write_lines( - struct window_pane *wp, struct screen_write_ctx *ctx, u_int py, u_int ny) +window_copy_write_lines(struct window_pane *wp, struct screen_write_ctx *ctx, + u_int py, u_int ny) { u_int yy; @@ -1222,6 +1251,23 @@ window_copy_write_lines( } void +window_copy_redraw_selection(struct window_pane *wp, u_int old_y) +{ + struct window_copy_mode_data *data = wp->modedata; + u_int new_y, start, end; + + new_y = data->cy; + if (old_y <= new_y) { + start = old_y; + end = new_y; + } else { + start = new_y; + end = old_y; + } + window_copy_redraw_lines(wp, start, end - start + 1); +} + +void window_copy_redraw_lines(struct window_pane *wp, u_int py, u_int ny) { struct window_copy_mode_data *data = wp->modedata; @@ -1286,7 +1332,7 @@ window_copy_update_selection(struct window_pane *wp, int may_redraw) struct grid_cell gc; u_int sx, sy, ty, cy; - if (!s->sel.flag) + if (!s->sel.flag && s->sel.lineflag == LINE_SEL_NONE) return (0); /* Set colours. */ @@ -1336,11 +1382,11 @@ window_copy_get_selection(struct window_pane *wp, size_t *len) struct screen *s = &data->screen; char *buf; size_t off; - u_int i, xx, yy, sx, sy, ex, ey; + u_int i, xx, yy, sx, sy, ex, ey, ey_last; u_int firstsx, lastex, restex, restsx; int keys; - if (!s->sel.flag) + if (!s->sel.flag && s->sel.lineflag == LINE_SEL_NONE) return (NULL); buf = xmalloc(1); @@ -1365,9 +1411,9 @@ window_copy_get_selection(struct window_pane *wp, size_t *len) } /* Trim ex to end of line. */ - xx = window_copy_find_length(wp, ey); - if (ex > xx) - ex = xx; + ey_last = window_copy_find_length(wp, ey); + if (ex > ey_last) + ex = ey_last; /* * Deal with rectangle-copy if necessary; four situations: start of @@ -1418,17 +1464,10 @@ window_copy_get_selection(struct window_pane *wp, size_t *len) } /* Copy the lines. */ - if (sy == ey) - window_copy_copy_line(wp, &buf, &off, sy, firstsx, lastex); - else { - window_copy_copy_line(wp, &buf, &off, sy, firstsx, restex); - if (ey - sy > 1) { - for (i = sy + 1; i < ey; i++) { - window_copy_copy_line( - wp, &buf, &off, i, restsx, restex); - } - } - window_copy_copy_line(wp, &buf, &off, ey, restsx, lastex); + for (i = sy; i <= ey; i++) { + window_copy_copy_line(wp, &buf, &off, i, + (i == sy ? firstsx : restsx), + (i == ey ? lastex : restex)); } /* Don't bother if no data. */ @@ -1436,14 +1475,16 @@ window_copy_get_selection(struct window_pane *wp, size_t *len) free(buf); return (NULL); } - *len = off - 1; /* remove final \n */ + if (keys == MODEKEY_EMACS || lastex <= ey_last) + off -= 1; /* remove final \n (unless at end in vi mode) */ + *len = off; return (buf); } void -window_copy_copy_buffer(struct window_pane *wp, int idx, void *buf, size_t len) +window_copy_copy_buffer(struct window_pane *wp, const char *bufname, void *buf, + size_t len) { - u_int limit; struct screen_write_ctx ctx; if (options_get_number(&global_options, "set-clipboard")) { @@ -1452,43 +1493,82 @@ window_copy_copy_buffer(struct window_pane *wp, int idx, void *buf, size_t len) screen_write_stop(&ctx); } - if (idx == -1) { - limit = options_get_number(&global_options, "buffer-limit"); - paste_add(&global_buffers, buf, len, limit); - } else if (paste_replace(&global_buffers, idx, buf, len) != 0) + if (paste_set(buf, len, bufname, NULL) != 0) free(buf); } void -window_copy_copy_pipe( - struct window_pane *wp, struct session *sess, int idx, const char *arg) +window_copy_copy_pipe(struct window_pane *wp, struct session *sess, + const char *bufname, const char *arg) { - void *buf; - size_t len; - struct job *job; - + void *buf; + size_t len; + struct job *job; + struct format_tree *ft; + char *expanded; buf = window_copy_get_selection(wp, &len); if (buf == NULL) return; - job = job_run(arg, sess, NULL, NULL, NULL); + ft = format_create(); + format_defaults(ft, NULL, sess, NULL, wp); + expanded = format_expand(ft, arg); + + job = job_run(expanded, sess, NULL, NULL, NULL); bufferevent_write(job->event, buf, len); - window_copy_copy_buffer(wp, idx, buf, len); + free(expanded); + format_free(ft); + + window_copy_copy_buffer(wp, bufname, buf, len); +} + +void +window_copy_copy_selection(struct window_pane *wp, const char *bufname) +{ + void *buf; + size_t len; + + buf = window_copy_get_selection(wp, &len); + if (buf == NULL) + return; + + window_copy_copy_buffer(wp, bufname, buf, len); } void -window_copy_copy_selection(struct window_pane *wp, int idx) +window_copy_append_selection(struct window_pane *wp, const char *bufname) { - void* buf; - size_t len; + char *buf; + struct paste_buffer *pb; + size_t len; + struct screen_write_ctx ctx; buf = window_copy_get_selection(wp, &len); if (buf == NULL) return; - window_copy_copy_buffer(wp, idx, buf, len); + if (options_get_number(&global_options, "set-clipboard")) { + screen_write_start(&ctx, wp, NULL); + screen_write_setselection(&ctx, buf, len); + screen_write_stop(&ctx); + } + + if (bufname == NULL || *bufname == '\0') { + pb = paste_get_top(); + if (pb != NULL) + bufname = pb->name; + } else + pb = paste_get_name(bufname); + if (pb != NULL) { + buf = xrealloc(buf, len + pb->size); + memmove(buf + pb->size, buf, len); + memcpy(buf, pb->data, pb->size); + len += pb->size; + } + if (paste_set(buf, len, bufname, NULL) != 0) + free(buf); } void @@ -1501,6 +1581,7 @@ window_copy_copy_line(struct window_pane *wp, struct grid_line *gl; struct utf8_data ud; u_int i, xx, wrapped = 0; + const char *s; if (sx > ex) return; @@ -1529,8 +1610,15 @@ window_copy_copy_line(struct window_pane *wp, if (gc->flags & GRID_FLAG_PADDING) continue; grid_cell_get(gc, &ud); + if (ud.size == 1 && (gc->attr & GRID_ATTR_CHARSET)) { + s = tty_acs_get(NULL, ud.data[0]); + if (s != NULL && strlen(s) <= sizeof ud.data) { + ud.size = strlen(s); + memcpy(ud.data, s, ud.size); + } + } - *buf = xrealloc(*buf, 1, (*off) + ud.size); + *buf = xrealloc(*buf, (*off) + ud.size); memcpy(*buf + *off, ud.data, ud.size); *off += ud.size; } @@ -1538,7 +1626,7 @@ window_copy_copy_line(struct window_pane *wp, /* Only add a newline if the line wasn't wrapped. */ if (!wrapped || ex != xx) { - *buf = xrealloc(*buf, 1, (*off) + 1); + *buf = xrealloc(*buf, (*off) + 1); (*buf)[(*off)++] = '\n'; } } @@ -1606,12 +1694,14 @@ window_copy_cursor_start_of_line(struct window_pane *wp) { struct window_copy_mode_data *data = wp->modedata; struct screen *back_s = data->backing; + struct screen *s = &data->screen; struct grid *gd = back_s->grid; 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; - 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); py = screen_hsize(back_s) + data->cy - data->oy; } @@ -1651,13 +1741,14 @@ window_copy_cursor_end_of_line(struct window_pane *wp) { struct window_copy_mode_data *data = wp->modedata; struct screen *back_s = data->backing; + struct screen *s = &data->screen; struct grid *gd = back_s->grid; u_int px, py; py = screen_hsize(back_s) + data->cy - data->oy; 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) px = screen_size_x(back_s); if (gd->linedata[py].flags & GRID_LINE_WRAPPED) { @@ -1681,11 +1772,16 @@ window_copy_other_end(struct window_pane *wp) { struct window_copy_mode_data *data = wp->modedata; struct screen *s = &data->screen; - u_int selx, sely, cx, cy, yy; + u_int selx, sely, cx, cy, yy, hsize; - if (!s->sel.flag) + if (!s->sel.flag && s->sel.lineflag == LINE_SEL_NONE) 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; sely = data->sely; cx = data->cx; @@ -1696,13 +1792,13 @@ window_copy_other_end(struct window_pane *wp) data->sely = yy; data->cx = selx; - if (sely < screen_hsize(data->backing) - data->oy) { - data->oy = screen_hsize(data->backing) - sely; + hsize = screen_hsize(data->backing); + if (sely < hsize - data->oy) { + data->oy = hsize - sely; data->cy = 0; - } else if (sely > screen_hsize(data->backing) - data->oy + screen_size_y(s)) { - data->oy = screen_hsize(data->backing) - sely + screen_size_y(s) - 1; + } else if (sely > hsize - data->oy + screen_size_y(s)) { + data->oy = hsize - sely + screen_size_y(s) - 1; data->cy = screen_size_y(s) - 1; - } else data->cy = cy + sely - yy; @@ -1761,6 +1857,9 @@ window_copy_cursor_up(struct window_pane *wp, int scroll_only) data->lastsx = ox; } + if (s->sel.lineflag == LINE_SEL_LEFT_RIGHT && oy == data->sely) + window_copy_other_end(wp); + data->cx = data->lastcx; if (scroll_only || data->cy == 0) { window_copy_scroll_down(wp, 1); @@ -1787,6 +1886,11 @@ window_copy_cursor_up(struct window_pane *wp, int scroll_only) data->cx > px) 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 @@ -1803,6 +1907,9 @@ window_copy_cursor_down(struct window_pane *wp, int scroll_only) data->lastsx = ox; } + if (s->sel.lineflag == LINE_SEL_RIGHT_LEFT && oy == data->sely) + window_copy_other_end(wp); + data->cx = data->lastcx; if (scroll_only || data->cy == screen_size_y(s) - 1) { window_copy_scroll_up(wp, 1); @@ -1821,6 +1928,11 @@ window_copy_cursor_down(struct window_pane *wp, int scroll_only) data->cx > px) 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 @@ -1982,7 +2094,8 @@ window_copy_cursor_next_word(struct window_pane *wp, const char *separators) } void -window_copy_cursor_next_word_end(struct window_pane *wp, const char *separators) +window_copy_cursor_next_word_end(struct window_pane *wp, + const char *separators) { struct window_copy_mode_data *data = wp->modedata; struct options *oo = &wp->window->options; @@ -2033,7 +2146,8 @@ window_copy_cursor_next_word_end(struct window_pane *wp, const char *separators) /* Move to the previous place where a word begins. */ void -window_copy_cursor_previous_word(struct window_pane *wp, const char *separators) +window_copy_cursor_previous_word(struct window_pane *wp, + const char *separators) { struct window_copy_mode_data *data = wp->modedata; u_int px, py; |