From 0ea8f28e7b230315fe3fcca162a15258b618b0b2 Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Mon, 17 Nov 2014 16:32:04 +0100 Subject: 33700: new widget for put in vim style visual selection mode --- ChangeLog | 4 ++++ Doc/Zsh/zle.yo | 7 ++++++ Src/Zle/iwidgets.list | 1 + Src/Zle/zle_misc.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++---- Src/Zle/zle_utils.c | 2 +- 5 files changed, 70 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1491234a3..fc9f8e5fa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2014-11-17 Oliver Kiddle + * 33700: Doc/Zsh/zle.yo, Src/Zle/iwidgets.list, + Src/Zle/zle_misc.c, Src/Zle/zle_utils.c: new widget + for put in vim style visual selection mode + * 33699: Test/X02zlevi.ztst, Test/comptest: support short delays in zle tests where we need KEYTIMEOUT to elapse diff --git a/Doc/Zsh/zle.yo b/Doc/Zsh/zle.yo index 6fe7c9bf2..998bf4a10 100644 --- a/Doc/Zsh/zle.yo +++ b/Doc/Zsh/zle.yo @@ -1721,6 +1721,13 @@ Insert the contents of the kill buffer after the cursor. If the kill buffer contains a sequence of lines (as opposed to characters), paste it below the current line. ) +tindex(put-replace-selection) +item(tt(put-replace-selection) (unbound) (unbound) (unbound))( +Replace the contents of the current region or selection with the +contents of the kill buffer. If the kill buffer contains a sequence of +lines (as opposed to characters), the current line will be split by the +pasted lines. +) tindex(quoted-insert) item(tt(quoted-insert) (^V) (unbound) (unbound))( Insert the next character typed into the buffer literally. diff --git a/Src/Zle/iwidgets.list b/Src/Zle/iwidgets.list index a2bad5aa9..070116f5f 100644 --- a/Src/Zle/iwidgets.list +++ b/Src/Zle/iwidgets.list @@ -89,6 +89,7 @@ "push-input", pushinput, 0 "push-line", pushline, 0 "push-line-or-edit", pushlineoredit, 0 +"put-replace-selection", putreplaceselection, ZLE_KEEPSUFFIX "quoted-insert", quotedinsert, ZLE_MENUCMP | ZLE_KEEPSUFFIX "quote-line", quoteline, 0 "quote-region", quoteregion, 0 diff --git a/Src/Zle/zle_misc.c b/Src/Zle/zle_misc.c index 3d4a9bb4e..3e6d1aaac 100644 --- a/Src/Zle/zle_misc.c +++ b/Src/Zle/zle_misc.c @@ -507,11 +507,26 @@ yank(UNUSED(char **args)) return 0; } -static void pastebuf(Cutbuffer buf, int mult, int after) +/* position: 0 is before, 1 after, 2 split the line */ +static void pastebuf(Cutbuffer buf, int mult, int position) { int cc; if (buf->flags & CUTBUFFER_LINE) { - if (after) { + if (position == 2) { + if (!zlecs) + position = 0; + else if (zlecs == zlell) + position = 1; + } + if (position == 2) { + yankb = zlecs; + spaceinline(buf->len + 2); + zleline[zlecs++] = ZWC('\n'); + ZS_memcpy(zleline + zlecs, buf->buf, buf->len); + zlecs += buf->len; + zleline[zlecs] = ZWC('\n'); + yanke = zlecs + 1; + } else if (position != 0) { yankb = zlecs = findeol(); spaceinline(buf->len + 1); zleline[zlecs++] = ZWC('\n'); @@ -526,7 +541,7 @@ static void pastebuf(Cutbuffer buf, int mult, int after) } vifirstnonblank(zlenoargs); } else { - if (after && zlecs != findeol()) + if (position == 1 && zlecs != findeol()) INCCS(); yankb = zlecs; cc = buf->len; @@ -583,6 +598,44 @@ viputafter(UNUSED(char **args)) return 0; } +/**/ +int +putreplaceselection(UNUSED(char **args)) +{ + int n = zmult; + struct cutbuffer prevbuf; + Cutbuffer putbuf; + int clear = 0; + int pos = 2; + + startvichange(-1); + if (n < 0 || zmod.flags & MOD_NULL) + return 1; + putbuf = (zmod.flags & MOD_VIBUF) ? &vibuf[zmod.vibuf] : &cutbuf; + if (!putbuf->buf) + return 1; + memcpy(&prevbuf, putbuf, sizeof(prevbuf)); + + /* if "9 was specified, prevent killregion from freeing it */ + if (zmod.vibuf == 35) { + putbuf->buf = 0; + clear = 1; + } + + zmod.flags = 0; /* flags apply to paste not kill */ + if (region_active == 2 && prevbuf.flags & CUTBUFFER_LINE) { + int a, b; + regionlines(&a, &b); + pos = (b == zlell); + } + killregion(zlenoargs); + + pastebuf(&prevbuf, n, pos); + if (clear) + free(prevbuf.buf); + return 0; +} + /**/ int yankpop(UNUSED(char **args)) @@ -635,7 +688,7 @@ yankpop(UNUSED(char **args)) zlecs = yankb; foredel(yanke - yankb, CUT_RAW); zlecs = yankcs; - pastebuf(buf, 1, lastcmd & ZLE_YANKAFTER); + pastebuf(buf, 1, !!(lastcmd & ZLE_YANKAFTER)); return 0; } diff --git a/Src/Zle/zle_utils.c b/Src/Zle/zle_utils.c index f56063e82..08a32c30e 100644 --- a/Src/Zle/zle_utils.c +++ b/Src/Zle/zle_utils.c @@ -953,7 +953,7 @@ cuttext(ZLE_STRING_T line, int ct, int flags) } else { /* Save in "1, shifting "1-"8 along to "2-"9 */ int n; - free(vibuf[34].buf); + free(vibuf[35].buf); for(n=35; n>27; n--) vibuf[n] = vibuf[n-1]; vibuf[27].buf = (ZLE_STRING_T)zalloc(ct * ZLE_CHAR_SIZE); -- cgit 1.4.1