summaryrefslogtreecommitdiff
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.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