Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: doing regex on history

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
       return 0
   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
     return 0
   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