I have been working on my zsh configs (Github Repo) and came across a pretty useful snippet:
1
2
3
4
5
6
7
8
9
10
11
12
13
function rationalize_dot {
local MATCH
if [[ $LBUFFER =~ '(^|/| | |'$'\n''|\||;|&)\.\.$' ]]; then
LBUFFER+=/
zle self-insert
zle self-insert
else
zle self-insert
fi
}
zle -N rationalize_dot
bindkey . rationalize_dot
bindkey -M isearch . self-insert
What’s happening in this code is, first, the definition of a function
rationalize_dot
that scans the current command buffer
($LBUFFER
to see if it ends with ..
. If it does, it will add a /
and then insert the character typed twice (this will make more sense in a moment).
If the $LBUFFER
does not end with ..
, the character typed is only inserted once.
After the function definition is the integration with ZLE. The zle -N
rationalize_dot
call registers the created function as a valid ZLE key
action. Then the following line binds the created function to execute
whenever a .
is typed and the following disables this binding when in search mode.
So now what does this stuff do? When traversing your file tree, you can now type
...
and it will expand as ../..
and each subsequent .
typed will expand as
another level up the tree. This has been very useful in my day to day usage of
the shell. With this inserting works as desired, but what if I have done one too
many .
s ? So I wrote an unrationalize_dot
ZLE function to perform the opposite
action as rationalize_dot
. (Tools that are extendable via programming are so
awesome). So what I ended up with:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function unrationalize_dot {
local MATCH # keep regex match from leaking into the environment
if [[ $LBUFFER =~ '(^|/| | |'$'\n''|\||;|&)\.\.$' ]]; then
zle backward-delete-char
zle backward-delete-char
if [[ $MATCH =~ '^/' ]]; then
zle backward-delete-char
fi
else
zle backward-delete-char
fi
}
zle -N unrationalize_dot
bindkey "^h" unrationalize_dot
bindkey "^?" unrationalize_dot
This does basically the same as the other, except it will use
backward-delete-char
instead of self-insert
and will delete
one more character if there is a leading /
in the buffer (so ..
removes both and ../..
becomes just ..
). The keys bound to are ^h
and ^?
, one is for ‘Delete’ and the other ‘Backspace’.
So just a little snippet to power up some of my development tools!