about summary refs log tree commit diff
diff options
context:
space:
mode:
authorOliver Kiddle <opk@zsh.org>2014-10-30 21:52:18 +0100
committerOliver Kiddle <opk@zsh.org>2014-10-30 21:52:36 +0100
commitfd302c9837b0034962471b9288b182e2525ba1d8 (patch)
tree9b47d9b32d8612077b25aeb5ea937725c8946b70
parent9d2cfa7af6b8973e13716f7c36f7fb156e3348dd (diff)
downloadzsh-fd302c9837b0034962471b9288b182e2525ba1d8.tar.gz
zsh-fd302c9837b0034962471b9288b182e2525ba1d8.tar.xz
zsh-fd302c9837b0034962471b9288b182e2525ba1d8.zip
33570, 33576: make killring/yank-pop work in vi mode after
vi-put-before and vi-put-after
-rw-r--r--ChangeLog6
-rw-r--r--Doc/Zsh/zle.yo2
-rw-r--r--Src/Zle/iwidgets.list8
-rw-r--r--Src/Zle/zle.h16
-rw-r--r--Src/Zle/zle_misc.c92
-rw-r--r--Src/Zle/zle_vi.c68
-rw-r--r--Test/X02zlevi.ztst28
7 files changed, 132 insertions, 88 deletions
diff --git a/ChangeLog b/ChangeLog
index 284029883..146f1b8c1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2014-10-30  Oliver Kiddle  <opk@zsh.org>
+
+	* 33570, 33576: Doc/Zsh/zle.yo, Src/Zle/iwidgets.list, Src/Zle/zle.h,
+	Src/Zle/zle_misc.c, Src/Zle/zle_vi.c, Test/X02zlevi.ztst: make kill-
+	ring/yank-pop work in vi mode after vi-put-before and vi-put-after
+
 2014-10-29  Barton E. Schaefer  <schaefer@zsh.org>
 
 	* 33566: Jun T.: Src/Modules/zselect.c: quash compiler warning
