2

I have the following lines in my ~/.aliases:

function __function_exists() {
    declare -f -F $1 > /dev/null
    return $?
}

# git aliases (need to have git bash completion installed)
for al in `__git_aliases`; do
    alias g$al="git $al"

    complete_func=_git_$(__git_aliased_command $al)
    __function_exists $complete_fnc && __git_complete g$al $complete_func
done

And in my ~/.gitconfig i have:

[alias]
    # one-line log
    l = log --pretty=format:"%C(yellow)%h\\ %ad%Cred%d\\ %Creset%s%Cblue\\ [%cn]" --decorate --date=short

    a = add
    ap = add -p
    c = commit --verbose
    ca = commit -a --verbose
    cm = commit -m
    cam = commit -a -m
    m = commit --amend --verbose

    d = diff
    ds = diff --stat
    dc = diff --cached

    s = status -s
    co = checkout
    cob = checkout -b
    # list branches sorted by last modified
    b = "!git for-each-ref --sort='-authordate' --format='%(authordate)%09%(objectname:short)%09%(refname)' refs/heads | sed -e 's-refs/heads/--'"

    # list aliases
    la = "!git config -l | grep alias | cut -c 7-"

And in my ~/.zshrc:

zstyle :compinstall filename '/home/giuliani/.zshrc'
autoload -Uz compinit
compinit
[[ -f $HOME/.aliases ]] && source "$HOME/.aliases"

So, for each alias in my gitconfig i will define a shell alias like gl for git log and so on.

Trying to port this to zsh i'm having a problem: zsh autoload built-in only loads the file /usr/share/zsh/functions/Completion/Unix/_git the first time i try to complete some git command.

I've tried to call/load _git file directly from the .zshrc but other them a few warnings, it didn't work.

What is the proper way to have the same funcionality that i have in bash, using zsh ?

1 Answer 1

2

Actually, calling _git from your .zshrc does work, in that it defines _git and its companion functions including __git_aliases, and it tries to do some completion but fails (without even an error message in this particular case). This works with most completion functions. You need to do this after compinit so that _git and its auxiliary functions are marked for autoloading.

% zsh -f
darkstar% autoload compinit          
darkstar% compinit
darkstar% _git 
darkstar% __git_aliases 
_tags:comptags:36: can only be called from completion function
_tags:comptry:55: can only be called from completion function
_tags:comptags:60: can only be called from completion function
_tags:comptags:67: can only be called from completion function

The problem is that when you run __git_aliases, it calls builtins that can only be used while doing completion. You can work around that by temporarily defining functions with the same name as these builtins that do just the part that you want to do, which is often nothing, but it is very clumsy. I'm not going to show how because there's a much simpler way in this particular case.

Since you're diving deep into the _git completion file anyway, call __git_extract_aliases instead of __git_aliases. __git_extract_aliases stuffs information into the variable aliases in a way that's easy to extract. (Note: I wrote this answer for zsh 5.4.2, which is the version on Ubuntu 18.04. Other versions of zsh may have different structure in _git.)

_git 2>/dev/null
define_git_aliases () {
  local -a aliases; local al
  __git_extract_aliases
  for al in ${aliases%%:*}; do
    alias g$al="git $al"
  done
}
define_git_aliases

That's still a lot more effort that necessary, and potentially extra porting effort to cope with different versions of zsh. __git_extract_aliases is basically one line of code.

for al in ${${${(0)"$(git config -z --get-regexp '^alias.')"}%%$'\n'*}#alias.}; do
  alias g$al="git $al"
done
2
  • Thank you very much. I used the second example. The one using _git and __git_extract_aliases didn't work, and I must admit that it took me a while to see the little typo in the variable names (alias and al). Commented Jun 12, 2019 at 2:51
  • I gave another shot to the first example it worked! (variable names again, but now it was my mistake). Thank you again! Commented Jun 12, 2019 at 2:56

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .