summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Stephenson <pws@users.sourceforge.net>2005-11-04 16:20:32 +0000
committerPeter Stephenson <pws@users.sourceforge.net>2005-11-04 16:20:32 +0000
commit325f9c5deadd85d75860ca53b213961497d9e3c7 (patch)
tree32f3864c4da74549a6feffbc08db6aaa49133de5
parent0acbed6ab03d41391175baa10d16cd35cc5bf140 (diff)
downloadzsh-325f9c5deadd85d75860ca53b213961497d9e3c7.tar.gz
zsh-325f9c5deadd85d75860ca53b213961497d9e3c7.zip
users/9618, modified: :G for global substution modifier
-rw-r--r--ChangeLog6
-rw-r--r--Doc/Zsh/expn.yo10
-rw-r--r--Src/hist.c40
3 files changed, 48 insertions, 8 deletions
diff --git a/ChangeLog b/ChangeLog
index 3029a8824..cc42ba072 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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
diff --git a/Doc/Zsh/expn.yo b/Doc/Zsh/expn.yo
index c05796a94..b8aa1cfd8 100644
--- a/Doc/Zsh/expn.yo
+++ b/Doc/Zsh/expn.yo
@@ -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
diff --git a/Src/hist.c b/Src/hist.c
index 00773cd74..90e97313e 100644
--- a/Src/hist.c
+++ b/Src/hist.c
@@ -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)