diff --git a/Doc/Zsh/zle.yo b/Doc/Zsh/zle.yo
index 881e56b19..06b165963 100644
--- a/Doc/Zsh/zle.yo
+++ b/Doc/Zsh/zle.yo
@@ -1786,7 +1786,7 @@ tindex(yank-pop)
 item(tt(yank-pop) (ESC-y) (unbound) (unbound))(
 Remove the text just yanked, rotate the kill-ring (the history of
 previously killed text) and yank the new top.  Only works following
-tt(yank) or tt(yank-pop).
+tt(yank), tt(vi-put-before), tt(vi-put-after) or tt(yank-pop).
 )
 tindex(vi-yank)
 item(tt(vi-yank) (unbound) (y) (unbound))(
diff --git a/Src/Zle/iwidgets.list b/Src/Zle/iwidgets.list
index 79d62c7b5..dc7e8008d 100644
--- a/Src/Zle/iwidgets.list
+++ b/Src/Zle/iwidgets.list
@@ -159,8 +159,8 @@
 "vi-open-line-below", viopenlinebelow, 0
 "vi-oper-swap-case", vioperswapcase, ZLE_LASTCOL
 "vi-pound-insert", vipoundinsert, 0
-"vi-put-after", viputafter, ZLE_YANK | ZLE_KEEPSUFFIX
-"vi-put-before", viputbefore, ZLE_YANK | ZLE_KEEPSUFFIX
+"vi-put-after", viputafter, ZLE_YANKAFTER | ZLE_KEEPSUFFIX
+"vi-put-before", viputbefore, ZLE_YANKBEFORE | ZLE_KEEPSUFFIX
 "vi-quoted-insert", viquotedinsert, ZLE_MENUCMP | ZLE_KEEPSUFFIX
 "vi-repeat-change", virepeatchange, 0
 "vi-repeat-find", virepeatfind, 0
@@ -182,5 +182,5 @@
 "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
-"yank", yank, ZLE_YANK | ZLE_KEEPSUFFIX
-"yank-pop", yankpop, ZLE_YANK | ZLE_KEEPSUFFIX
+"yank", yank, ZLE_YANKBEFORE | ZLE_KEEPSUFFIX
+"yank-pop", yankpop, ZLE_KEEPSUFFIX | ZLE_NOTCOMMAND
diff --git a/Src/Zle/zle.h b/Src/Zle/zle.h
index dd6cdcca0..8a85ee342 100644
--- a/Src/Zle/zle.h
+++ b/Src/Zle/zle.h
@@ -203,13 +203,15 @@ struct widget {
 #define WIDGET_INT	(1<<0)	/* widget is internally implemented */
 #define WIDGET_NCOMP    (1<<1)	/* new style completion widget */
 #define ZLE_MENUCMP	(1<<2)	/* DON'T invalidate completion list */
-#define ZLE_YANK	(1<<3)
-#define ZLE_LINEMOVE	(1<<4)	/* command is a line-oriented movement */
-#define ZLE_LASTCOL     (1<<5)	/* command maintains lastcol correctly */
-#define ZLE_KILL	(1<<6)
-#define ZLE_KEEPSUFFIX	(1<<7)	/* DON'T remove added suffix */
-#define ZLE_NOTCOMMAND  (1<<8)	/* widget should not alter lastcmd */
-#define ZLE_ISCOMP      (1<<9)	/* usable for new style completion */
+#define ZLE_YANKAFTER	(1<<3)
+#define ZLE_YANKBEFORE	(1<<4)
+#define ZLE_YANK        (ZLE_YANKAFTER | ZLE_YANKBEFORE)
+#define ZLE_LINEMOVE	(1<<5)	/* command is a line-oriented movement */
+#define ZLE_LASTCOL     (1<<6)	/* command maintains lastcol correctly */
+#define ZLE_KILL	(1<<7)
+#define ZLE_KEEPSUFFIX	(1<<8)	/* DON'T remove added suffix */
+#define ZLE_NOTCOMMAND  (1<<9)	/* widget should not alter lastcmd */
+#define ZLE_ISCOMP      (1<<10)	/* usable for new style completion */
 
 /* thingies */
 
diff --git a/Src/Zle/zle_misc.c b/Src/Zle/zle_misc.c
index 9bc1cf6f5..3d4a9bb4e 100644
--- a/Src/Zle/zle_misc.c
+++ b/Src/Zle/zle_misc.c
@@ -475,8 +475,10 @@ copyregionaskill(char **args)
 /*
  * kct: index into kill ring, or -1 for original cutbuffer of yank.
  * yankb, yanke: mark the start and end of last yank in editing buffer.
+ * yankcs marks the cursor position preceding the last yank
  */
-static int kct, yankb, yanke;
+static int kct, yankb, yanke, yankcs;
+
 /* The original cutbuffer, either cutbuf or one of the vi buffers. */
 static Cutbuffer kctbuf;
 
@@ -494,8 +496,7 @@ yank(UNUSED(char **args))
 	kctbuf = &cutbuf;
     if (!kctbuf->buf)
 	return 1;
-    mark = zlecs;
-    yankb = zlecs;
+    yankb = yankcs = mark = zlecs;
     while (n--) {
 	kct = -1;
 	spaceinline(kctbuf->len);
@@ -506,11 +507,87 @@ yank(UNUSED(char **args))
     return 0;
 }
 
+static void pastebuf(Cutbuffer buf, int mult, int after)
+{
+    int cc;
+    if (buf->flags & CUTBUFFER_LINE) {
+	if (after) {
+	    yankb = zlecs = findeol();
+	    spaceinline(buf->len + 1);
+	    zleline[zlecs++] = ZWC('\n');
+	    yanke = zlecs + buf->len;
+	    ZS_memcpy(zleline + zlecs, buf->buf, buf->len);
+	} else {
+	    yankb = zlecs = findbol();
+	    spaceinline(buf->len + 1);
+	    ZS_memcpy(zleline + zlecs, buf->buf, buf->len);
+	    yanke = zlecs + buf->len + 1;
+	    zleline[zlecs + buf->len] = ZWC('\n');
+	}
+	vifirstnonblank(zlenoargs);
+    } else {
+	if (after && zlecs != findeol())
+	    INCCS();
+	yankb = zlecs;
+	cc = buf->len;
+	while (mult--) {
+	    spaceinline(cc);
+	    ZS_memcpy(zleline + zlecs, buf->buf, cc);
+	    zlecs += cc;
+	}
+	yanke = zlecs;
+	if (zlecs)
+	    DECCS();
+    }
+}
+
+/**/
+int
+viputbefore(UNUSED(char **args))
+{
+    int n = zmult;
+
+    startvichange(-1);
+    if (n < 0 || zmod.flags & MOD_NULL)
+	return 1;
+    if (zmod.flags & MOD_VIBUF)
+	kctbuf = &vibuf[zmod.vibuf];
+    else
+	kctbuf = &cutbuf;
+    if (!kctbuf->buf)
+	return 1;
+    kct = -1;
+    yankcs = zlecs;
+    pastebuf(kctbuf, n, 0);
+    return 0;
+}
+
+/**/
+int
+viputafter(UNUSED(char **args))
+{
+    int n = zmult;
+
+    startvichange(-1);
+    if (n < 0 || zmod.flags & MOD_NULL)
+	return 1;
+    if (zmod.flags & MOD_VIBUF)
+	kctbuf = &vibuf[zmod.vibuf];
+    else
+	kctbuf = &cutbuf;
+    if (!kctbuf->buf)
+	return 1;
+    kct = -1;
+    yankcs = zlecs;
+    pastebuf(kctbuf, n, 1);
+    return 0;
+}
+
 /**/
 int
 yankpop(UNUSED(char **args))
 {
-    int cc, kctstart = kct;
+    int kctstart = kct;
     Cutbuffer buf;
 
     if (!(lastcmd & ZLE_YANK) || !kring || !kctbuf) {
@@ -557,11 +634,8 @@ yankpop(UNUSED(char **args))
 
     zlecs = yankb;
     foredel(yanke - yankb, CUT_RAW);
-    cc = buf->len;
-    spaceinline(cc);
-    ZS_memcpy(zleline + zlecs, buf->buf, cc);
-    zlecs += cc;
-    yanke = zlecs;
+    zlecs = yankcs;
+    pastebuf(buf, 1, lastcmd & ZLE_YANKAFTER);
     return 0;
 }
 
diff --git a/Src/Zle/zle_vi.c b/Src/Zle/zle_vi.c
index 0a8b27d65..b0e696b62 100644
--- a/Src/Zle/zle_vi.c
+++ b/Src/Zle/zle_vi.c
@@ -75,7 +75,7 @@ static int inrepeat, vichgrepeat;
  */
 
 /**/
-static void
+void
 startvichange(int im)
 {
     if (im != -1) {
@@ -793,72 +793,6 @@ vikillline(UNUSED(char **args))
 
 /**/
 int
-viputbefore(UNUSED(char **args))
-{
-    Cutbuffer buf = &cutbuf;
-    int n = zmult;
-
-    startvichange(-1);
-    if (n < 0 || zmod.flags & MOD_NULL)
-	return 1;
-    if (zmod.flags & MOD_VIBUF)
-	buf = &vibuf[zmod.vibuf];
-    if (!buf->buf)
-	return 1;
-    if(buf->flags & CUTBUFFER_LINE) {
-	zlecs = findbol();
-	spaceinline(buf->len + 1);
-	ZS_memcpy(zleline + zlecs, buf->buf, buf->len);
-	zleline[zlecs + buf->len] = ZWC('\n');
-	vifirstnonblank(zlenoargs);
-    } else {
-	while (n--) {
-	    spaceinline(buf->len);
-	    ZS_memcpy(zleline + zlecs, buf->buf, buf->len);
-	    zlecs += buf->len;
-	}
-	if (zlecs)
-	    DECCS();
-    }
-    return 0;
-}
-
-/**/
-int
-viputafter(UNUSED(char **args))
-{
-    Cutbuffer buf = &cutbuf;
-    int n = zmult;
-
-    startvichange(-1);
-    if (n < 0 || zmod.flags & MOD_NULL)
-	return 1;
-    if (zmod.flags & MOD_VIBUF)
-	buf = &vibuf[zmod.vibuf];
-    if (!buf->buf)
-	return 1;
-    if(buf->flags & CUTBUFFER_LINE) {
-	zlecs = findeol();
-	spaceinline(buf->len + 1);
-	zleline[zlecs++] = ZWC('\n');
-	ZS_memcpy(zleline + zlecs, buf->buf, buf->len);
-	vifirstnonblank(zlenoargs);
-    } else {
-	if (zlecs != findeol())
-	    INCCS();
-	while (n--) {
-	    spaceinline(buf->len);
-	    ZS_memcpy(zleline + zlecs, buf->buf, buf->len);
-	    zlecs += buf->len;
-	}
-	if (zlecs)
-	    DECCS();
-    }
-    return 0;
-}
-
-/**/
-int
 vijoin(UNUSED(char **args))
 {
     int x, pos;
diff --git a/Test/X02zlevi.ztst b/Test/X02zlevi.ztst
index 2af6f06e6..185980b70 100644
--- a/Test/X02zlevi.ztst
+++ b/Test/X02zlevi.ztst
@@ -116,6 +116,34 @@
 >BUFFER: stnwararart
 >CURSOR: 9
 
+  zpty_run 'bindkey -a "^P" yank-pop'
+  zletest $'word\C-wline\eddiSE\eP\C-P'
+0:line based put before followed by character based yank-pop
+>BUFFER: SwordE
+>CURSOR: 4
+
+  zletest $'line\eddiword\C-w\eiSE\eP\C-P'
+0:character based put before followed by line based yank-pop
+>BUFFER: line
+>SE
+>CURSOR: 0
+
+  zletest $'one two three\C-w\C-w\C-wSE\e0p\C-P\C-P'
+0:put after cycled twice with yank-pop
+>BUFFER: SthreeE
+>CURSOR: 5
+
+  zletest $'word\C-wline\eddiSE\ehp\C-P'
+0:line based put after followed by character based yank-pop
+>BUFFER: SwordE
+>CURSOR: 5
+
+  zletest $'line\eddiword\C-w\eiSE\ehp\C-P'
+0:character based after before followed by line based yank-pop
+>BUFFER: SE
+>line
+>CURSOR: 3
+
   zletest $'word\euaend'
 0:undo initial change
 >BUFFER: end