From mboxrd@z Thu Jan 1 00:00:00 1970
X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on inbox.vuxu.org
X-Spam-Level:
X-Spam-Status: No, score=-3.4 required=5.0 tests=DKIM_SIGNED,DKIM_VALID,
DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED,
T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.4
Received: (qmail 12529 invoked from network); 2 Jun 2023 10:19:02 -0000
Received: from zero.zsh.org (2a02:898:31:0:48:4558:7a:7368)
by inbox.vuxu.org with ESMTPUTF8; 2 Jun 2023 10:19:02 -0000
ARC-Seal: i=1; cv=none; a=rsa-sha256; d=zsh.org; s=rsa-20210803; t=1685701143;
b=hESPymSPR1C53uSWz/lS4j/pbLU6b3vNypmAaMh77DrsMscD8ap3sekUr9QP+Txp8Zx4IC7khS
SIm5gLb+LkOtO0LsaycVZ/uyDsy3AC9xn2zvio0geGUgtikRgRzwrQe+LXDwc4QQmyf3Gbdfxs
H3ZXoKLXjwjOLcSvLfVjNbF0QviZHBRsw8Y3usMvU/3geFDuSHXVFgf/Sww5rQMIE5oVyvVlib
eGgAe1H4c2Ymqw43q+XPvQe/bFnb0YWHXzXR/sVL3X6HUsCBvGqNAPE8vN/ieBw4wLK4CEapNE
lP8wBbBrwj4aMDmzWbnt8CNFJBBee/8CUxSDSaZyrF7xXQ==;
ARC-Authentication-Results: i=1; zsh.org;
iprev=pass (smtpq2.tb.ukmail.iss.as9143.net) smtp.remote-ip=212.54.57.97;
dkim=pass header.d=ntlworld.com header.s=meg.feb2017 header.a=rsa-sha256;
dmarc=pass header.from=ntlworld.com;
arc=none
ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed; d=zsh.org; s=rsa-20210803; t=1685701143;
bh=Rp9FHclBCZAJ+fgm7RrptGWN5T8OmoUYGnA+v2tLkLM=;
h=List-Archive:List-Owner:List-Post:List-Unsubscribe:List-Subscribe:List-Help:
List-Id:Sender:Content-Transfer-Encoding:Content-Type:MIME-Version:Subject:
References:In-Reply-To:Message-ID:To:From:Date:DKIM-Signature:
DKIM-Signature;
b=k1rnAvtGtl9Pyw7C9yM5tYIdub8LJPbfvdWFvvREbGK8aAu1lGKrRuyqPkm7QjEk0+pmja8GMX
8wbqRl7Gw931uz9ChmtvHX7ADkOrB+yqRORxTReARowW29XOi9WtyspELIKwhx4q+fLmIlmxjh
l1tCCf7ErbUSgvMK2NNqtzruPM5xe/XIT1W/QenjUhJnNYcU4ZLyOVe38YVjNMPnKTDaQhi/UH
nG9W/rNqSs2u9NIv4nGh8k0PAjzURIQcCbxMdS9Av1irx4gpk1lxW0SXYMeIS6Ohqi8UG9G9gx
+Fnsn/NFwjTWhh9+7AAa2nlv8iETuxxBs8uJG2DFYpgqWg==;
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=zsh.org;
s=rsa-20210803; h=List-Archive:List-Owner:List-Post:List-Unsubscribe:
List-Subscribe:List-Help:List-Id:Sender:Content-Transfer-Encoding:
Content-Type:MIME-Version:Subject:References:In-Reply-To:Message-ID:To:From:
Date:Reply-To:Cc:Content-ID:Content-Description:Resent-Date:Resent-From:
Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID;
bh=yKGyPS5WSp5GKxu9w4geCBu3MkWDVRjjaf76/54xTrk=; b=PVDLAFzqmlwEC9tZx/0FozIXk5
RUlgIpy2VqM/am488MIa+3M73OpACUIiLa6ZGv+7wMKHpND/3QrNGYmubzT1h3L1oAtII64fc7IJ1
IS2BDgn3scq/j+cQzltd8CM6JxE5YUx3o65XtT1iDPLsKOszPvGOpfknmBc85g8WL3Rh9Ov0NE3n1
UQ2YdaufKN3oI2pcSHBIjUxSb6gR6juOXUl+gxhWP3c1GQQ/54QqmeiqZwkpHZNBkjMvQoU0ZNXxD
rsGYK1rIpmiKil0YeDdLRQetLHiYt7hUTW3/n49V+r0qI7h5INdnPuolD0nPIy8qaNYdGKB2ciMiq
vq4WEgPA==;
Received: by zero.zsh.org with local
id 1q51s6-000BQz-2R;
Fri, 02 Jun 2023 10:19:02 +0000
Authentication-Results: zsh.org;
iprev=pass (smtpq2.tb.ukmail.iss.as9143.net) smtp.remote-ip=212.54.57.97;
dkim=pass header.d=ntlworld.com header.s=meg.feb2017 header.a=rsa-sha256;
dmarc=pass header.from=ntlworld.com;
arc=none
Received: from smtpq2.tb.ukmail.iss.as9143.net ([212.54.57.97]:37884)
by zero.zsh.org with esmtps (TLS1.2:ECDHE-RSA-AES256-GCM-SHA384:256)
id 1q51rj-000B79-2l;
Fri, 02 Jun 2023 10:18:41 +0000
Received: from [212.54.57.82] (helo=smtp3.tb.ukmail.iss.as9143.net)
by smtpq2.tb.ukmail.iss.as9143.net with esmtp (Exim 4.90_1)
(envelope-from
)
id 1q51ri-0002Ks-MR
for zsh-workers@zsh.org; Fri, 02 Jun 2023 12:18:38 +0200
Received: from oxbe12.tb.ukmail.iss.as9143.net ([172.25.160.143])
by smtp3.tb.ukmail.iss.as9143.net with ESMTP
id 51riqCucO9tPm51riqmPDi; Fri, 02 Jun 2023 12:18:38 +0200
X-Env-Mailfrom: p.w.stephenson@ntlworld.com
X-Env-Rcptto: zsh-workers@zsh.org
X-SourceIP: 172.25.160.143
X-CNFS-Analysis: v=2.4 cv=IPTESCjG c=1 sm=1 tr=0 ts=6479c1fe cx=a_exe
a=pVlFXI3Q25jgZXAaIqG4JA==:117 a=1DWFKdCB1IcA:10 a=IkcTkHD0fZMA:10
a=NLZqzBF-AAAA:8 a=N898d1J4AAAA:8 a=npldXguGAAAA:8 a=dkbBYixBL5i4UCKbo3MA:9
a=QEXdDO2ut3YA:10 a=1Z6EAcxPEhoA:10 a=Y6yEfkeh0FwA:10
a=75Kt_H3ikK-EkTT1woid:22 a=4OhKILdWXy8MGewZJRtY:22 a=1MEZn5qd6kv58cYvHi58:22
X-Authenticated-Sender: p.w.stephenson@ntlworld.com
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ntlworld.com;
s=meg.feb2017; t=1685701118;
bh=Rp9FHclBCZAJ+fgm7RrptGWN5T8OmoUYGnA+v2tLkLM=;
h=Date:From:To:In-Reply-To:References:Subject;
b=gocKgsy3d0I3GGOoJs77Wzc2HDcsIOV3UOamYt1AmG4NML8NQXGf9uGPM3doQptjj
KwfUrR7UxygN7PdUSlA4htanwuwfWl7sOd8wrlzRtEE6cqGOu/r4EnqPjnyr2wwvQs
u5HQdwJYSZVB6P7/k9NyHaUm1ECR7WK9E1VM1+cOXsTzhSn03EFKbKvX7rYrVwdwB1
qrTaRWLLq9T2vxs8bP21RKbaYjECvMwOZgBGSsE/ZnKp5e8DYKGgQHitwPVU70jdSt
tkfdXkMIvgCAqv59alyKL/xNuheJ0CCvo3mj6da+652AcA5oo5Rf8Z8pl3zP0Vm1iq
7nYuA9sUwh2tA==
Date: Fri, 2 Jun 2023 11:18:38 +0100 (BST)
From: Peter Stephenson
To: Zsh hackers list
Message-ID: <1068343689.5141130.1685701118603@mail.virginmedia.com>
In-Reply-To: <1452348325.5131636.1685695219291@mail.virginmedia.com>
References: <20230601183556.nl3zhv2kdxgj7x4d@chazelas.org>
<1452348325.5131636.1685695219291@mail.virginmedia.com>
Subject: Re: histsubstpattern in zmv
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 7bit
X-Priority: 3
Importance: Normal
X-Mailer: Open-Xchange Mailer
X-Originating-IP: 147.161.224.167
X-Originating-Client: open-xchange-appsuite
X-CMAE-Envelope: MS4xfM2xqojQACteQWoqKnio8mUREePoD4TSCdsKUZIas73N8ESBKVN1zOeFjIHORYpBpPEcxZfo1DTlOcdRZS7yjKvUCnlQgrUPbYGfbFT2UjcUoYCSS9o7
5s8Y98hP/CPyqXysf051+1unkeWUd6ArfR9IIsGcdjd7P5WCxIs3/B1tMI3SVNJbkBALPZjCs6bfhiKQu3YE8YD5VbJzcUVsy2V/88JNIzOudAiFEfqBMguR
X-Seq: 51816
Archived-At:
X-Loop: zsh-workers@zsh.org
Errors-To: zsh-workers-owner@zsh.org
Precedence: list
Precedence: bulk
Sender: zsh-workers-request@zsh.org
X-no-archive: yes
List-Id:
List-Help: ,
List-Subscribe: ,
List-Unsubscribe: ,
List-Post:
List-Owner:
List-Archive:
> On 02/06/2023 09:40 Peter Stephenson wrote:
> On 01/06/2023 19:35 Stephane Chazelas wrote:
> > The csh-style ${var:s/foo/bar} is often more legible and easy
> > to cumulate than the Korn-style equivalent ${var/foo/bar}
> >..
> > But that needs set -o histsubstpattern and in zmv, emulate -LR
> > zsh resets options.
> >
> > Would it be possibe to enable it in zmv along with extendedglob
> > which is already enabled there, or if not allow the user to enable it,
> > or maybe even better introduced some :+s/pattern/repl/
> > :-s/string/repl/ or :S/pattern/replacement/ so we can use both
> > at the same time, like ${f:gs/***/3-stars/:gS/???/any-3-chars} ?
>
> I can't see any good reason not to enable it.
Having said that, adding an :S variant isn't particularly difficult
and is more widely useful.
pws
diff --git a/Doc/Zsh/expn.yo b/Doc/Zsh/expn.yo
index 6f86d0c54..7bc736470 100644
--- a/Doc/Zsh/expn.yo
+++ b/Doc/Zsh/expn.yo
@@ -312,7 +312,8 @@ zero) that are neither `tt(.)' nor `tt(/)' and that continue to the end
of the string. For example, the extension of
`tt(foo.orig.c)' is `tt(.c)', and `tt(dir.c/foo)' has no extension.
)
-item(tt(s/)var(l)tt(/)var(r)[tt(/)])(
+xitem(tt(s/)var(l)tt(/)var(r)[tt(/)])
+item(tt(S/)var(l)tt(/)var(r)[tt(/)])(
Substitute var(r) for var(l) as described below.
The substitution is done only for the
first string that matches var(l). For arrays and for filename
@@ -324,13 +325,17 @@ perform global substitution, i.e. substitute every occurrence of var(r)
for var(l). Note that the tt(g) or tt(:G) must appear in exactly the
position shown.
+The use of tt(S) instead of tt(s) is identical except that
+the source is treated as a pattern, just as if the option
+tt(HIST_SUBST_PATTERN) were set.
+
See further notes on this form of substitution below.
)
item(tt(&))(
-Repeat the previous tt(s) substitution. Like tt(s), may be preceded
-immediately by a tt(g). In parameter expansion the tt(&) must appear
-inside braces, and in filename generation it must be quoted with a
-backslash.
+Repeat the previous tt(s) or tt(S) substitution, whichever was most
+recent. Like tt(s) and tt(S), may be preceded immediately by a tt(g).
+In parameter expansion the tt(&) must appear inside braces, and in
+filename generation it must be quoted with a backslash.
)
item(tt(t) [ var(digits) ])(
Remove all leading pathname components, leaving the final component (tail).
@@ -377,7 +382,8 @@ substitutions or expansions are performed once at the time the qualifier
is parsed, even before the `tt(:s)' expression itself is divided into
var(l) and var(r) sides.
-If the option tt(HIST_SUBST_PATTERN) is set, var(l) is treated as
+If the option tt(HIST_SUBST_PATTERN) is set or the original substitution
+was started with a capital tt(S), var(l) is treated as
a pattern of the usual form described in
ifzman(the section FILENAME GENERATION below)\
ifnzman(noderef(Filename Generation)). This can be used in
diff --git a/Src/hist.c b/Src/hist.c
index 7e6394406..b4dc53d90 100644
--- a/Src/hist.c
+++ b/Src/hist.c
@@ -163,6 +163,11 @@ char *hsubl;
/**/
char *hsubr;
+/* state of histsubstpattern at last substitution */
+
+/**/
+int hsubpatopt;
+
/* pointer into the history line */
/**/
@@ -624,7 +629,7 @@ histsubchar(int c)
return substfailed();
if (!hsubl)
return -1;
- if (subst(&sline, hsubl, hsubr, gbal))
+ if (subst(&sline, hsubl, hsubr, gbal, 0))
return substfailed();
} else {
/* Line doesn't begin ^foo^bar */
@@ -831,7 +836,7 @@ histsubchar(int c)
if ((c = ingetc()) == 'g') {
gbal = 1;
c = ingetc();
- if (c != 's' && c != '&') {
+ if (c != 's' && c != 'S' && c != '&') {
zerr("'s' or '&' modifier expected after 'g'");
return -1;
}
@@ -891,11 +896,13 @@ histsubchar(int c)
}
break;
case 's':
+ case 'S':
+ hsubpatopt = (c == 'S');
if (getsubsargs(sline, &gbal, &cflag))
return -1; /* fall through */
case '&':
if (hsubl && hsubr) {
- if (subst(&sline, hsubl, hsubr, gbal))
+ if (subst(&sline, hsubl, hsubr, gbal, hsubpatopt))
return substfailed();
} else {
herrflush();
@@ -2315,7 +2322,7 @@ casemodify(char *str, int how)
/**/
int
-subst(char **strptr, char *in, char *out, int gbal)
+subst(char **strptr, char *in, char *out, int gbal, int forcepat)
{
char *str = *strptr, *substcut, *sptr;
int off, inlen, outlen;
@@ -2323,7 +2330,7 @@ subst(char **strptr, char *in, char *out, int gbal)
if (!*in)
in = str, gbal = 0;
- if (isset(HISTSUBSTPATTERN)) {
+ if (isset(HISTSUBSTPATTERN) || forcepat) {
int fl = SUB_LONG|SUB_REST|SUB_RETFAIL;
char *oldin = in;
if (gbal)
diff --git a/Src/subst.c b/Src/subst.c
index 974d6171e..14947ae36 100644
--- a/Src/subst.c
+++ b/Src/subst.c
@@ -4351,6 +4351,8 @@ modify(char **str, char **ptr, int inbrace)
break;
case 's':
+ case 'S':
+ hsubpatopt = (**ptr == 'S');
c = **ptr;
(*ptr)++;
ptr1 = *ptr;
@@ -4445,7 +4447,7 @@ modify(char **str, char **ptr, int inbrace)
break;
case '&':
- c = 's';
+ c = hsubpatopt ? 'S' : 's';
break;
case 'g':
@@ -4534,8 +4536,10 @@ modify(char **str, char **ptr, int inbrace)
copy = casemodify(tt, CASMOD_UPPER);
break;
case 's':
+ case 'S':
+ hsubpatopt = (c == 'S');
if (hsubl && hsubr)
- subst(©, hsubl, hsubr, gbal);
+ subst(©, hsubl, hsubr, gbal, hsubpatopt);
break;
case 'q':
copy = quotestring(copy, QT_BACKSLASH_SHOWNULL);
@@ -4620,8 +4624,10 @@ modify(char **str, char **ptr, int inbrace)
*str = casemodify(*str, CASMOD_UPPER);
break;
case 's':
+ case 'S':
+ hsubpatopt = (c == 'S');
if (hsubl && hsubr)
- subst(str, hsubl, hsubr, gbal);
+ subst(str, hsubl, hsubr, gbal, hsubpatopt);
break;
case 'q':
*str = quotestring(*str, QT_BACKSLASH);
diff --git a/Test/D04parameter.ztst b/Test/D04parameter.ztst
index 7990c2958..2fd2f975f 100644
--- a/Test/D04parameter.ztst
+++ b/Test/D04parameter.ztst
@@ -2754,3 +2754,13 @@ F:behavior, see http://austingroupbugs.net/view.php?id=888
0:(users/28784 inspired this) substituting a single-quoted backslash, part #3: control
>xfooy
+ spacestring="string with spaces"
+ print ${spacestring:gs/[[:space:]]/ /}
+ print ${spacestring:g&}
+ print ${spacestring:gS/[[:space:]]//}
+ print ${spacestring:g&}
+0:Different behaviour of :s and :S modifiers
+>string with spaces
+>string with spaces
+>stringwithspaces
+>stringwithspaces