Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Re: bracketed paste - chopping trailing newlines
- X-seq: zsh-workers 36443
- From: Daniel Shahaf <d.s@xxxxxxxxxxxxxxxxxx>
- To: Carsten Hey <carsten@xxxxxxxxxx>
- Subject: Re: bracketed paste - chopping trailing newlines
- Date: Mon, 7 Sep 2015 21:13:11 +0000
- Cc: zsh-workers@xxxxxxx
- Dkim-signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d= daniel.shahaf.name; h=cc:content-transfer-encoding:content-type :date:from:in-reply-to:message-id:mime-version:references :subject:to:x-sasl-enc:x-sasl-enc; s=mesmtp; bh=RIBv+pGAFvCuq9WE R8qDtapLiIM=; b=uPwnoe18geiSJ5MQfPJmCC0edRnM5YCvXrhzlQAZrxnAQ5kI f+3B5qwxuuHOjtprlfOsg4lkW2MEBYxvNEQAOXtwlloxPkRRdWK9e71UWZqpJ50F RfFu91xZI6p2KuhdbeUkeQSCq+g8X1CgXYPY5qUUp0qrk9WXm6NyfnJPeFc=
- Dkim-signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:content-type :date:from:in-reply-to:message-id:mime-version:references :subject:to:x-sasl-enc:x-sasl-enc; s=smtpout; bh=RIBv+pGAFvCuq9W ER8qDtapLiIM=; b=gkA/lDLfVvDeobClwWnMbA4tqDww/cpxH6H3b0kSbwTlXm8 w3dwzVSPFLS3d6ETkZk4a2T4X+02ZZJfBKjAvq01N/wqMKa8pAHagHN6I+oOqf6i g38trKhhde4uQB6xSAhDGNcYno7rFBAx/qJ/ZfQER/Wv0co0yhMC3dr1ZMts=
- In-reply-to: <20150906095224.GD1895@tarsus.local2>
- 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
- References: <20150829012452.GE30848@bosko.stateful.de> <150828220057.ZM14497@torch.brasslantern.com> <20150830202530.GF30848@bosko.stateful.de> <150901164827.ZM2480@torch.brasslantern.com> <20150903235936.GH30848@bosko.stateful.de> <20150906095224.GD1895@tarsus.local2>
Daniel Shahaf wrote on Sun, Sep 06, 2015 at 09:52:24 +0000:
> Carsten Hey wrote on Fri, Sep 04, 2015 at 01:59:36 +0200:
> > An other main paste feature, not running a pasted command without user
> > interaction, would be disabled by this (which makes it, for my private
> > setup, a good candidate for being activated if needed by some currently
> > unused function key).
> >
> > Btw., I also think that highlighting is sufficient to alert the user
> > that no command is running - that it vanishes if a command runs makes
> > this pretty clear for the second time, and the first time the previously
> > unseen highlighing should catch the attention of the users and make them
> > check what happend. zle -M ... seems to be a bit too verbose for
> > a default behaviour.
>
> I'm attaching a patch and a zshrc that together demonstrate the proposed
> behaviour. To test them, apply the patch, run the resulting 'zsh -f',
> and source the script.
>
> I propose to make the _resulting behaviour_ the default in 5.1.1. However,
> before I spend time on rewriting the attached patch entirely in C, I'd
> like to ensure we have consensus for making this change.
>
> The behaviour is: (a) pastes are never executed until <Enter> is pressed;
> (b) zle_highlight is set; (c) newlines are removed only at <accept-line>.
I've gone ahead and prepared a patch series that implementes that behaviour
entirely in C. It's attached.
From 5fff3ba4c26ec7105a54f0189a53145d4a287541 Mon Sep 17 00:00:00 2001
From: Daniel Shahaf <d.s@xxxxxxxxxxxxxxxxxx>
Date: Wed, 2 Sep 2015 12:16:39 +0000
Subject: [PATCH 1/3] Revert "35834: strip a final newline from pasted text:
inserting is hard to tell apart from accepting it"
This reverts commit f17eb26a34af69a2238a3d8b46079445e09c096e.
Conflicts:
ChangeLog
Src/Zle/zle_misc.c
---
ChangeLog | 1 +
Src/Zle/zle_misc.c | 6 ------
2 files changed, 1 insertion(+), 6 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index cdaed18..bfb71f4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -371,6 +371,7 @@
* 36125: Src/Zle/zle_hist.c: don't set history context in get-line
+ [reverted in NNNNN]
* 35834 (tweaked): Src/Zle/zle_misc.c: strip a final newline from
pasted text: inserting is hard to tell apart from accepting it
diff --git a/Src/Zle/zle_misc.c b/Src/Zle/zle_misc.c
index 2d18628..c1005dc 100644
--- a/Src/Zle/zle_misc.c
+++ b/Src/Zle/zle_misc.c
@@ -787,12 +787,6 @@ bracketedpaste(char **args)
zmult = 1;
if (region_active)
killregion(zlenoargs);
- /* Chop a final newline if its insertion would be hard to
- * distinguish by the user from the line being accepted. */
- else if (n > 1 && zlecontext != ZLCON_VARED &&
- (zlecs + (insmode ? 0 : n - 1)) >= zlell &&
- wpaste[n-1] == ZWC('\n'))
- n--;
yankcs = yankb = zlecs;
doinsert(wpaste, n);
yanke = zlecs;
--
2.1.4
From 2266d4e4e56dcad8c35ec7f57973f69b0b278ff9 Mon Sep 17 00:00:00 2001
From: Daniel Shahaf <d.s@xxxxxxxxxxxxxxxxxx>
Date: Mon, 7 Sep 2015 15:50:26 +0000
Subject: [PATCH 2/3] Set zle_highlight=(paste:standout) by default.
---
Doc/Zsh/zle.yo | 2 +-
Src/Zle/zle_refresh.c | 3 ++-
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/Doc/Zsh/zle.yo b/Doc/Zsh/zle.yo
index 4e93695..05bae3c 100644
--- a/Doc/Zsh/zle.yo
+++ b/Doc/Zsh/zle.yo
@@ -2656,7 +2656,7 @@ If tt(zle_highlight) is not set or no value applies to a particular
context, the defaults applied are equivalent to
example(zle_highlight=LPAR()region:standout special:standout
-suffix:bold isearch:underline+RPAR())
+suffix:bold isearch:underline paste:standout+RPAR())
i.e. both the region and special characters are shown in standout mode.
diff --git a/Src/Zle/zle_refresh.c b/Src/Zle/zle_refresh.c
index 0c28c0a..6facff4 100644
--- a/Src/Zle/zle_refresh.c
+++ b/Src/Zle/zle_refresh.c
@@ -372,7 +372,8 @@ zle_set_highlight(void)
region_highlights[1].atr = TXTUNDERLINE;
if (!suffix_atr_on_set)
region_highlights[2].atr = TXTBOLDFACE;
- /* paste defaults to 0 */
+ if (!paste_atr_on_set)
+ region_highlights[3].atr = TXTSTANDOUT;
allocate_colour_buffer();
}
--
2.1.4
From a0e7bfb791703f140fdbe3aee5c24f490945228c Mon Sep 17 00:00:00 2001
From: Daniel Shahaf <d.s@xxxxxxxxxxxxxxxxxx>
Date: Mon, 7 Sep 2015 17:10:03 +0000
Subject: [PATCH 3/3] accept-line, accept-and-hold,
accept-and-infer-next-history: Strip trailing newline after paste.
---
Src/Zle/zle_hist.c | 4 ++++
Src/Zle/zle_misc.c | 25 +++++++++++++++++++++++++
Src/utils.c | 32 ++++++++++++++++++++++++++++++++
3 files changed, 61 insertions(+)
diff --git a/Src/Zle/zle_hist.c b/Src/Zle/zle_hist.c
index c61b4ef..c3d7c1a 100644
--- a/Src/Zle/zle_hist.c
+++ b/Src/Zle/zle_hist.c
@@ -1728,12 +1728,16 @@ infernexthist(Histent he, UNUSED(char **args))
return NULL;
}
+/* Defined in zle_misc.c */
+void zle_strip_trailing_newline_if_after_paste(void);
+
/**/
int
acceptandinfernexthistory(char **args)
{
Histent he;
+ zle_strip_trailing_newline_if_after_paste();
if (!(he = infernexthist(hist_ring, args)))
return 1;
zpushnode(bufstack, ztrdup(he->node.nam));
diff --git a/Src/Zle/zle_misc.c b/Src/Zle/zle_misc.c
index c1005dc..dac31bf 100644
--- a/Src/Zle/zle_misc.c
+++ b/Src/Zle/zle_misc.c
@@ -395,10 +395,34 @@ poundinsert(UNUSED(char **args))
return 0;
}
+/* Declare non-static so zle_hist.c can use it */
+void zle_strip_trailing_newline_if_after_paste(void);
+
+/* If the last widget is a paste, and the last byte is a newline, strip it.
+ *
+ * If it was syntactically whitespace, that's cleaner; and if it was
+ * significant, it will be re-added latre.
+ */
+void zle_strip_trailing_newline_if_after_paste(void)
+{
+ if (lbindk == Th(z_bracketedpaste)) {
+ if (zlemetaline ? zlemetall : zlell) {
+ char last = zlemetaline ? ztr_last(zlemetaline) : zleline[zlell-1];
+ if (last == ZWC('\n')) {
+ /* backwarddeletechar() doesn't use ARGS, but be conservative
+ * and pass them empty. */
+ static char *empty_args[] = { NULL };
+ backwarddeletechar(empty_args);
+ }
+ }
+ }
+}
+
/**/
int
acceptline(UNUSED(char **args))
{
+ zle_strip_trailing_newline_if_after_paste();
done = 1;
return 0;
}
@@ -407,6 +431,7 @@ acceptline(UNUSED(char **args))
int
acceptandhold(UNUSED(char **args))
{
+ zle_strip_trailing_newline_if_after_paste();
zpushnode(bufstack, zlelineasstring(zleline, zlell, 0, NULL, NULL, 0));
stackcs = zlecs;
done = 1;
diff --git a/Src/utils.c b/Src/utils.c
index ca68eae..325997a 100644
--- a/Src/utils.c
+++ b/Src/utils.c
@@ -4483,6 +4483,38 @@ unmeta(const char *file_name)
return fn;
}
+/* Return the last character of a metafied non-empty string */
+
+/**/
+mod_export char
+ztr_last(char const *s)
+{
+ char last;
+
+ if (!*s) {
+ DPUTS(1, "BUG: ztr_last() called on empty string\n");
+
+ /* We must return some value. Hopefully NUL is good enough. */
+ return '\0';
+ }
+
+ while (*s) {
+ if (*s == Meta) {
+ ++s;
+ if (! *s) {
+ DPUTS(1, "BUG: unexpected end of string in ztr_last()\n");
+
+ /* We must return some value. Hopefully NUL is good enough. */
+ return '\0';
+ }
+ last = *s++ ^ 32;
+ }
+ else
+ last = *s++;
+ }
+ return last;
+}
+
/*
* Unmetafy and compare two strings, comparing unsigned character values.
* "a\0" sorts after "a".
--
2.1.4
Messages sorted by:
Reverse Date,
Date,
Thread,
Author