about summary refs log tree commit diff
path: root/Src
diff options
context:
space:
mode:
Diffstat (limited to 'Src')
-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
4 files changed, 97 insertions, 87 deletions
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;