From 36878852efc1673aba445e7affe9c5c554c343d5 Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Mon, 17 Nov 2014 22:50:34 +0100 Subject: 33636: add support for a linewise visual selection mode --- Src/Zle/iwidgets.list | 3 ++- Src/Zle/zle_misc.c | 45 ++++++++++++++++++++++++++++++++++++++++++--- Src/Zle/zle_move.c | 19 +++++++++++++++++++ Src/Zle/zle_refresh.c | 8 ++++++++ Src/Zle/zle_vi.c | 28 +++++++++++++++++++++------- 5 files changed, 92 insertions(+), 11 deletions(-) (limited to 'Src/Zle') diff --git a/Src/Zle/iwidgets.list b/Src/Zle/iwidgets.list index 23e5783f9..26182974a 100644 --- a/Src/Zle/iwidgets.list +++ b/Src/Zle/iwidgets.list @@ -184,7 +184,8 @@ "vi-yank", viyank, ZLE_LASTCOL "vi-yank-eol", viyankeol, 0 "vi-yank-whole-line", viyankwholeline, 0 -"visual-mode", visualmode, ZLE_MENUCMP | ZLE_KEEPSUFFIX | ZLE_LASTCOL +"visual-line-mode", visuallinemode, ZLE_MENUCMP | ZLE_LASTCOL +"visual-mode", visualmode, ZLE_MENUCMP | ZLE_LASTCOL "what-cursor-position", whatcursorposition, ZLE_MENUCMP | ZLE_KEEPSUFFIX | ZLE_LASTCOL "where-is", whereis, ZLE_MENUCMP | ZLE_KEEPSUFFIX | ZLE_LASTCOL "which-command", processcmd, ZLE_MENUCMP | ZLE_KEEPSUFFIX | ZLE_LASTCOL diff --git a/Src/Zle/zle_misc.c b/Src/Zle/zle_misc.c index 5996c485d..a220a6bc8 100644 --- a/Src/Zle/zle_misc.c +++ b/Src/Zle/zle_misc.c @@ -439,13 +439,45 @@ killline(char **args) return 0; } +/**/ +void +regionlines(int *start, int *end) +{ + int origcs = zlecs; + + UNMETACHECK(); + if (zlecs < mark) { + *start = findbol(); + zlecs = (mark > zlell) ? zlell : mark; + *end = findeol(); + } else { + *end = findeol(); + zlecs = mark; + *start = findbol(); + } + zlecs = origcs; +} + /**/ int killregion(UNUSED(char **args)) { if (mark > zlell) mark = zlell; - if (mark > zlecs) + if (region_active == 2) { + int a, b; + regionlines(&a, &b); + zlecs = a; + region_active = 0; + cut(zlecs, b - zlecs, CUT_RAW); + shiftchars(zlecs, b - zlecs); + if (zlell) { + if (zlecs == zlell) + DECCS(); + foredel(1, 0); + vifirstnonblank(zlenoargs); + } + } else if (mark > zlecs) forekill(mark - zlecs + invicmdmode(), CUT_RAW); else { if (invicmdmode()) @@ -1011,15 +1043,22 @@ quoteregion(UNUSED(char **args)) { ZLE_STRING_T str; size_t len; + int extra = invicmdmode(); if (mark > zlell) mark = zlell; - if (mark < zlecs) { + if (region_active == 2) { + int a, b; + regionlines(&a, &b); + zlecs = a; + mark = b; + extra = 0; + } else if (mark < zlecs) { int tmp = mark; mark = zlecs; zlecs = tmp; } - str = (ZLE_STRING_T)hcalloc((len = mark - zlecs + invicmdmode()) * + str = (ZLE_STRING_T)hcalloc((len = mark - zlecs + extra) * ZLE_CHAR_SIZE); ZS_memcpy(str, zleline + zlecs, len); foredel(len, CUT_RAW); diff --git a/Src/Zle/zle_move.c b/Src/Zle/zle_move.c index 7b6420c06..fad6b0a5f 100644 --- a/Src/Zle/zle_move.c +++ b/Src/Zle/zle_move.c @@ -525,6 +525,25 @@ visualmode(UNUSED(char **args)) return 0; } +/**/ +int +visuallinemode(UNUSED(char **args)) +{ + switch (region_active) { + case 2: + region_active = 0; + break; + case 0: + mark = zlecs; + /* fall through */ + case 1: + region_active = 2; + break; + } + return 0; +} + + /**/ int vigotocolumn(UNUSED(char **args)) diff --git a/Src/Zle/zle_refresh.c b/Src/Zle/zle_refresh.c index ebc6b494c..f0351ad15 100644 --- a/Src/Zle/zle_refresh.c +++ b/Src/Zle/zle_refresh.c @@ -1039,6 +1039,14 @@ zrefresh(void) } if (invicmdmode()) INCPOS(region_highlights[0].end); + if (region_active == 2) { + int origcs = zlecs; + zlecs = region_highlights[0].end; + region_highlights[0].end = findeol(); + zlecs = region_highlights[0].start; + region_highlights[0].start = findbol(); + zlecs = origcs; + } } else { region_highlights[0].start = region_highlights[0].end = -1; } diff --git a/Src/Zle/zle_vi.c b/Src/Zle/zle_vi.c index 02877deee..3a4304ced 100644 --- a/Src/Zle/zle_vi.c +++ b/Src/Zle/zle_vi.c @@ -162,12 +162,14 @@ static int getvirange(int wf) { int pos = zlecs, mpos = mark, ret = 0; - int visual = region_active; /* don't trust movement cmd not to change it */ + int visual = region_active; /* movement command might set it */ int mult1 = zmult, hist1 = histline; Thingy k2; if (visual) { pos = mark; + vilinerange = (visual == 2); + region_active = 0; } else { virangeflag = 1; @@ -256,10 +258,8 @@ getvirange(int wf) pos = tmp; } - if (visual && invicmdmode()) { - region_active = 0; + if (visual && invicmdmode()) INCPOS(pos); - } /* Was it a line-oriented move? If so, the command will have set * * the vilinerange flag. In this case, entire lines are taken, * @@ -463,7 +463,15 @@ visubstitute(UNUSED(char **args)) int vichangeeol(UNUSED(char **args)) { - forekill(findeol() - zlecs, CUT_RAW); + int a, b; + if (region_active) { + regionlines(&a, &b); + zlecs = a; + region_active = 0; + cut(zlecs, b - zlecs, CUT_RAW); + shiftchars(zlecs, b - zlecs); + } else + forekill(findeol() - zlecs, CUT_RAW); startvitext(1); return 0; } @@ -721,8 +729,11 @@ viindent(UNUSED(char **args)) { int oldcs = zlecs, c2; - /* get the range */ startvichange(1); + /* force line range */ + if (region_active == 1) + region_active = 2; + /* get the range */ if ((c2 = getvirange(0)) == -1) { vichgflag = 0; return 1; @@ -756,8 +767,11 @@ viunindent(UNUSED(char **args)) { int oldcs = zlecs, c2; - /* get the range */ startvichange(1); + /* force line range */ + if (region_active == 1) + region_active = 2; + /* get the range */ if ((c2 = getvirange(0)) == -1) { vichgflag = 0; return 1; -- cgit 1.4.1