about summary refs log tree commit diff
diff options
context:
space:
mode:
authorOliver Kiddle <opk@zsh.org>2014-11-17 22:47:59 +0100
committerOliver Kiddle <opk@zsh.org>2014-11-17 22:47:59 +0100
commit492b6cec28d70eb4ef34054f414dd1e80102e857 (patch)
tree4857f503061b5123cbfbab03dae4fc3bf11a2c1a
parent0ea8f28e7b230315fe3fcca162a15258b618b0b2 (diff)
downloadzsh-492b6cec28d70eb4ef34054f414dd1e80102e857.tar.gz
zsh-492b6cec28d70eb4ef34054f414dd1e80102e857.tar.xz
zsh-492b6cec28d70eb4ef34054f414dd1e80102e857.zip
33635: adapt region to function as vim style visual selection mode
-rw-r--r--ChangeLog4
-rw-r--r--Src/Zle/iwidgets.list1
-rw-r--r--Src/Zle/zle_misc.c14
-rw-r--r--Src/Zle/zle_move.c18
-rw-r--r--Src/Zle/zle_refresh.c2
-rw-r--r--Src/Zle/zle_vi.c48
6 files changed, 74 insertions, 13 deletions
diff --git a/ChangeLog b/ChangeLog
index fc9f8e5fa..7391f300c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
 2014-11-17  Oliver Kiddle  <opk@zsh.org>
 
+	* 33635: Src/Zle/iwidgets.list, Src/Zle/zle_misc.c,
+	Src/Zle/zle_move.c, Src/Zle/zle_refresh.c, Src/Zle/zle_vi.c:
+	adapt region to function as vim style visual selection mode
+
 	* 33700: Doc/Zsh/zle.yo, Src/Zle/iwidgets.list,
 	Src/Zle/zle_misc.c, Src/Zle/zle_utils.c: new widget
 	for put in vim style visual selection mode
diff --git a/Src/Zle/iwidgets.list b/Src/Zle/iwidgets.list
index 070116f5f..23e5783f9 100644
--- a/Src/Zle/iwidgets.list
+++ b/Src/Zle/iwidgets.list
@@ -184,6 +184,7 @@
 "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
 "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 3e6d1aaac..5996c485d 100644
--- a/Src/Zle/zle_misc.c
+++ b/Src/Zle/zle_misc.c
@@ -446,9 +446,12 @@ killregion(UNUSED(char **args))
     if (mark > zlell)
 	mark = zlell;
     if (mark > zlecs)
-	forekill(mark - zlecs, CUT_RAW);
-    else
+	forekill(mark - zlecs + invicmdmode(), CUT_RAW);
+    else {
+	if (invicmdmode())
+	    INCCS();
 	backkill(zlecs - mark, CUT_FRONT|CUT_RAW);
+    }
     return 0;
 }
 
@@ -465,9 +468,9 @@ copyregionaskill(char **args)
 	if (mark > zlell)
 	    mark = zlell;
 	if (mark > zlecs)
-	    cut(zlecs, mark - zlecs, 0);
+	    cut(zlecs, mark - zlecs + invicmdmode(), 0);
 	else
-	    cut(mark, zlecs - mark, CUT_FRONT);
+	    cut(mark, zlecs - mark + invicmdmode(), CUT_FRONT);
     }
     return 0;
 }
@@ -1016,7 +1019,8 @@ quoteregion(UNUSED(char **args))
 	mark = zlecs;
 	zlecs = tmp;
     }
-    str = (ZLE_STRING_T)hcalloc((len = mark - zlecs) * ZLE_CHAR_SIZE);
+    str = (ZLE_STRING_T)hcalloc((len = mark - zlecs + invicmdmode()) *
+	ZLE_CHAR_SIZE);
     ZS_memcpy(str, zleline + zlecs, len);
     foredel(len, CUT_RAW);
     str = makequote(str, &len);
diff --git a/Src/Zle/zle_move.c b/Src/Zle/zle_move.c
index 35e419369..7b6420c06 100644
--- a/Src/Zle/zle_move.c
+++ b/Src/Zle/zle_move.c
@@ -509,6 +509,24 @@ exchangepointandmark(UNUSED(char **args))
 
 /**/
 int
