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 > On 22 October 2010 06:05, Bart Schaefer 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 >