From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 27102 invoked by alias); 10 Jun 2015 00:35:22 -0000 Mailing-List: contact zsh-workers-help@zsh.org; run by ezmlm Precedence: bulk X-No-Archive: yes List-Id: Zsh Workers List List-Post: List-Help: X-Seq: 35427 Received: (qmail 24460 invoked from network); 10 Jun 2015 00:35:18 -0000 X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on f.primenet.com.au X-Spam-Level: X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2 autolearn=ham autolearn_force=no version=3.4.0 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.co.uk; s=s2048; t=1433896118; bh=p+Utt7TeXVmdjylAk92oitVrvbAKgojZ0B///KMeva8=; h=In-reply-to:From:References:To:Subject:Date:From:Subject; b=HqpKBBvbIKXU4U2Zm70fRVHvgVc4TcfBGPsyr8vt+6C/cEYuMl/e783sRvnHFN9fABIctCCBQD31Mos7UIINs6EPyo5zMyg2LHXbuFQ9DD2IRFGXYshye7edBLjI2eIvxJbxhEVSWu8ifG0FAE2I1H9zU17tq4dJchNDQYFnydtV9WXX6xeEYMyxLJhFIQYFGdApCULsMDpW3cA12sdrexE/xyDbMIbuZRtHsRCLaFM8kuW79ASJbPApT0RguXqg4Kb7TcOhgSCGpLFeu30NOeHWx7ag/1ZFzDYPLkKbjHV6jMtAkLvCGvM+zsdZ1FKXj2jDYQZgv8U14MEmAbZ2GQ== X-Yahoo-Newman-Id: 447919.65160.bm@smtp134.mail.ir2.yahoo.com X-Yahoo-Newman-Property: ymail-3 X-YMail-OSG: hNdXMj4VM1mGHjIi75ZY7muFNDrlOo5QnkP1TAJ8vDF9tzi pMEUfygShElBw3fp6W2nvqrJKz98LlofyRDkalgQIMgSGs9niEmjwyJMTkh1 52qOUuJVKnJvHkJz50O3BB3c7VOLavDHzi_7hpIrkXTxY5ez36yikgqI9Z8R YI.3t7byDnhnOy2e8lu.aqUn.gwkRi6R92drdrCkCar8pM1A5CkVEBQB_KEk r9_0bdnFDyykJk46EOmQrZ028E6YMkShrTAwUHtGfPKvpZPRHiMt.HyJWxg1 Jr683.Y_X1SDFNjq1aKfekqzikab9MTCSj06ZfTTDDNdkPLg6piNij0NKwPe AT9N6_c1F2bod_NxLdrQ3R2k7Sxe6qfGZ2WRVAflzpl.hyFhN3K25BwIPxFQ 95O708ziEB_ovvimhgaeyPiVMTv322uGbOdXYnbxsti.Kp6fKZQVoe93aS4v yLhIbOUBLJeTEIbbYlgbvxfADruyx_vKrVS1PHCF74FY_JIAzTJmYNs2eTm8 0N3O2XOH_uAS2zgJ6QkZ.Heh1lGnmhrEq X-Yahoo-SMTP: opAkk_CswBAce_kJ3nIPlH80cJI- In-reply-to: From: Oliver Kiddle References: <55677AF5.50709@thequod.de> <27004.1433345491@thecus.kiddle.eu> <3098.1433511607@thecus.kiddle.eu> To: zsh-workers@zsh.org Subject: Re: bracketed paste mode in xterm and urxvt MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-ID: <7700.1433896116.1@thecus.kiddle.eu> Date: Wed, 10 Jun 2015 02:28:36 +0200 Message-ID: <7701.1433896116@thecus.kiddle.eu> On 5 Jun, Yuri D'Elia wrote: > What if the terminal itself turns off BREAK processing during paste? You can try. Would be interesting. May not work when there is ssh/sshd, telnet, screen, tmux etc sat between urxvt and zsh. > Putty also eats it by the way. If that's the case for all terminals, I > would just enabled it by default. We can always add some tests later if it appears to be necessary. Any objections? I've tried quite hard to find a terminal that won't eat the sequence and found none. This links it to a new BRACKETED_PASTE option. A concern with that approach is that if logic is needed in init_term() to disable the feature, the distinction between the user explicitly disabling the feature and init_term() doing it wouldn't be clear. Any thoughts on the exact positioning of the code to print the enable/disable sequences here? Is there any way the disable sequence could get missed? Doesn't seem necessary to do anything in trashzle(). Unlike zle-line-finish (but like $POSTEDIT), this prints the disable sequence even if zle is aborted with ^C or ^D. It is also important that it comes before preexec is run because that is where you might enable bracketed paste for specific commands. This includes the previous patch. The region is now replaced if active and the widget is also bound for vi command mode. Oliver diff --git a/Doc/Zsh/options.yo b/Doc/Zsh/options.yo index fa54024..6b32d89 100644 --- a/Doc/Zsh/options.yo +++ b/Doc/Zsh/options.yo @@ -2291,6 +2291,20 @@ cindex(enabling the beep) item(tt(BEEP) (tt(PLUS()B)) )( Beep on error in ZLE. ) +pindex(BRACKETED_PASTE) +pindex(NO_BRACKETED_PASTE) +pindex(NOBRACKETED_PASTE) +cindex(bracketed paste) +cindex(enabling bracketed paste) +item(tt(BRACKETED_PASTE))( +Many terminal emulators have a feature that allow applications to +identify when text is pasted into the terminal rather than being typed +normally. If this option is set, that feature will be enabled while ZLE +is active and disabled at other times. In particular, this means that +special characters such as tabs and newlines will be inserted instead of +invoking editor commands. Furthermore, pasted text forms a single undo +event and if the region is active, pasted text will replace the region. +) pindex(COMBINING_CHARS) pindex(NO_COMBINING_CHARS) pindex(COMBININGCHARS) diff --git a/Doc/Zsh/zle.yo b/Doc/Zsh/zle.yo index 16d661f..652f996 100644 --- a/Doc/Zsh/zle.yo +++ b/Doc/Zsh/zle.yo @@ -2057,6 +2057,11 @@ tindex(beep) item(tt(beep))( Beep, unless the tt(BEEP) option is unset. ) +tindex(bracketed-paste) +item(tt(bracketed-paste))( +This widget is invoked when text is pasted to the terminal emulator. +See also the BRACKETED_PASTE option. +) tindex(vi-cmd-mode) item(tt(vi-cmd-mode) (tt(^X^V)) (unbound) (tt(^[)))( Enter command mode; that is, select the `tt(vicmd)' keymap. diff --git a/Src/Zle/iwidgets.list b/Src/Zle/iwidgets.list index b41661a..6a07212 100644 --- a/Src/Zle/iwidgets.list +++ b/Src/Zle/iwidgets.list @@ -28,6 +28,7 @@ "beginning-of-history", beginningofhistory, 0 "beginning-of-line", beginningofline, 0 "beginning-of-line-hist", beginningoflinehist, 0 +"bracketed-paste", bracketedpaste, ZLE_MENUCMP | ZLE_KEEPSUFFIX "capitalize-word", capitalizeword, 0 "clear-screen", clearscreen, ZLE_MENUCMP | ZLE_KEEPSUFFIX | ZLE_LASTCOL | ZLE_NOTCOMMAND "complete-word", completeword, ZLE_MENUCMP | ZLE_KEEPSUFFIX | ZLE_ISCOMP diff --git a/Src/Zle/zle_keymap.c b/Src/Zle/zle_keymap.c index c6fae25..d355f41 100644 --- a/Src/Zle/zle_keymap.c +++ b/Src/Zle/zle_keymap.c @@ -1400,6 +1400,11 @@ default_bindings(void) bindkey(emap, "\30\30", refthingy(t_exchangepointandmark), NULL); bindkey(emap, "\30=", refthingy(t_whatcursorposition), NULL); + /* bracketed paste applicable to all keymaps */ + bindkey(emap, "\33[200~", refthingy(t_bracketedpaste), NULL); + bindkey(vmap, "\33[200~", refthingy(t_bracketedpaste), NULL); + bindkey(amap, "\33[200~", refthingy(t_bracketedpaste), NULL); + /* emacs mode: ESC sequences, all taken from the meta binding table */ buf[0] = '\33'; buf[2] = 0; diff --git a/Src/Zle/zle_main.c b/Src/Zle/zle_main.c index cec44c0..47b5aa5 100644 --- a/Src/Zle/zle_main.c +++ b/Src/Zle/zle_main.c @@ -1248,6 +1248,9 @@ zleread(char **lp, char **rp, int flags, int context, char *init, char *finish) zlecallhook(init, NULL); + if (isset(BRACKETEDPASTE)) + fputs("\e[?2004h", shout); + zrefresh(); zlecore(); @@ -1257,6 +1260,9 @@ zleread(char **lp, char **rp, int flags, int context, char *init, char *finish) "ZLE_VARED_ABORTED" : "ZLE_LINE_ABORTED", zlegetline(NULL, NULL)); + if (isset(BRACKETEDPASTE)) + fputs("\e[?2004l", shout); + if (done && !exit_pending && !errflag) zlecallhook(finish, NULL); diff --git a/Src/Zle/zle_misc.c b/Src/Zle/zle_misc.c index 4669ef2..873b01b 100644 --- a/Src/Zle/zle_misc.c +++ b/Src/Zle/zle_misc.c @@ -737,6 +737,44 @@ yankpop(UNUSED(char **args)) /**/ int +bracketedpaste(UNUSED(char **args)) +{ + static const char endesc[] = "\e[201~"; + int endpos = 0; + size_t psize = 64; + char *buf, *pbuf = zalloc(psize); + size_t current = 0; + int n, next, timeout; + ZLE_STRING_T wpaste; + + while (endesc[endpos]) { + if (current + 1 >= psize) + pbuf = zrealloc(pbuf, psize *= 2); + if ((next = getbyte(1L, &timeout)) == EOF) + break; + if (!endpos || next != endesc[endpos++]) + endpos = (next == *endesc); + if (imeta(next)) { + pbuf[current++] = Meta; + pbuf[current++] = next ^ 32; + } else if (next == '\r') + pbuf[current++] = '\n'; + else + pbuf[current++] = next; + } + pbuf[current-endpos] = '\0'; + buf = zmult == 1 ? pbuf : quotestring(pbuf, NULL, QT_BACKSLASH); + zmult = 1; + wpaste = stringaszleline(buf, 0, &n, NULL, NULL); + if (region_active) + killregion(zlenoargs); + doinsert(wpaste, n); + free(pbuf); free(wpaste); + return 0; +} + +/**/ +int overwritemode(UNUSED(char **args)) { insmode ^= 1; diff --git a/Src/options.c b/Src/options.c index 78f603d..440783f 100644 --- a/Src/options.c +++ b/Src/options.c @@ -100,6 +100,7 @@ static struct optname optns[] = { {{NULL, "beep", OPT_ALL}, BEEP}, {{NULL, "bgnice", OPT_EMULATE|OPT_NONBOURNE},BGNICE}, {{NULL, "braceccl", OPT_EMULATE}, BRACECCL}, +{{NULL, "bracketedpaste", OPT_ALL}, BRACKETEDPASTE}, {{NULL, "bsdecho", OPT_EMULATE|OPT_SH}, BSDECHO}, {{NULL, "caseglob", OPT_ALL}, CASEGLOB}, {{NULL, "casematch", OPT_ALL}, CASEMATCH}, diff --git a/Src/zsh.h b/Src/zsh.h index c88c2e7..ff3793a 100644 --- a/Src/zsh.h +++ b/Src/zsh.h @@ -2075,6 +2075,7 @@ enum { BEEP, BGNICE, BRACECCL, + BRACKETEDPASTE, BSDECHO, CASEGLOB, CASEMATCH,