1

I'm trying to set up a zsh function that will take me back to the top level git directory with an optional argument to move relative to that directory. I've currently got this which works:

alias gitdir='git rev-parse --show-toplevel'
cdgit() { cd $(gitdir)/$1 }

The issue is, tab completion doesn't work properly, it will autocomplete from whatever directory I'm in when I run cdgit, but I want it to complete from $(gitdir). If I type the following line before running cdgit, the completion will work correctly (from $(gitdir)):

compctl -W $(gitdir) -/ cdgit

However, I don't want to type that command every time before I type cdgit just to get tab completion. Is there any way that I can make a completion function for cdgit that will somehow run that command so my completion is correct?

  • Why the downvote? – Josh Sherick Jun 13 '16 at 14:42
  • Why don't you want to stick with the compctl solution? This can go to the rc file where you define the cdgit function, can't it?! – mpy Jun 14 '16 at 18:58
  • 1
    No, because I don't want it to run when my shell starts. That would change the directory that cdgit <path> completes to to whatever $(gitdir) evaluated to at the time that my .zshrc was run. However, I want it to autocomplete to whatever $(gitdir) evaluates to at the time that I type cdgit <path>. So I want to type cdgit and press tab and get completion from where it would cd me to, which might not be the same place as when the shell was started. – Josh Sherick Jun 14 '16 at 20:00
  • It could potentially run on every directory change, I guess. Not the cleanest solution but it's a quick command. – Josh Sherick Jun 14 '16 at 20:01
  • Of course, my bad not realizing that $(gitdir) will be static then. See my answer for a suggestion. – mpy Jun 15 '16 at 16:46
2

I'd suggest to write a completion function for your cdgit function.

Put this file named _cdgit into a directory which is in your $fpath, e.g. /usr/share/zsh/site-functions, then start a new shell instance:

#compdef cdgit

local expl
local ret=1

[[ CURRENT -eq 2 ]] && _wanted directories expl 'git toplevel directory' \
    _path_files -/ -W $(git rev-parse --show-toplevel) && ret=0

return ret

This is borrowed from one of the last lines in the _cd completion function itself, which is of course much more complex.

Demo:

/usr/src/linux-git/Documentation/x86> cd [TAB]
local directory
i386/    x86_64/

/usr/src/linux-git/Documentation/x86> cdgit [TAB]
git toplevel directory
Documentation/  crypto/         include/        lib/            scripts/        usr/                          
arch/           drivers/        init/           mm/             security/       virt/                         
block/          firmware/       ipc/            net/            sound/                                      
certs/          fs/             kernel/         samples/        tools/                                      

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.