about summary refs log tree commit diff
path: root/Src/Zle/zle_vi.c
diff options
context:
space:
mode:
Diffstat (limited to 'Src/Zle/zle_vi.c')
-rw-r--r--Src/Zle/zle_vi.c48
1 files changed, 40 insertions, 8 deletions
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;