diff options
author | Peter Stephenson <p.stephenson@samsung.com> | 2023-06-06 09:16:46 +0100 |
---|---|---|
committer | Peter Stephenson <p.stephenson@samsung.com> | 2023-06-06 09:16:46 +0100 |
commit | 78102120b9c9e7485e7f537864fc2c24fbe0071a (patch) | |
tree | 48811d8ad11f2a086e9150d8a7b6f20debb79d90 | |
parent | 63400fdbc5b8ce639a885629e4b1087b4277691d (diff) | |
download | zsh-78102120b9c9e7485e7f537864fc2c24fbe0071a.tar.gz zsh-78102120b9c9e7485e7f537864fc2c24fbe0071a.tar.xz zsh-78102120b9c9e7485e7f537864fc2c24fbe0071a.zip |
51816: add :S history modifier with pattern match
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | Doc/Zsh/expn.yo | 18 | ||||
-rw-r--r-- | Src/hist.c | 17 | ||||
-rw-r--r-- | Src/subst.c | 12 | ||||
-rw-r--r-- | Test/D04parameter.ztst | 10 |
5 files changed, 49 insertions, 14 deletions
diff --git a/ChangeLog b/ChangeLog index 2c0f6287a..c760fccab 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2023-06-06 Peter Stephenson <p.stephenson@samsung.com> + + * 51816: Doc/Zsh/expn.yo, Src/hist.c, Src/subst.c, + Test/D04parameter.ztst: add :S history modifier with pattern + match. + 2023-06-06 Jun-ichi Takimoto <takimoto-j@kba.biglobe.ne.jp> * Marlon Richert: 51779: Test/Y01completion.ztst: update 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 |