zsh-workers
 help / color / mirror / code / Atom feed
* PATCH: make kill ring work in vi mode
@ 2014-10-29 23:42 Oliver Kiddle
  2014-10-30  2:13 ` Bart Schaefer
  2014-10-30  8:53 ` Peter Stephenson
  0 siblings, 2 replies; 5+ messages in thread
From: Oliver Kiddle @ 2014-10-29 23:42 UTC (permalink / raw)
  To: Zsh workers

This makes yank-pop also work together with vi-put-before and
vi-put-after. I find this a lot more usable than trying to work out
which of the vi numbered registers is applicable. In vim, this requires
a plugin (see https://github.com/maxbrunsfeld/vim-yankstack). 

Rather than make a bunch of static variables global, I've moved the vi
put functions to zle_misc.c. So startvichange() loses 'static' instead.
Any objections or alternative suggestions to this? There's a certain
amount of commonality between the four affected functions, should I
perhaps try to factor bits out into some smaller functions?

I'm not too happy with the way this interacts with undo. I'd prefer that
undo would revert everything to before the put instead of stepping back
through each yank-pop. This seems to be consistent with emacs though so
I'm probably stuck with it. I may also look further at what happens with
. (vi-repeat-change).

Oliver

diff --git a/Doc/Zsh/zle.yo b/Doc/Zsh/zle.yo
index 881e56b..06b1659 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 79d62c7..dc7e800 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 dd6cdcc..8a85ee3 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 9bc1cf6..10bd71c 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);
@@ -508,6 +509,84 @@ yank(UNUSED(char **args))
 
 /**/
 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;
+    if (kctbuf->flags & CUTBUFFER_LINE) {
+	yankb = zlecs = findbol();
+	spaceinline(kctbuf->len + 1);
+	ZS_memcpy(zleline + zlecs, kctbuf->buf, kctbuf->len);
+	yanke = zlecs + kctbuf->len + 1;
+	zleline[zlecs + kctbuf->len] = ZWC('\n');
+	vifirstnonblank(zlenoargs);
+    } else {
+	yankb = zlecs;
+	while (n--) {
+	    spaceinline(kctbuf->len);
+	    ZS_memcpy(zleline + zlecs, kctbuf->buf, kctbuf->len);
+	    zlecs += kctbuf->len;
+	}
+	yanke = zlecs;
+	if (zlecs)
+	    DECCS();
+    }
+    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;
+    if (kctbuf->flags & CUTBUFFER_LINE) {
+	yankb = zlecs = findeol();
+	spaceinline(kctbuf->len + 1);
+	zleline[zlecs++] = ZWC('\n');
+	yanke = zlecs + kctbuf->len;
+	ZS_memcpy(zleline + zlecs, kctbuf->buf, kctbuf->len);
+	vifirstnonblank(zlenoargs);
+    } else {
+	if (zlecs != findeol())
+	    INCCS();
+	yankb = zlecs;
+	while (n--) {
+	    spaceinline(kctbuf->len);
+	    ZS_memcpy(zleline + zlecs, kctbuf->buf, kctbuf->len);
+	    zlecs += kctbuf->len;
+	}
+	yanke = zlecs;
+	if (zlecs)
+	    DECCS();
+    }
+    return 0;
+}
+
+/**/
+int
 yankpop(UNUSED(char **args))
 {
     int cc, kctstart = kct;
@@ -557,11 +636,33 @@ 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;
+
+    if (buf->flags & CUTBUFFER_LINE) {
+	if (lastcmd & ZLE_YANKBEFORE) {
+	    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');
+	} else {
+	    yankb = zlecs = findeol();
+	    spaceinline(buf->len + 1);
+	    zleline[zlecs++] = ZWC('\n');
+	    yanke = zlecs + buf->len;
+	    ZS_memcpy(zleline + zlecs, buf->buf, buf->len);
+	}
+	vifirstnonblank(zlenoargs);
+    } else {
+	if ((lastcmd & ZLE_YANKAFTER) && zlecs != findeol())
+	    INCCS();
+	yankb = zlecs;
+	cc = buf->len;
+	spaceinline(cc);
+	ZS_memcpy(zleline + zlecs, buf->buf, cc);
+	zlecs += cc;
+	yanke = zlecs;
+    }
     return 0;
 }
 
diff --git a/Src/Zle/zle_vi.c b/Src/Zle/zle_vi.c
index 0a8b27d..b0e696b 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;


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2014-10-31 11:36 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-10-29 23:42 PATCH: make kill ring work in vi mode Oliver Kiddle
2014-10-30  2:13 ` Bart Schaefer
2014-10-30  8:53 ` Peter Stephenson
2014-10-30 17:54   ` Oliver Kiddle
2014-10-31 11:35     ` Vin Shelton

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).