From 96835d663171fa44d740bcba7e75e9e615f5b4b6 Mon Sep 17 00:00:00 2001 From: Juho Pohjala Date: Sat, 21 Jun 2014 02:02:13 +0300 Subject: [PATCH] vi-copy: select line with V Line selection behaves similarly as in Vim. --- mode-key.c | 1 + screen.c | 1 + tmux.h | 5 +++++ window-copy.c | 42 +++++++++++++++++++++++++++++++++++------- 4 files changed, 42 insertions(+), 7 deletions(-) diff --git a/mode-key.c b/mode-key.c index 8bb83cb..0857c29 100644 --- a/mode-key.c +++ b/mode-key.c @@ -288,6 +288,7 @@ const struct mode_key_entry mode_key_vi_copy[] = { { 'M', 0, MODEKEYCOPY_MIDDLELINE }, { 'N', 0, MODEKEYCOPY_SEARCHREVERSE }, { 'T', 0, MODEKEYCOPY_JUMPTOBACK }, + { 'V', 0, MODEKEYCOPY_SELECTLINE }, { 'W', 0, MODEKEYCOPY_NEXTSPACE }, { '\002' /* C-b */, 0, MODEKEYCOPY_PREVIOUSPAGE }, { '\003' /* C-c */, 0, MODEKEYCOPY_CANCEL }, diff --git a/screen.c b/screen.c index 7bfc015..31cd591 100644 --- a/screen.c +++ b/screen.c @@ -270,6 +270,7 @@ screen_clear_selection(struct screen *s) struct screen_sel *sel = &s->sel; sel->flag = 0; + sel->lineflag = LINE_SELECTION_NONE; } /* Check if cell in selection. */ diff --git a/tmux.h b/tmux.h index c4c5236..8e2187a 100644 --- a/tmux.h +++ b/tmux.h @@ -756,6 +756,11 @@ LIST_HEAD(joblist, job); struct screen_sel { int flag; int rectflag; + enum { + LINE_SELECTION_NONE = 0, + LINE_SELECTION_LEFT_TO_RIGHT, + LINE_SELECTION_RIGHT_TO_LEFT, + } lineflag; u_int sx; u_int sy; diff --git a/window-copy.c b/window-copy.c index 0775bcb..fd76f03 100644 --- a/window-copy.c +++ b/window-copy.c @@ -527,11 +527,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_SELECTION_NONE; window_copy_start_selection(wp); window_copy_redraw_screen(wp); break; - case MODEKEYCOPY_COPYLINE: case MODEKEYCOPY_SELECTLINE: + s->sel.lineflag = LINE_SELECTION_LEFT_TO_RIGHT; + data->rectflag = 0; + /* FALLTHROUGH */ + case MODEKEYCOPY_COPYLINE: window_copy_cursor_start_of_line(wp); /* FALLTHROUGH */ case MODEKEYCOPY_COPYENDOFLINE: @@ -729,6 +733,7 @@ window_copy_key(struct window_pane *wp, struct session *sess, int key) } break; case MODEKEYCOPY_RECTANGLETOGGLE: + s->sel.lineflag = LINE_SELECTION_NONE; window_copy_rectangle_toggle(wp); break; default: @@ -894,7 +899,7 @@ window_copy_mouse( * We reached the bottom, leave copy mode, but * 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_SELECTION_NONE) goto reset_mode; } } @@ -1310,7 +1315,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_SELECTION_NONE) return (0); /* Set colours. */ @@ -1364,7 +1369,7 @@ window_copy_get_selection(struct window_pane *wp, size_t *len) u_int firstsx, lastex, restex, restsx; int keys; - if (!s->sel.flag) + if (!s->sel.flag && s->sel.lineflag == LINE_SELECTION_NONE) return (NULL); buf = xmalloc(1); @@ -1656,10 +1661,11 @@ 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_SELECTION_NONE) { py = screen_hsize(back_s) + data->cy - data->oy; while (py > 0 && gd->linedata[py-1].flags & GRID_LINE_WRAPPED) { window_copy_cursor_up(wp, 0); @@ -1701,13 +1707,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_SELECTION_NONE) { if (data->screen.sel.flag && data->rectflag) px = screen_size_x(back_s); if (gd->linedata[py].flags & GRID_LINE_WRAPPED) { @@ -1733,9 +1740,14 @@ window_copy_other_end(struct window_pane *wp) struct screen *s = &data->screen; u_int selx, sely, cx, cy, yy; - if (!s->sel.flag) + if (!s->sel.flag && s->sel.lineflag == LINE_SELECTION_NONE) return; + if (s->sel.lineflag == LINE_SELECTION_LEFT_TO_RIGHT) + s->sel.lineflag = LINE_SELECTION_RIGHT_TO_LEFT; + else if (s->sel.lineflag == LINE_SELECTION_RIGHT_TO_LEFT) + s->sel.lineflag = LINE_SELECTION_LEFT_TO_RIGHT; + selx = data->selx; sely = data->sely; cx = data->cx; @@ -1811,6 +1823,9 @@ window_copy_cursor_up(struct window_pane *wp, int scroll_only) data->lastsx = ox; } + if (s->sel.lineflag == LINE_SELECTION_LEFT_TO_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); @@ -1837,6 +1852,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_SELECTION_LEFT_TO_RIGHT) + window_copy_cursor_end_of_line(wp); + else if (s->sel.lineflag == LINE_SELECTION_RIGHT_TO_LEFT) + window_copy_cursor_start_of_line(wp); } void @@ -1853,6 +1873,9 @@ window_copy_cursor_down(struct window_pane *wp, int scroll_only) data->lastsx = ox; } + if (s->sel.lineflag == LINE_SELECTION_RIGHT_TO_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); @@ -1871,6 +1894,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_SELECTION_LEFT_TO_RIGHT) + window_copy_cursor_end_of_line(wp); + else if (s->sel.lineflag == LINE_SELECTION_RIGHT_TO_LEFT) + window_copy_cursor_start_of_line(wp); } void -- 1.7.10.4