Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Re: Feature request: #a (approximate matching) only for spaces
On Dec 7, 5:44am, Mikael Magnusson wrote:
}
} % print -l ${~s//(#b)(?)/$match[1]*} # make the pattern g*i*t*p*u*r*g*e*
Yeah, but that also matches gfooifootfooifoopfooufoorfoogfooefoo, which
I'm not sure is what Sebastian wants. The pattern
(g*tpurge|gi*tpurge|git*purge|gitp*urge|gitpu*rge|gitpur*ge|gitpurg*e)*
is probably closer to what he wants, but it's a bit ugly to generate a
pattern like that:
setopt histsubstpattern extendedglob
s="gitpurge" # string is $#s chars long
a=( ( "${(@)${(s::)s}/?/}" ) # array of $#s empty elements
x=( ${s:^^a} ) # array of $#s copies of $s
i=1
p=( ${x:s/(#b)(#s)(?(#c$[i++]))/$match[1]*} ) # $#s patterns
print -lr - (${(j:|:)~p})* # join and enable matching
Amazingly, you can write that as a one-liner, if you don't count the
necessity of the setopts and declaring the parameters:
(${(j:|:)~${i::=1}+${${:-$INPUT"${(@)^${(s::)INPUT}/?/}"}:s/(#b)(#s)(?(#c$[i++]))/$match[1]*}})*
I renamed $s to $INPUT to make it easier to pick out from the rest of
the chicken scratching.
Breaking that down ...
1. ${i::=1} forces $i to reset to 1 before the rest of this expands.
2. The "+" after that says that if $i is set, substitute what follows
instead. Since we just forced $i to be set, this always happens.
3. ${:-words} inserts those words as a nested expansion where they
otherwise would be a parse error.
4. "${(@)^${(s::)INPUT}/?/}" forms an array of $#INPUT empty elements
and also turns on rc_expand_param [the caret after (@)].
5. Juxtaposing (4) with $INPUT results in $#INPUT copies of $INPUT
as an array for the rest of the substitution to act upon.
6. The :s// expression applies to that array such that $[i++] is
evaluated for each element. This is unlike ${..//pat/rep} which
evaluates pat only once, and thus why we need hist_subst_pattern.
7. Hence (?(#c$[i++])) matches $i characters at array index $i, and
we front-anchor that with (#s) and grab a reference to it with
(#b), then use it in the replacement as $match[1].
8. Then (j:|:) combines the resulting $#INPUT patterns and ~ makes
active both the | and the * inserted by :s/.../$match[1]* so the
whole expansion becomes a single pattern.
Theoretically it should work to use this pattern as a subscript of the
$history associative array with the (r) or (R) subscript flags to find
all matching history events.
--
Barton E. Schaefer
Messages sorted by:
Reverse Date,
Date,
Thread,
Author