11

I have a custom Zsh function g:

function g() {
  # Handle arguments [...]
}

Within it, I handle short arguments that execute Git commands. For example:

g ls # Executes git ls-files ...
g g  # Executes git grep ...

I need to be able to set the autocompletion rules to Git's rules for the short arguments but I am unsure of how to do this.

For example, I need g ls <TAB> to tab-complete the rules for git ls-files <TAB> which would give me the arguments for git ls-files:

$ g ls --<TAB>
--abbrev                 -- set minimum SHA1 display-length
--cached                 -- show cached files in output
--deleted                -- show deleted files in output
# Etc...

This is not simply setting g to autocomplete for git since I'm mapping my custom short commands to the Git commands.

1
  • 1
    If your function only maps shorter names to git subcommands you can also use the git alias system for this. Read about it in the mapage: man git-config.
    – Lucas
    Apr 18, 2016 at 8:24

3 Answers 3

5

I found /usr/share/zsh/functions/Completion/Unix/_git which had some tips for aliases like this and ended up defining these functions for the aliases:

_git-ls () {
  # Just return the _git-ls-files autocomplete function
  _git-ls-files
}

Then, I did a straight compdef g=git. The autocomplete system will see that you are running, for example, g ls and use the _git-ls autocomplete function.

Thanks to user67060 for steering me in the right direction.

2

I had to do something very similar so this is roughly what should solve your problem.

_g () {
    case "${words[2]}" in
      ls) words[1,2]=(git ls-files);;
      g) words[1,2]=(git grep);;
      *) return 1;;
    esac

    _git # Delegate to completion
}
compdef _g g

One thing to note is that if you change the number of arguments you will need to adjust the $CURRENT variable.

1

This is what I would do:

_tg () {
    local _ret=1
    local cur cword prev

    cur=${words[CURRENT]}
    prev=${words[CURRENT-1]}
    cmd=${words[2]}
    let cword=CURRENT-1

    case "$cmd" in
    ls)
        emulate ksh -c _git_ls_files
        ;;
    g)
        emulate ksh -c _git_grep
        ;;
    esac

    let _ret && _default && _ret=0
    return _ret
}

compdef _tg tg

However, this is using Git's completion, not zsh's completion:

https://git.kernel.org/cgit/git/git.git/tree/contrib/completion/git-completion.zsh

1
  • Thanks, I ended up going a different route since I didn't know where to find the Git completion rules and was getting errors. See my answer. May 7, 2014 at 18:06

You must log in to answer this question.

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