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

Re: Neat hash -d trick



I use this too:

rationalise-dot() {
  if [[ $LBUFFER = *.. ]]; then
    LBUFFER+=/..
  else
    LBUFFER+=.
  fi
}
zle -N rationalise-dot
bindkey . rationalise-dot

2010/10/22 Mikael Magnusson <mikachu@xxxxxxxxx>

> On 22 October 2010 06:05, Bart Schaefer <schaefer@xxxxxxxxxxxxxxxx> wrote:
> > [Aside to -workers:  This reminds me about Mikael Magnusson's thread
> > for his proposed HASH_LOOKUP option, which sort of died out without
> > resolution after a discussion of findcmd() behaving oddly.]
>
> [I'm still meaning to look into that, it's just that hacking on zsh C
> code requires a pretty rare set of circumstances, being both pretty
> bored, but also in a very optimistic mood. :)]
>
> > On Oct 22, 12:34am, Nikolai Weibull wrote:
> > }
> > } for ((i = 1; i < 9; i++)); do
> >
> > You probably mean <= 9 there?  Or just
> >
> >  for i in {1..9}
> >
> > }   hash -d .$i=${(j:/:)${(l:2::.:)${(s::)${(l:i::.:)}}}}
> >
> >    hash -d .$i=${${(l:i*3::../:)}%/}
> >
> > } done
> > }
> > } cd ~.4/dir
> >
> > A generic word of caution about using "hash -d": if you for any reason
> > change the value of $PATH or $path after this, all your custom hash
> > entries are lost when the table is rebuilt for the new searchpath.
>
> Hmm? Doesn't seem to happen for me.
>
> > A similar trick:
> >
> >    dotdot() {
> >      if (( NUMERIC > 0 ))
> >      then LBUFFER+=..; repeat $((NUMERIC-1)) LBUFFER+=/..
> >      else LBUFFER+=.
> >      fi
> >    }
> >    zle -N dotdot
> >    bindkey . dotdot
> >
> > Now you can type ESC 4 . to insert ../../../.. (or ESC 9 ESC 9 . to
> > insert 99 levels, if for some insane reason you need that many).
>
> Doing this actually causes you to be unable to type dots in an isearch
> widget, since it aborts on custom bindings. I think pws is partly
> responsible for this
> # just type '...' to get '../..'
> rationalise-dot() {
> local MATCH
> if [[ $LBUFFER =~ '(^|/| |      |'$'\n''|\||;|&)\.\.$' ]]; then
>  LBUFFER+=/
>  zle self-insert
>  zle self-insert
> else
>  zle self-insert
> fi
> }
> zle -N rationalise-dot
> bindkey . rationalise-dot
> # without this, typing a . aborts incremental history search
> bindkey -M isearch . self-insert
>
> You only need the last line to avoid the problem of course.
>
> > } What would be even sweeter is if someone would come up with a way to
> > } do this with only one call to hash -d without writing out all the
> > } expansions
> >
> > Because the counter has to be referenced twice in the expansion, I
> > don't think there's any way of avoiding the "for" loop that's worth
> > the effort to figure out.  However,
> >
> >    for i in {1..9}; h+=(.$i=${${(l:i*3::../:)}%/}); hash -d $h
> >
> > Or to avoid leaving $i and $h with a value at the end,
> >
> >    hash -d $( for i in {1..9}; print .$i=${${(l:i*3::../:)}%/} )
>
> To avoid leaving $i and $h with a value and a fork ;)
> % () {local i h; for i in {1..9}; h+=(.$i=${${(l:i*3::../:)}%/}); hash -d
> $h}
> % path+=/tmp
> % path[2]=()
> % hash -d|head -1
> .1=..
>
> I also have a vaguely related custom widget, in case you're unsure
> just how many dotdots you need.
>
> function _showcurrargrealpath() {
>  setopt localoptions nonomatch
>  local REPLY REALPATH
>  _split_shell_arguments_under
>  #zle -M "$(realpath ${(Q)${~REPLY}} 2> /dev/null | head -n1 || echo
> 1>&2 "No such path")"
>  REALPATH=( ${(Q)${~REPLY}}(N:A) )
>  zle -M "${REALPATH:-Path not found: $REPLY}"
> }
> zle -N _showcurrargrealpath
> bindkey "^X." _showcurrargrealpath
>
> # which i now notice in turn relies on this bit:
> autoload -U modify-current-argument
> autoload -U split-shell-arguments
>
> function _split_shell_arguments_under()
> {
>  local -a reply
>  integer REPLY2
>  split-shell-arguments
>  #have to duplicate some of modify-current-argument to get the word
>  #_under_ the cursor, not after.
>  setopt localoptions noksharrays multibyte
>  if (( REPLY > 1 )); then
>    if (( REPLY & 1 )); then
>      (( REPLY-- ))
>    fi
>  fi
>  REPLY=${reply[$REPLY]}
> }
>
> I also noticed now that if you mistype a named dir and run that
> widget, the whole command line aborted due to the failed $~ expansion,
> not sure why it would do that. That's why I added the setopt nonomatch
> just now, it'll print the original path with (:A) appended as if it
> succeeds but at least better than eating the command line.
>
> [aside to -workers: would it make sense if ~ also checked for
> nullglob? i noticed in the code that it checks for nomatch only
> (merely looking at zsh C code is possible more often than editing it).
> not sure how many different bits use that same function to expand
> stuff though.]
>
> --
> Mikael Magnusson
>


Messages sorted by: Reverse Date, Date, Thread, Author