Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

PATCH: Re: bug report: vi mode yank should yank to 0 register



I wrote:
> > I have noticed that zsh vi mode is using the " register instead of the 0
> > register when a yank is done.
> 
> It's a vi mode not a vim mode. And as in vi, there is no 0 register. You
> might notice that you get a beep after pressing "0.

The patch below adds support for this. No tests or documentation just
yet. There's no user-visible handling for the " register partly because
I can't think of a use for it without also implementing vim's i_Ctrl-R
or some other vim feature I'm not aware of. More sensible might be a zle
special variable to access the registers. Is it actually possible at the
moment to have a special associative array without using a hash table
internally underneath?

> I'm not sure that "1 to "9 are exactly working as in vi: both deletions
> and yanks go to them. This is probably because they were implemented on
> top of the killring which was implemented with emacs in mind first.

This patch also has the side-effect of fixing this. Note that I was
wrong above about emacs: the registers are completely separate from the
killring.

In the process, I've found a couple of further issues: even with a named
register, we should update cutbuf and under some circumstances we seem
to be erroneously appending to cutbuf instead of replacing it.

Oliver

diff --git a/Src/Zle/zle.h b/Src/Zle/zle.h
index 870e214..860c821 100644
--- a/Src/Zle/zle.h
+++ b/Src/Zle/zle.h
@@ -256,6 +256,7 @@ struct modifier {
 			      * of visible characters directly input by
 			      * the user.
 			      */
+#define CUT_YANK    (1<<3)   /* vi yank: use register 0 instead of 1-9 */
 
 /* undo system */
 
diff --git a/Src/Zle/zle_main.c b/Src/Zle/zle_main.c
index 442c319..8344c66 100644
--- a/Src/Zle/zle_main.c
+++ b/Src/Zle/zle_main.c
@@ -2128,7 +2128,7 @@ finish_(UNUSED(Module m))
 	    free(kring[i].buf);
 	zfree(kring, kringsize * sizeof(struct cutbuffer));
     }
-    for(i = 35; i--; )
+    for(i = 36; i--; )
 	zfree(vibuf[i].buf, vibuf[i].len);
 
     /* editor entry points */
diff --git a/Src/Zle/zle_utils.c b/Src/Zle/zle_utils.c
index 1089e27..1479365 100644
--- a/Src/Zle/zle_utils.c
+++ b/Src/Zle/zle_utils.c
@@ -43,10 +43,10 @@ struct cutbuffer *kring;
 int kringsize, kringnum;
 
 /* Vi named cut buffers.  0-25 are the named buffers "a to "z, and *
- * 26-34 are the numbered buffer stack "1 to "9.                   */
+ * 26-35 are the numbered buffer stack "0 to "9.                   */
 
 /**/
-struct cutbuffer vibuf[35];
+struct cutbuffer vibuf[36];
 
 /* the line before last mod (for undo purposes) */
 
@@ -942,16 +942,23 @@ cuttext(ZLE_STRING_T line, int ct, int flags)
 	    b->len = len + ct;
 	}
 	return;
+    } else if (flags & CUT_YANK) {
+	/* Save in "0 */
+	free(vibuf[26].buf);
+	vibuf[26].buf = (ZLE_STRING_T)zalloc(ct * ZLE_CHAR_SIZE);
+	ZS_memcpy(vibuf[26].buf, line, ct);
+	vibuf[26].len = ct;
+	vibuf[26].flags = vilinerange ? CUTBUFFER_LINE : 0;
     } else {
 	/* Save in "1, shifting "1-"8 along to "2-"9 */
 	int n;
 	free(vibuf[34].buf);
-	for(n=34; n>26; n--)
+	for(n=35; n>27; n--)
 	    vibuf[n] = vibuf[n-1];
-	vibuf[26].buf = (ZLE_STRING_T)zalloc(ct * ZLE_CHAR_SIZE);
-	ZS_memcpy(vibuf[26].buf, line, ct);
-	vibuf[26].len = ct;
-	vibuf[26].flags = vilinerange ? CUTBUFFER_LINE : 0;
+	vibuf[27].buf = (ZLE_STRING_T)zalloc(ct * ZLE_CHAR_SIZE);
+	ZS_memcpy(vibuf[27].buf, line, ct);
+	vibuf[27].len = ct;
+	vibuf[27].flags = vilinerange ? CUTBUFFER_LINE : 0;
     }
     if (!cutbuf.buf) {
 	cutbuf.buf = (ZLE_STRING_T)zalloc(ZLE_CHAR_SIZE);
diff --git a/Src/Zle/zle_vi.c b/Src/Zle/zle_vi.c
index 9e39143..2555c6a 100644
--- a/Src/Zle/zle_vi.c
+++ b/Src/Zle/zle_vi.c
@@ -453,7 +453,7 @@ viyank(UNUSED(char **args))
 
     startvichange(1);
     if ((c2 = getvirange(0)) != -1) {
-	cut(zlecs, c2 - zlecs, 0);
+	cut(zlecs, c2 - zlecs, CUT_YANK);
 	ret = 0;
     }
     vichgflag = 0;
@@ -470,7 +470,7 @@ viyankeol(UNUSED(char **args))
     startvichange(-1);
     if (x == zlecs)
 	return 1;
-    cut(zlecs, x - zlecs, 0);
+    cut(zlecs, x - zlecs, CUT_YANK);
     return 0;
 }
 
@@ -492,7 +492,7 @@ viyankwholeline(UNUSED(char **args))
      zlecs = findeol() + 1;
     }
     vilinerange = 1;
-    cut(bol, zlecs - bol - 1, 0);
+    cut(bol, zlecs - bol - 1, CUT_YANK);
     zlecs = oldcs;
     return 0;
 }
@@ -910,7 +910,7 @@ visetbuffer(UNUSED(char **args))
     ZLE_INT_T ch;
 
     if ((zmod.flags & MOD_VIBUF) ||
-	(((ch = getfullchar(0)) < ZWC('1') || ch > ZWC('9')) &&
+	(((ch = getfullchar(0)) < ZWC('0') || ch > ZWC('9')) &&
 	 (ch < ZWC('a') || ch > ZWC('z')) &&
 	 (ch < ZWC('A') || ch > ZWC('Z'))))
 	return 1;
@@ -920,8 +920,8 @@ visetbuffer(UNUSED(char **args))
 	zmod.flags &= ~MOD_VIAPP;
     /* FIXME how portable is it for multibyte encoding? */
     zmod.vibuf = ZC_tolower(ch);
-    if (ch >= ZWC('1') && ch <= ZWC('9'))
-	zmod.vibuf += - (int)ZWC('1') + 26;
+    if (ch >= ZWC('0') && ch <= ZWC('9'))
+	zmod.vibuf += - (int)ZWC('0') + 26;
     else
 	zmod.vibuf += - (int)ZWC('a');
     zmod.flags |= MOD_VIBUF;



Messages sorted by: Reverse Date, Date, Thread, Author