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

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



Of the other vim registers "_ (the black hole register) is both useful
and meaningful in zsh so this adds that. I've also changed vi-set-buffer
so that when invoked from a zle widget, you can pass it the name of a
buffer to use so you can now use the following before other commands in
order to leave the cut buffer untouched.
  zle vi-set-buffer _

This also adds documentation and tests.

Oliver

diff --git a/Doc/Zsh/zle.yo b/Doc/Zsh/zle.yo
index 98f3802..881e56b 100644
--- a/Doc/Zsh/zle.yo
+++ b/Doc/Zsh/zle.yo
@@ -2180,19 +2180,29 @@ command.  tt(run-help) is normally aliased to tt(man).
 tindex(vi-set-buffer)
 item(tt(vi-set-buffer) (unbound) (") (unbound))(
 Specify a buffer to be used in the following command.
-There are 35 buffers that can be specified:
-the 26 `named' buffers tt("a) to tt("z)
-and the nine `queued' buffers tt("1) to tt("9).  The named buffers can also
-be specified as tt("A) to tt("Z).
-
-When a buffer is specified for a cut command, the text being cut replaces
-the previous contents of the specified buffer.  If a named buffer
-is specified using a capital, the newly cut text is appended to the buffer
-instead of overwriting it.
-
-If no buffer is specified for a cut command, tt("1) is used, and the
-contents of tt("1) to tt("8) are each shifted along one buffer; the contents of
-tt("9) is lost.
+There are 37 buffers that can be specified:
+the 26 `named' buffers tt("a) to tt("z), the `yank' buffer tt("0),
+the nine `queued' buffers tt("1) to tt("9) and the `black hole' buffer
+tt("_).  The named buffers can also be specified as tt("A) to tt("Z).
+
+When a buffer is specified for a cut, change or yank command, the text
+concerned replaces the previous contents of the specified buffer. If
+a named buffer is specified using a capital, the newly cut text is
+appended to the buffer instead of overwriting it. When using the tt("_)
+buffer, nothing happens. This can be useful for deleting text without
+affecting the normal registers.
+
+If no buffer is specified for a cut or change command, tt("1) is used, and
+the contents of tt("1) to tt("8) are each shifted along one buffer;
+the contents of tt("9) is lost. If no buffer is specified for a yank
+command, tt("0") is used. Finally, a paste command without a specified
+buffer will paste the text from the most recent command regardless of any
+buffer that might have been used with that command.
+
+When called from a widget function by the tt(zle) command, the buffer
+can optionally be specified with an argument. For example,
+
+example(zle vi-set-buffer A)
 )
 tindex(vi-set-mark)
 item(tt(vi-set-mark) (unbound) (m) (unbound))(
diff --git a/Src/Zle/zle.h b/Src/Zle/zle.h
index 860c821..dd6cdcc 100644
--- a/Src/Zle/zle.h
+++ b/Src/Zle/zle.h
@@ -240,6 +240,7 @@ struct modifier {
 #define MOD_VIBUF (1<<2)   /* a vi cut buffer has been selected */
 #define MOD_VIAPP (1<<3)   /* appending to the vi cut buffer */
 #define MOD_NEG   (1<<4)   /* last command was negate argument */
+#define MOD_NULL  (1<<5)   /* throw away text for the vi cut buffer */
 
 /* current modifier status */
 
diff --git a/Src/Zle/zle_utils.c b/Src/Zle/zle_utils.c
index f69bc77..46d5373 100644
--- a/Src/Zle/zle_utils.c
+++ b/Src/Zle/zle_utils.c
@@ -914,7 +914,7 @@ cut(int i, int ct, int flags)
 void
 cuttext(ZLE_STRING_T line, int ct, int flags)
 {
-    if (!ct)
+    if (!ct || zmod.flags & MOD_NULL)
 	return;
 
     UNMETACHECK();
diff --git a/Src/Zle/zle_vi.c b/Src/Zle/zle_vi.c
index 2555c6a..20cece0 100644
--- a/Src/Zle/zle_vi.c
+++ b/Src/Zle/zle_vi.c
@@ -782,7 +782,7 @@ viputbefore(UNUSED(char **args))
     int n = zmult;
 
     startvichange(-1);
-    if (n < 0)
+    if (n < 0 || zmod.flags & MOD_NULL)
 	return 1;
     if (zmod.flags & MOD_VIBUF)
 	buf = &vibuf[zmod.vibuf];
@@ -814,7 +814,7 @@ viputafter(UNUSED(char **args))
     int n = zmult;
 
     startvichange(-1);
-    if (n < 0)
+    if (n < 0 || zmod.flags & MOD_NULL)
 	return 1;
     if (zmod.flags & MOD_VIBUF)
 	buf = &vibuf[zmod.vibuf];
@@ -905,14 +905,26 @@ vicapslockpanic(UNUSED(char **args))
 
 /**/
 int
-visetbuffer(UNUSED(char **args))
+visetbuffer(char **args)
 {
     ZLE_INT_T ch;
 
-    if ((zmod.flags & MOD_VIBUF) ||
-	(((ch = getfullchar(0)) < ZWC('0') || ch > ZWC('9')) &&
+    if (*args) {
+	ch = **args;
+	if (args[1] || (ch && (*args)[1]))
+	    return 1;
+    } else {
+	ch = getfullchar(0);
+    }
+    if (ch == ZWC('_')) {
+	zmod.flags |= MOD_NULL;
+	prefixflag = 1;
+	return 0;
+    } else
+	zmod.flags &= ~MOD_NULL;
+    if ((ch < ZWC('0') || ch > ZWC('9')) &&
 	 (ch < ZWC('a') || ch > ZWC('z')) &&
-	 (ch < ZWC('A') || ch > ZWC('Z'))))
+	 (ch < ZWC('A') || ch > ZWC('Z')))
 	return 1;
     if (ch >= ZWC('A') && ch <= ZWC('Z'))	/* needed in cut() */
 	zmod.flags |= MOD_VIAPP;
diff --git a/Test/X02zlevi.ztst b/Test/X02zlevi.ztst
index 19188df..507107e 100644
--- a/Test/X02zlevi.ztst
+++ b/Test/X02zlevi.ztst
@@ -10,6 +10,66 @@
 
 %test
 
+  zletest $'yankee doodle\ebhDyy0"1P'
+0:paste register 1 to get last deletion
+>BUFFER:  doodleyankee
+>CURSOR: 6
+
+  zletest $'yankee\eyyodoodle\edd"0p'
+0:paste register 0 to get last yank
+>BUFFER: yankee
+>yankee
+>CURSOR: 7
+
+  zletest $'err\eddahello\e"hddP'
+0:setting named register also sets unnamed register
+>BUFFER: hello
+>CURSOR: 0
+
+  zletest $'first\e"ay0ddasecond\e"Add"aP'
+0:appending to named register
+>BUFFER: firs
+>second
+>CURSOR: 0
+
+  zletest $'word\e"a"byy"bp'
+0:set one and then a different register
+>BUFFER: word
+>word
+>CURSOR: 5
+
+  zletest $'i\exaar\e0"a"_cewn\eP'
+0:set register then set black hole register
+>BUFFER: win
+>CURSOR: 1
+
+  zletest $'double\eyy"_"0P'
+0:reset register after selecting black hole
+>BUFFER: double
+>double
+>CURSOR: 0
+
+# zsh works like vi here; in vim you get the concatenated string
+  zletest $'first\e"addasecond\eddP'
+0:retrieve unnamed register after appending
+>BUFFER: second
+>CURSOR: 0
+
+  zletest $'Z\exayankee doodle\e"_db0"_yeP'
+0:yank and delete to black hole register
+>BUFFER: Zyankee e
+>CURSOR: 0
+
+  zletest $'foo\eddabar\e"_p..'
+0:paste from black hole register and repeat
+>BUFFER: bar
+>CURSOR: 2
+
+  zletest $'start\eFa"ac2lnew\eX"ap..'
+0:repeat paste from named register
+>BUFFER: stnwararart
+>CURSOR: 9
+
   zletest $'word\euaend'
 0:undo initial change
 >BUFFER: end



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