Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
PATCH: implement put for vim style selection mode
- X-seq: zsh-workers 33700
- From: Oliver Kiddle <okiddle@xxxxxxxxxxx>
- To: Zsh workers <zsh-workers@xxxxxxx>
- Subject: PATCH: implement put for vim style selection mode
- Date: Mon, 17 Nov 2014 01:45:45 +0100
- Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.co.uk; s=s2048; t=1416185146; bh=6mTVVSAC6cS8I9/qv1ysPLr+YYiAC0xbiZq424wqRbY=; h=From:To:Subject:Date:From:Subject; b=OjPIV+XJ5pwZyofhbOsN7pasKtbT46N5uHm2u4j1U5nOMEY3g7/RGHpY4vUeoa8eDCJtaJESFB1OR7a5b59FU8HJ6nFOYw1w171DEV6wzGVrpyrAJHv2WDNFVPP0THQdfthbwiptAzsWKSNAEGFor0ET5TzNf5zZyQEWRSXk4MW0ldaBNmeStmIMY2pQr3DLRFfe5ZmKrj10C7IyU+jcDcN/CeooH1UHYwPBr+K0/78wy5oSrjv+WagzbFCBbS2Hi4CGoiwnex1rLrE0gIWrHdrKuuQ7HlQKPkg6Hd1u4TKjlxdz2fr3rK+IDrRmkRVHLFvj6axmZ7DkRwOF/t/zJQ==
- Domainkey-signature: a=rsa-sha1; q=dns; c=nofws; s=s2048; d=yahoo.co.uk; b=X++ojL5JRLDkTteWGmDevuXVm+atWe3vHybLYolUAogBxCTv7R6MycZV1eywkEjbh4vs4isG4HNBAPrD7ZUq1KYxujpIfdHdq3+bHj/Gv46dWRVFH3RMJ4ByP0fTYSaxWKf/WtlTF1INdPc1/grHcnxF02bqsG5qlmERtfW4HBsjp0+LQUF+lkVo6jUMvCJ+texyTWsz7o7qrptdZkLreo7GIG4mdaN6D2+ZJyTN2Obnz2W2rkIkLDUPgRZ10vHp/dgr9xLCsnaEqfQ3tu78ZUUVtDHLZ9QSBlQiOFOk82HOcTFXfeVkSmwOSGGmAU4o3sBw1W/bLCSYjWJJ/ve3VA==;
- List-help: <mailto:zsh-workers-help@zsh.org>
- List-id: Zsh Workers List <zsh-workers.zsh.org>
- List-post: <mailto:zsh-workers@zsh.org>
- Mailing-list: contact zsh-workers-help@xxxxxxx; run by ezmlm
Rather than change both vi-put-before and vi-put-after for visual mode,
this adds a new put-replace-selection widget. The idea being that this
is bound to p in the visual keymap. My thinking is that having more but
simpler widgets in this manner will be more flexible.
Along similar lines, I think it makes sense to revert the region
handling I added to vi-delete-char and vi-backward-delete-char: x can
simply be bound to vi-delete in the visual keymap. In vim, X actually
forces a linewise delete but I don't think I can be bothered to do that.
Oddly, the same is not true of P which perhaps shows how obscure the
feature is.
It'll need a little adjustment to be usable from emacs or vi insert
mode. The killring isn't supported: it gets a bit too complicated
because it kills the selection itself first before pasting.
Tests will come later: I have them prepared but they depend on the
keybindings.
Oliver
diff --git a/Doc/Zsh/zle.yo b/Doc/Zsh/zle.yo
index 6fe7c9b..998bf4a 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 a2bad5a..070116f 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 3d4a9bb..9b6b7ac 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;
@@ -585,6 +600,44 @@ viputafter(UNUSED(char **args))
/**/
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))
{
int kctstart = kct;
@@ -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 f56063e..08a32c3 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);
Messages sorted by:
Reverse Date,
Date,
Thread,
Author