+visualmode(UNUSED(char **args))
+{
+    switch (region_active) {
+    case 1:
+	region_active = 0;
+	break;
+    case 0:
+	mark = zlecs;
+	/* fall through */
+    case 2:
+	region_active = 1;
+	break;
+    }
+    return 0;
+}
+
+/**/
+int
 vigotocolumn(UNUSED(char **args))
 {
     int x, y, n = zmult;
diff --git a/Src/Zle/zle_refresh.c b/Src/Zle/zle_refresh.c
index 684ac13a2..ebc6b494c 100644
--- a/Src/Zle/zle_refresh.c
+++ b/Src/Zle/zle_refresh.c
@@ -1037,6 +1037,8 @@ zrefresh(void)
 	    region_highlights[0].start = mark;
 	    region_highlights[0].end = zlecs;
 	}
+	if (invicmdmode())
+	    INCPOS(region_highlights[0].end);
     } 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 c3a9e75aa..02877deee 100644
--- a/Src/Zle/zle_vi.c
+++ b/Src/Zle/zle_vi.c
@@ -162,9 +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 mult1 = zmult, hist1 = histline;
     Thingy k2;
 
+    if (visual) {
+	pos = mark;
+    } else {
+
     virangeflag = 1;
     wordflag = wf;
     mark = -1;
@@ -239,6 +244,7 @@ getvirange(int wf)
      * and use the mark. */
     if (mark != -1)
 	pos = mark;
+    }
     mark = mpos;
 
     /* Get the range the right way round.  zlecs is placed at the *
@@ -250,6 +256,11 @@ getvirange(int wf)
 	pos = tmp;
     }
 
+    if (visual && invicmdmode()) {
+	region_active = 0;
+	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,   *
      * rather than just the sequence of characters delimited by pos   *
@@ -377,6 +388,10 @@ videletechar(char **args)
     int n = zmult;
 
     startvichange(-1);
+
+    if (region_active)
+	return killregion(args);
+
     /* handle negative argument */
     if (n < 0) {
 	int ret;
@@ -430,12 +445,16 @@ visubstitute(UNUSED(char **args))
     /* it is an error to be on the end of line */
     if (zlecs == zlell || zleline[zlecs] == '\n')
 	return 1;
-    /* Put argument into the acceptable range -- it is not an error to  *
-     * specify a greater count than the number of available characters. */
-    if (n > findeol() - zlecs)
-	n = findeol() - zlecs;
-    /* do the substitution */
-    forekill(n, CUT_RAW);
+    if (region_active) {
+	killregion(zlenoargs);
+    } else {
+	/* Put argument into the acceptable range -- it is not an error to  *
+	* specify a greater count than the number of available characters. */
+	if (n > findeol() - zlecs)
+	    n = findeol() - zlecs;
+	/* do the substitution */
+	forekill(n, CUT_RAW);
+    }
     startvitext(1);
     return 0;
 }
@@ -770,6 +789,10 @@ vibackwarddeletechar(char **args)
 
     if (invicmdmode())
 	startvichange(-1);
+
+    if (region_active)
+	return killregion(args);
+
     /* handle negative argument */
     if (n < 0) {
 	int ret;
@@ -811,12 +834,21 @@ vijoin(UNUSED(char **args))
 {
     int x, pos;
     int n = zmult;
+    int visual = region_active;
 
     startvichange(-1);
     if (n < 1)
 	return 1;
-    if ((x = findeol()) == zlell)
+    if (visual && zlecs > mark) {
+	exchangepointandmark(zlenoargs);
+	x = findeol();
+	if (x >= mark) {
+	    exchangepointandmark(zlenoargs);
+	    return 1;
+	}
+    } else if ((x = findeol()) == zlell || (visual && x >= mark))
 	return 1;
+
     while (n) {
 	zlecs = x + 1;
 	pos = zlecs;
@@ -834,7 +866,7 @@ vijoin(UNUSED(char **args))
 	}
 	spaceinline(1);
 	zleline[zlecs] = ZWC(' ');
-	if (--n < 2 || (x = findeol()) == zlell)
+	if ((!visual && --n < 2) || (x = findeol()) == zlell || (visual && x >= mark))
 	    return 0;
     }
     return 0;