Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Re: doing regex on history
- X-seq: zsh-users 7669
- From: Bart Schaefer <schaefer@xxxxxxxxxxxxxxxx>
- To: zsh-users@xxxxxxxxxx
- Subject: Re: doing regex on history
- Date: Thu, 8 Jul 2004 00:40:40 -0700 (PDT)
- In-reply-to: <1089253050.30333.5.camel@tp>
- Mailing-list: contact zsh-users-help@xxxxxxxxxx; run by ezmlm
- References: <1089253050.30333.5.camel@tp>
- Reply-to: zsh-users@xxxxxxxxxx
On Wed, 8 Jul 2004, damon wrote:
> I am after help to enable/use? regex on the history (using vi)
By "using vi" I assume you mean that you're using ZLE in vi emulation
mode, and that the vi-history-search-{forward,backward} widgets are
therefore of interest.
There's no direct support for regular expressions in history search,
in vi emulation or otherwise. ZLE's vi emulation can be though of as
operating as if ":se nomagic" is always in effect.
If you have e.g. the PCRE library available and have built the zsh/pcre
module, you can write your own widgets that do the searching. This gets
pretty tricky as there is no way to override the searching part of the
builtin vi-history-* widgets without also overriding the read-the-pattern
part, but fortunately there's a read-from-minibuffer function supplied in
the zsh distribution. So you might do:
autoload -U read-from-minibuffer
vi-history-re-search-backward() {
zmodload -i zsh/pcre || return 1
local REPLY event
read-from-minibuffer "?"
[[ -z $REPLY ]] && return 0
history -n -r 0 | while read event; do
if [[ $event -pcre-match $REPLY ]]; then
BUFFER=$event
return 0
fi
done
return 1
}
If you don't have pcre, you can settle for glob patterns, which (if you
setopt EXTENDED_GLOB) can be regex-equivalent but do not use compatible
syntax. In that case it's even easier:
vi-history-glob-search-backward() {
local event
read-from-minibuffer '?'
[[ -z $REPLY ]] && return 0
if history -n -r -m \*$REPLY\* 0 | read event; then
BUFFER=$event
return 0
fi
return 1
}
Left as excercises are to use the zsh/parameter module's $history hash
instead of forking off "history -r 0" (and, can you find a bug in my
example that would fixed by using the hash?), and then extending that to
remember where you last found a match and to begin again from there the
next time.
Oh, and for more fun, try doing it with an incremental search, which needs
a loop around "read-from-minibuffer -k 1" with a call to "zle -R", plus
some special handling for backspace, return, etc.
Messages sorted by:
Reverse Date,
Date,
Thread,
Author