summary refs log tree commit diff
diff options
context:
space:
mode:
authorOliver Kiddle <opk@zsh.org>2016-11-17 12:28:08 +0100
committerOliver Kiddle <opk@zsh.org>2016-11-17 12:28:08 +0100
commit48bdcd771308072c1cfc35220e4478356fd475fa (patch)
treefb480ee81c57295ae807733bd7e8391d4038732c
parent6d991ce177d8821592b27158d4a96343a63e6745 (diff)
downloadzsh-48bdcd771308072c1cfc35220e4478356fd475fa.tar.gz
zsh-48bdcd771308072c1cfc35220e4478356fd475fa.tar.xz
zsh-48bdcd771308072c1cfc35220e4478356fd475fa.zip
39959: when repeating vi changes advance through the numbered killring registers
Also fix numeric arguments with vi-repeat-change: and argument passed
to the repeat replaces that previously saved with the change.
-rw-r--r--ChangeLog4
-rw-r--r--Src/Zle/zle_vi.c35
-rw-r--r--Test/X02zlevi.ztst15
3 files changed, 45 insertions, 9 deletions
diff --git a/ChangeLog b/ChangeLog
index 973414520..ce2e13871 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
 2016-11-17  Oliver Kiddle  <opk@zsh.org>
 
+	* 39959: Src/Zle/zle_vi.c, Test/X02zlevi.ztst: when repeating
+	vi changes advance through the numbered killring registers.
+	Also fix numeric arguments with vi-repeat-change.
+
 	* 39952: Src/Zle/zle_params.c, Doc/Zsh/zle.yo: add registers
 	special parameter to provide access to the vi register
 	buffers from a zle widget function
diff --git a/Src/Zle/zle_vi.c b/Src/Zle/zle_vi.c
index 213dc15f8..fc0e49b32 100644
--- a/Src/Zle/zle_vi.c
+++ b/Src/Zle/zle_vi.c
@@ -73,7 +73,13 @@ char *vichgbuf;
 /**/
 int viinsbegin;
 
+/* value of zmod associated with vi change */
 static struct modifier lastmod;
+
+/*
+ * inrepeat: current widget is the vi change being repeated
+ * vichgrepeat: nested widget call within a repeat
+ */
 static int inrepeat, vichgrepeat;
 
 /**
@@ -81,6 +87,7 @@ static int inrepeat, vichgrepeat;
  *    -1: skip setting insert mode
  *    -2: entering viins at start of editing from clean --- don't use
  *        inrepeat or keybuf, synthesise an entry to insert mode.
+ * Note that zmult is updated so this should be called before zmult is used.
  */
 
 /**/
@@ -402,9 +409,10 @@ videlete(UNUSED(char **args))
 int
 videletechar(char **args)
 {
-    int n = zmult;
+    int n;
 
     startvichange(-1);
+    n = zmult;
 
     /* handle negative argument */
     if (n < 0) {
@@ -451,9 +459,10 @@ vichange(UNUSED(char **args))
 int
 visubstitute(UNUSED(char **args))
 {
-    int n = zmult;
+    int n;
 
     startvichange(1);
+    n = zmult;
     if (n < 0)
 	return 1;
     /* it is an error to be on the end of line */
@@ -547,9 +556,10 @@ int
 viyankwholeline(UNUSED(char **args))
 {
     int bol = findbol(), oldcs = zlecs;
-    int n = zmult;
+    int n;
 
     startvichange(-1);
+    n = zmult;
     if (n < 1)
 	return 1;
     while(n--) {
@@ -591,8 +601,10 @@ int
 vireplacechars(UNUSED(char **args))
 {
     ZLE_INT_T ch;
-    int n = zmult, fail = 0, newchars = 0;
+    int n, fail = 0, newchars = 0;
 
+    startvichange(1);
+    n = zmult;
     if (n > 0) {
 	if (region_active) {
 	    int a, b;
@@ -629,7 +641,7 @@ vireplacechars(UNUSED(char **args))
 	    n = pos - zlecs;
 	}
     }
-    startvichange(1);
+
     /* check argument range */
     if (n < 1 || fail) {
 	if(vichgrepeat)
@@ -802,7 +814,9 @@ virepeatchange(UNUSED(char **args))
 	lastmod.vibuf = zmod.vibuf;
 	lastmod.flags = (lastmod.flags & ~MOD_VIAPP) |
 	    MOD_VIBUF | (zmod.flags & MOD_VIAPP);
-    }
+    } else if (lastmod.flags & MOD_VIBUF &&
+	    lastmod.vibuf >= 27 && lastmod.vibuf <= 34)
+	lastmod.vibuf++; /* for "1 to "8 advance to next buffer */
     /* repeat the command */
     inrepeat = 1;
     ungetbytes(vichgbuf, vichgbufptr);
@@ -885,12 +899,13 @@ viunindent(UNUSED(char **args))
 int
 vibackwarddeletechar(char **args)
 {
-    int n = zmult;
+    int n;
 
     if (invicmdmode())
 	startvichange(-1);
 
     /* handle negative argument */
+    n = zmult;
     if (n < 0) {
 	int ret;
 	zmult = -n;
@@ -930,10 +945,11 @@ int
 vijoin(UNUSED(char **args))
 {
     int x, pos;
-    int n = zmult;
+    int n;
     int visual = region_active;
 
     startvichange(-1);
+    n = zmult;
     if (n < 1)
 	return 1;
     if (visual && zlecs > mark) {
@@ -972,9 +988,10 @@ vijoin(UNUSED(char **args))
 int
 viswapcase(UNUSED(char **args))
 {
-    int eol, n = zmult;
+    int eol, n;
 
     startvichange(-1);
+    n = zmult;
     if (n < 1)
 	return 1;
     eol = findeol();
diff --git a/Test/X02zlevi.ztst b/Test/X02zlevi.ztst
index 70fef4c67..c19573241 100644
--- a/Test/X02zlevi.ztst
+++ b/Test/X02zlevi.ztst
@@ -130,6 +130,16 @@
 >long
 >CURSOR: 0
 
+  zletest $'one two\e03rX$.'
+0:repeat replace chars at the end of the line consumes the replace char
+>BUFFER: XXX two
+>CURSOR: 6
+
+  zletest $'one two three\e02rxw3.w.'
+0:numeric argument to repeat replaces change count
+>BUFFER: xxe xxx xxxee
+>CURSOR: 10
+
   zletest $'yankee doodle\ebhDyy0"1P'
 0:paste register 1 to get last deletion
 >BUFFER:  doodleyankee
@@ -178,6 +188,11 @@
 >
 >CURSOR: 0
 
+  zletest $'123456789\exxxxxxxxx"1P.........'
+0:repeat advances to next killring register
+>BUFFER: 9987654321
+>CURSOR: 0
+
   zletest $'Z\exayankee doodle\e"_db0"_yeP'
 0:yank and delete to black hole register
 >BUFFER: Zyankee e