All shells understand these commands:
$ cd .
$ cd ..
And zsh will also understand:
$ cd ...
$ cd ....
Provided you say:
$ alias -g ...='../..'
$ alias -g ....='../../..'
Now, how can I make it do proper tab-completion when I've started typing cd ..../<TAB>
? I recall it was implemented in oh-my-zsh but I've stopped using it now.
It would also be appreciated if it would work not only for cd
, say I want to execute cat ..../a/b/..../c/d | less
.
What I did to to deal with the same problem is to just let zsh fill in ../..
when I type ...
and it makes sense to expand it in that way. It may suit you (or not :-P):
if is-at-least 5.0.0 && [[ ! $UID -eq 0 ]]; then
## http://www.zsh.org/mla/users/2010/msg00769.html
function rationalise-dot() {
local MATCH # keep the regex match from leaking to the environment
if [[ $LBUFFER =~ '(^|/| | |'$'\n''|\||;|&)\.\.$' && ! $LBUFFER = p4* ]]; then
#if [[ ! $LBUFFER = p4* && $LBUFFER = *.. ]]; then
LBUFFER+=/..
else
zle self-insert
fi
}
zle -N rationalise-dot
bindkey . rationalise-dot
bindkey -M isearch . self-insert
fi
I also have an alias for ...
, but it is not global.
Notice I check if the command line starts with p4
(the Perforce command line tool) and do not mess with it in that case, as Perforce arguments often involve literal ...
. If you do not use p4
you can obviously remove that check.
I wasn't happy with the other answers so I spent a bit of time getting something more to my liking. The following will expand the dots when you hit ↵ (return) or ↹ (tab), not as you type the dots.
function expand-dots() {
local MATCH
if [[ $LBUFFER =~ '\.\.\.+' ]]; then
LBUFFER=$LBUFFER:fs%\.\.\.%../..%
fi
}
function expand-dots-then-expand-or-complete() {
zle expand-dots
zle expand-or-complete
}
function expand-dots-then-accept-line() {
zle expand-dots
zle accept-line
}
zle -N expand-dots
zle -N expand-dots-then-expand-or-complete
zle -N expand-dots-then-accept-line
bindkey '^I' expand-dots-then-expand-or-complete
bindkey '^M' expand-dots-then-accept-line
A good option is manydots-magic, which expands ...
into ../..
, etc. but does it intelligently. See the link above for more details, but briefly:
- It allows you to revert the expansion with a single Backspace (if it were the last thing you typed).
- But it won't revert explicitly typed
../..
- You can use it inline, e.g.
cd a/b/..../y/z
.
- Nevertheless, it won't expand when it doesn't make sense, e.g.
git log branch...
- It will expand when it might make sense, but revert when you type more. e.g.
git diff ...
-> git diff ../..
git diff ...b
-> git diff ...b
(for git diff ...branch
)
You have to use compinit
and use _expand_alias
as completer. Here is an example:
zstyle ':completion:*' completer _complete _ignored _expand_alias
autoload -Uz compinit
compinit
_complete _ignored
is the default setting for completer
, you could set it to only _expand_alias
but then completion would only work for aliases.
If compinit
is already configured in your ~/.zshrc
, then you just need to add _expand_alias
into the list for completer
, for example:
zstyle ':completion:*' completer _expand _complete _ignored _approximate _expand_alias
By default _expand_alias
expands global and and regular aliases, if you do not want to expand regular aliases, set:
zstyle ':completion:*' regular false
Note: This of course works only, where global aliases would work. So they would not be expanded as part of an entire path like a/b/..../c/d