9

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.

migrated from stackoverflow.com May 6 '14 at 21:56

This question came from our site for professional and enthusiast programmers.

  • 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 '16 at 8:24
3

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.

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

  • 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. – Erik Nomitch May 7 '14 at 18:06
1

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.