6

Is it possible to configure zsh to expand global aliases during tab completion? For example, I have the common aliases:

alias -g '...'='../..'
alias -g '....'='../../..'

but when I type, for example, cd .../some<tab> it won't expand to cd .../something or cd ../../something. Consequently, I frequently won't use these handy aliases because they are incompatible with tab completion.

Bryan Ward
  • 6,443
  • 8
  • 37
  • 48
  • 2
    Look in `man zshcompsys` and search for "_expand_alias". Sorry, I haven't had a chance to learn zsh completion in depth. You also might try asking on unix.stackexchange.com. – Dennis Williamson Jan 19 '11 at 20:22

2 Answers2

10

I'm a user of Mikael Magnusson's rationalise-dot. From my zshrc:

# This was written entirely by Mikael Magnusson (Mikachu)
# Basically type '...' to get '../..' with successive .'s adding /..
function rationalise-dot {
    local MATCH # keep the regex match from leaking to the environment
    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
fow
  • 556
  • 3
  • 6
  • 1
    This is very interesting, and sort of solves the example case, but doesn't solve the general case. (I say "sort of" because it doesn't wait until you hit `` to expand from `...` to `../..`.) – iconoclast Sep 22 '11 at 19:51
6

Try looking up zsh abbreviations. They allow you to enter an "abbreviation" which automatically gets replaced with its full form when you hit a magic key such as space. So you can create one which changes ...<SPACE> to ../...

For example, this is what you need in your profile:

typeset -A abbrevs
abbrevs=(
        "..." "../.."
        "...." "../../.."        
)

#create aliases for the abbrevs too
for abbr in ${(k)abbrevs}; do
   alias -g $abbr="${abbrevs[$abbr]}"
done

my-expand-abbrev() {
    local MATCH
    LBUFFER=${LBUFFER%%(#m)[_a-zA-Z0-9]#}
    LBUFFER+=${abbrevs[$MATCH]:-$MATCH}
    zle self-insert
}

bindkey " " my-expand-abbrev 
dogbane
  • 266,786
  • 75
  • 396
  • 414
  • 5
    For that matter, you can just type `...` and press `Ctrl-X a` using only normal `alias -g` aliases. – Dennis Williamson Jan 20 '11 at 01:01
  • @Dennis: can `` be made to do *both* do its normal completion *and* `_expand_alias` (`Ctrl-X a`)? If so, wouldn't that solve the problem as it is stated in the question? – iconoclast Sep 22 '11 at 19:59
  • 3
    @dogbane: This gives me "No such widget `my-expand-abbrev'" in zsh 4.3.10 – iconoclast Sep 22 '11 at 20:08
  • 1
    @iconoclast It looks like you need to add `zle -N my-expand-abbrev` before the `bindkey` now. – Eric Boehs Jul 15 '15 at 20:06
  • @EricBoehs: that prevents the error message, but it doesn't make the expansion take place. (`Ctrl-X a` does, though.) I'm now on zsh 5.0.2, if that changes anything. – iconoclast Jul 16 '15 at 02:12
  • 2
    Perhaps you're missing something. I have my full working set up here: https://github.com/ericboehs/dotfiles/blob/master/.zsh/abbreviations.zsh. It's probably the extended globs. – Eric Boehs Jul 17 '15 at 02:20