users/9618, modified: :G for global substution modifier

This commit is contained in:
Peter Stephenson 2005-11-04 16:20:32 +00:00
parent 0acbed6ab0
commit 325f9c5dea
3 changed files with 48 additions and 8 deletions

View File

@ -1,3 +1,9 @@
2005-11-04 Peter Stephenson <pws@csr.com>
* users/9618 modified as suggested in users/9621: Doc/Zsh/expn.yo,
Src/hist.c: extend history subsitution to allow trailing :G for
global.
2005-11-02 Andrey Borzenkov <bor@zsh.org>
* 21978: Src/Modules/stat.c: unmetafy file name before calling

View File

@ -117,6 +117,8 @@ repeats the last command, replacing the string var(foo) with var(bar).
More precisely, the sequence `tt(^)var(foo)tt(^)var(bar)tt(^)' is
synonymous with `tt(!!:s)tt(^)var(foo)tt(^)var(bar)tt(^)', hence other
modifiers (see noderef(Modifiers)) may follow the final `tt(^)'.
In particular, `tt(^)var(foo)tt(^)var(bar)tt(:G)' performs a global
substitution.
If the shell encounters the character sequence `tt(!")'
in the input, the history mechanism is temporarily disabled until
@ -254,10 +256,14 @@ Convert the words to all uppercase.
)
item(tt(s/)var(l)tt(/)var(r)[tt(/)])(
Substitute var(r) for var(l) as described below.
Unless preceded immediately by a tt(g), with no colon between,
the substitution is done only for the
The substitution is done only for the
first string that matches var(l). For arrays and for filename
generation, this applies to each word of the expanded text.
The forms `tt(gs/)var(l)tt(/)var(r)' and `tt(s/)var(l)tt(/)var(r)tt(/:G)'
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.
)
item(tt(&))(
Repeat the previous tt(s) substitution. Like tt(s), may be preceded

View File

@ -295,13 +295,24 @@ herrflush(void)
hwaddc(ingetc());
}
/* extract :s/foo/bar/ delimiters and arguments */
/*
* Extract :s/foo/bar/ delimiters and arguments
*
* The first character expected is the first delimiter.
* The arguments are stored in the hsubl and hsubr variables.
*
* subline is the part of the command line to be matched.
*
* If a ':' was found but was not followed by a 'G',
* *cflagp is set to 1 and the input is backed up to the
* character following the colon.
*/
/**/
static int
getsubsargs(char *subline)
getsubsargs(char *subline, int *gbalp, int *cflagp)
{
int del;
int del, follow;
char *ptr1, *ptr2;
del = ingetc();
@ -315,6 +326,17 @@ getsubsargs(char *subline)
}
zsfree(hsubr);
hsubr = ptr2;
follow = ingetc();
if (follow == ':') {
follow = ingetc();
if (follow == 'G')
*gbalp = 1;
else {
inungetc(follow);
*cflagp = 1;
}
} else
inungetc(follow);
if (hsubl && !strstr(subline, hsubl)) {
herrflush();
zerr("substitution failed", NULL, 0);
@ -348,14 +370,16 @@ histsubchar(int c)
/* look, no goto's */
if (isfirstch && c == hatchar) {
int gbal = 0;
/* Line begins ^foo^bar */
isfirstch = 0;
inungetc(hatchar);
if (!(ehist = gethist(defev))
|| !(sline = getargs(ehist, 0, getargc(ehist)))
|| getsubsargs(sline) || !hsubl)
|| getsubsargs(sline, &gbal, &cflag) || !hsubl)
return -1;
subst(&sline, hsubl, hsubr, 0);
subst(&sline, hsubl, hsubr, gbal);
} else {
/* Line doesn't begin ^foo^bar */
if (c != ' ')
@ -543,6 +567,10 @@ histsubchar(int c)
if ((c = ingetc()) == 'g') {
gbal = 1;
c = ingetc();
if (c != 's' && c != '&') {
zerr("'s' or '&' modifier expected after 'g'", NULL, 0);
return -1;
}
}
switch (c) {
case 'p':
@ -577,7 +605,7 @@ histsubchar(int c)
}
break;
case 's':
if (getsubsargs(sline))
if (getsubsargs(sline, &gbal, &cflag))
return -1; /* fall through */
case '&':
if (hsubl && hsubr)