New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

zsh completion is semi-broken #231

Closed
teoljungberg opened this Issue Sep 8, 2012 · 70 comments

Comments

Projects
None yet
@teoljungberg
Copy link

teoljungberg commented Sep 8, 2012

I have this in my .zshrc

eval "$(hub alias -s)"
  • hub is installed via homebrew
  • zsh completion is installed to /usr/local/share/zsh/site-functions

the hub commands like pull-request, browse etc doesn't get completed

Ideas @mislav ?

@rnc

This comment has been minimized.

Copy link

rnc commented Sep 10, 2012

Should the completion work even without the aliasing (i.e. as 'hub' ? )

@teoljungberg

This comment has been minimized.

Copy link

teoljungberg commented Sep 11, 2012

Should the completion work even without the aliasing (i.e. as 'hub' ? )

Doesn't look like it, running hub unalised doesn't autocomplete anything

@rnc

This comment has been minimized.

Copy link

rnc commented Sep 11, 2012

Er, yeah :-) I meant it would be good if it could be used like that.

@teoljungberg

This comment has been minimized.

Copy link

teoljungberg commented Sep 11, 2012

Er, yeah :-) I meant it would be good if it could be used like that.

Yeah, that would have been swell.
Is this a don't fix @mislav ?

@mislav

This comment has been minimized.

Copy link
Member

mislav commented Sep 11, 2012

I would like to have the best possible experience in zsh with completion of either hub command or git aliased to hub.

However, I don't know how. Even the current zsh completion script I didn't write myself. I barely know how it works, what's the best way to install it, or to change it. I tried reading zsh's man pages about tab-completion but they were just too much.

Maybe I'll fix this when I have time to spare. In the meantime, anyone else is welcome to try.

@dmmalam

This comment has been minimized.

Copy link

dmmalam commented Sep 26, 2012

+1

@singingwolfboy

This comment has been minimized.

Copy link

singingwolfboy commented Oct 26, 2012

Based on my casual inspection, the script works by retrieving the builtin completions for git (using declare -f _git) and then using sed to insert the information for hub. However, sed is looking for the string "base_commands" in the input, which for me (zsh 5.0.0) doesn't exist in the output of declare -f _git. Looks like zsh changed how git completion works, which broke hub completion.

If someone can look up how zsh's builtin git completion script used to be, maybe we can restore compatibility with hub's completion script.

@singingwolfboy

This comment has been minimized.

Copy link

singingwolfboy commented Oct 26, 2012

Another pointer: looks like the new builtin git completion adds in information from a variable called $_git_third_party_commands -- sounds like it's specifically designed for this use case.

@goodell

This comment has been minimized.

Copy link
Collaborator

goodell commented Oct 31, 2012

You can find a start of a fix here. This mostly works with the stock _git completion in zsh-5.0.0, with one major caveat: you can't complete the hub subcommand itself (e.g., pull-request). You can, however, complete most of the arguments to the particular subcommand. The files in that gist should be put somewhere in your $fpath, probably in the site-functions directory. The old _hub script can be discarded.

The stock _git completion script looks for subcommands in the $commands array (i.e., actual invokable commands that rehash finds) with the pattern git-CMD. This works for typical git extensions, but not for the hub subcommands because it subsumes the actual git command itself. A hackier version of the sed fix from before is an option, but remains super-ugly. The right fix is probably to coordinate with the zsh maintainers to get a less restrictive version of the _git completion script distributed in the main distribution.

I probably won't have time to finish this work up, so if someone wants to take the code from the above and figure out how to complete the last part, please feel free. I'm also watching the thread, so I can answer some questions if any of the above is confusing.

@teoljungberg

This comment has been minimized.

Copy link

teoljungberg commented Oct 31, 2012

@goodell thats definatly a start! I would love to be able to complete the commands aswell, tho my zsh-fu isn't strong :(
Looking forward to see if this goes anywhere

@aloiscochard

This comment has been minimized.

Copy link

aloiscochard commented Jan 3, 2013

+1

@bradical

This comment has been minimized.

Copy link

bradical commented Jan 3, 2013

I ran into this too. I found that while I couldn't get hub specific commands to tab-complete, I could get the rest of the git commands to compete by using oh-my-zsh and the "github" plugin instead of having: eval "$(hub alias -s)" in my .zshrc.

So my .zshrc looks like this:

... stuff ...
plugins=(git github)
source $ZSH/oh-my-zsh.sh

# Customize to your needs...

zstyle ':completion:*:*:git:*' script /usr/local/etc/bash_completion.d/git-completion.bash
fpath=(/usr/local/share/zsh/site-functions $fpath)
... more stuff ...

The last line is the one that should bring the hub completions but does not.

@goodell

This comment has been minimized.

Copy link
Collaborator

goodell commented Jan 3, 2013

If you don't mind living with a hacked version of ${prefix}/share/zsh/functions/_git, then you can take my previously-linked gist and make this modification to your _git file. It will also have the downside of enabling completion for subcommands which you don't have installed but for which you do have completion functions installed (git wtf is an example of this on my machine).

@bradical

This comment has been minimized.

Copy link

bradical commented Jan 7, 2013

@goodell sorry, i'm not quite following. This patch doesn't appear to be relevant to my _git file. Mine is coming directly from git's CONTRIB directory. Is there a different one that I need that contains lines like:

   local -a third_party_commands
   local command
   for command in $_git_third_party_commands; do
@goodell

This comment has been minimized.

Copy link
Collaborator

goodell commented Jan 7, 2013

@bradical what version of zsh do you have? My patch was against the Completion/Unix/Command/_git file from the zsh-5.0.0 source tarball. This gitweb view of the file seems to match mine, although I didn't diff it closely.

@bradical

This comment has been minimized.

Copy link

bradical commented Jan 7, 2013

Ah, I'm using zsh 4.3.11 (i386-apple-darwin12.0) and oh-my-zsh. A little overwhelmed by all the completion configuration for oh-my-zsh so far.

I've currently got:

  • /usr/local/share/zsh/site-functions/_hub --> /usr/local/Cellar/hub/1.10.4/share/zsh/site-functions/_hub -- which is coming from "hub" that I installed via homebrew
  • /usr/local/share/zsh/site-functions/_git --> /usr/local/Cellar/git/1.8.1/share/zsh/site-functions/git-completion.zsh -- this file I pulled from the Git CONTRIB directory.

And in my .zshrc I've got (among other things):

plugins=(git github)
# Git/github stuff
eval "$(hub alias -s)"
# Include BASH completions
zstyle ':completion:*:*:git:*' script /usr/local/etc/bash_completion.d/git-completion.bash
# Now zsh specific completions
fpath=(/usr/local/share/zsh/site-functions $fpath)
@goodell

This comment has been minimized.

Copy link
Collaborator

goodell commented Jan 7, 2013

I moved away from oh-my-zsh and to prezto a while ago b/c oh-my-zsh was way too intrusive and I found myself fighting it quite frequently. If you grab your zsh from homebrew you'll get 5.0.0 (with a more modern, zsh-distributed _git file, IIRC).

I'm not going to bother to try to backport my completions to old zsh, since that seems like a big waste of time. Feel free to use them as a starting point if you have a different opinion on the matter.

Good luck :)

@bradical

This comment has been minimized.

Copy link

bradical commented Jan 7, 2013

Thanks. I'll give a homebrew-installed version of zsh a try.

@mislav

This comment has been minimized.

Copy link
Member

mislav commented Jan 8, 2013

oh-my-zsh was way too intrusive and I found myself fighting it quite frequently

Ditto.

@goodell See my oh-my-zsh selective config

@jfromaniello

This comment has been minimized.

Copy link

jfromaniello commented Jan 10, 2013

Another way, specially if you are using prezto will be to copy this one _github for the github gem.

The github gem has more things than hub I guess.. so it will require to remove things mostly.

@goodell

This comment has been minimized.

Copy link
Collaborator

goodell commented Jan 10, 2013

@jfromaniello I haven't tried it out, but that doesn't look like it will actually solve the problem that we are having here. My completions all work for the actual subcommands themselves. Those were fairly easy to write. The issue is overly aggressive filtering of third-party subcommands by the stock _git completion script, which doesn't seem to be affected by the _github completion script. That is, git for[TAB] will not offer fork as a completion choice, but git fork --[TAB] will offer --no-remote as expected.

Am I missing something in your comment or the _github completion script?

@uk-ar

This comment has been minimized.

Copy link

uk-ar commented Feb 28, 2013

@goodell I wrote a code to complete subcommands. How about this?

compdef _hub hub

function _hub {
    _git
    local -a hub_commands
    hub_commands=(
        alias:'show shell instructions for wrapping git'
        pull-request:'open a pull request on GitHub'
        fork:'fork origin repo on GitHub'
        create:'create new repo on GitHub for the current project'
        browse:'browse the project on GitHub'
        compare:'open GitHub compare view')
    _describe -t hub-commands 'hub command' hub_commands && ret=0
}
compdef git=hub
@mislav

This comment has been minimized.

Copy link
Member

mislav commented Feb 28, 2013

@uk-ar That seems awesome. If it works well with hub invoked with hub as well as git, and supports regular git autocompletions, let's ship it

@goodell

This comment has been minimized.

Copy link
Collaborator

goodell commented Mar 1, 2013

I can confirm it does work, even invoked as git or hub. But it only provides completion of the subcommands itself, and it continues to offer those subcommands as completions even when completing options or arguments to non-hub commands. So if you have a branch named alien then git branch -d alTab will offer you the choice to complete alien or alias, the latter being a hub subcommand.

Feel free to take @uk-ar's completion, at least as a brew option. It's better than the currently-broken code that kicked off this ticket. I'll see if I can find some time to try and improve my approach based on @uk-ar's code.

@goodell

This comment has been minimized.

Copy link
Collaborator

goodell commented Mar 1, 2013

Hold on a moment. Things have changed in homebrew quite a bit since this issue was opened. See Homebrew/legacy-homebrew#16992 for full (and confusing) background. The short version, best as I can tell, is that they have decided to install the bash-based zsh completions for git that come from the git distribution's contrib directory. This is in addition to the default git completion script that ships with zsh (both are named _git). This bash script takes precedence over the default script because of the normal $fpath order.

My prototype completions were written based on the zsh version of _git, not the bash version. @uk-ar's version is too, AFAICT. Frankly, I prefer the zsh based ones, and I think it's pretty ugly to leave both installed. I started poking at a fix based on the zsh version but got stymied when I realized that code wasn't even being executed anymore.

I would hold off pulling the @uk-ar suggestion for now. There's a good chance that we can do something better after some investigation of the bash-based completions.

@mislav

This comment has been minimized.

Copy link
Member

mislav commented Mar 2, 2013

Ok let me know when things get sorted out. It's all indeed very confusing
right now, and I'm thankful for you people to help out with this

goodell added a commit to goodell/hub that referenced this issue Mar 2, 2013

fix zsh completion
The `compdef` that was previously emitted by `hub alias -s` prevents the
new `_zsh` script from working.

Fixes github#231

goodell added a commit to goodell/hub that referenced this issue Mar 2, 2013

fix zsh completion
The `compdef` that was previously emitted by `hub alias -s` prevents the
new `_git` script from working.

Fixes github#231
@fuadsaud

This comment has been minimized.

Copy link

fuadsaud commented Jul 19, 2013

Did anyone got this working with prezto? Does only reinstalling git without the completions do the job?

@OliverJAsh

This comment has been minimized.

Copy link

OliverJAsh commented Jul 19, 2013

I've reinstalled git without the completions, using prezto, to no avail. Also ran brew update; brew upgrade hub --HEAD.

Does it matter that I have both of these in my fpath?

/usr/local/share/zsh/site-functions
/usr/local/Cellar/zsh/5.0.2/share/zsh/functions

@bradical

This comment has been minimized.

Copy link

bradical commented Jul 19, 2013

Check the contents of this folder: /usr/local/share/zsh/site-functions and
make sure it only contains the _hub completion script. If it does, then I'm
not sure but I had to actually remove my old _git completion script from
/usr/local/share/zsh/site-functions.

On Fri, Jul 19, 2013 at 1:05 PM, Oliver Joseph Ash <notifications@github.com

wrote:

I've reinstalled git without the completions, using prezto, to no avail.
Also ran brew update; brew upgrade hub --HEAD.

Does it matter that I have both of these in my fpath?

/usr/local/share/zsh/site-functions
/usr/local/Cellar/zsh/5.0.2/share/zsh/functions


Reply to this email directly or view it on GitHubhttps://github.com//issues/231#issuecomment-21262847
.

@mislav

This comment has been minimized.

Copy link
Member

mislav commented Jul 19, 2013

It's not yet confirmed that our completion works with Prezto. It probably doesn't. Prezto does some weird shit with git aliases and completions.

@goodell

This comment has been minimized.

Copy link
Collaborator

goodell commented Jul 20, 2013

I use prezto and it works fine for me. IIRC I disabled a bunch of the aliases because they annoyed me, which can be seen here: https://github.com/goodell/prezto/commits/goodell-mods

My .zpreztorc is here: https://bitbucket.org/goodell/dotfiles/src/f797d150967de61291ef51f0e4fe5fd69a060d06/.zpreztorc?at=master

@pablox-cl

This comment has been minimized.

Copy link

pablox-cl commented Sep 16, 2013

Works fine with prezto... as long you don't have complete_aliases configured. Something strange is that if I have that option turned on, first time I try to run git, it doesn't read hub commands, but then it does.

~ ❯❯❯ setopt | grep alias
completealiases
~ ❯❯❯ git for<Tab>
 -- main porcelain command --
format-patch  -- prepare patches for e-mail submission
 -- plumbing interrogator command --
for-each-ref  -- output information on each ref
~ ❯❯❯ hub for<Tab>
 -- main porcelain command --
format-patch  -- prepare patches for e-mail submission
 -- plumbing interrogator command --
for-each-ref  -- output information on each ref
 -- hub command --
fork          -- fork origin repo on GitHub
~ ❯❯❯ git for<Tab>
 -- main porcelain command --
format-patch  -- prepare patches for e-mail submission
 -- plumbing interrogator command --
for-each-ref  -- output information on each ref
 -- hub command --
fork          -- fork origin repo on GitHub

I don't understand how running the commands in a different order works... O.o

@michaelhood

This comment has been minimized.

Copy link

michaelhood commented Sep 16, 2013

I don't understand how running the commands in a different order works... O.o

see: cb9bb13#L0R156

I don't use prezto, but I'm guessing you're missing an invocation like that?

@pablox-cl

This comment has been minimized.

Copy link

pablox-cl commented Sep 20, 2013

No, at all. I'm using that exact completion, I read that line before, but I guess it's not working as it is intended (because it's not completing on the first tab (at least with COMPLETE_ALIASES turned on).

tlvince added a commit to tlvince/osx-config that referenced this issue Nov 2, 2013

goodell added a commit that referenced this issue Dec 18, 2013

fix zsh completion
This `_hub` completion script should correctly wrap modern versions of
the `_git` scripts distributed by both zsh (native) and git
(bash-based).  The bash-based version could use a bit more love to
complete arguments to the actual subcommands.  Right now it can only
complete the names of the subcommands themselves.

The `compdef` that was previously emitted by `hub alias -s` prevents the
new `_git` script from working, so it has been eliminated.

Fixes #231
@quarterto

This comment has been minimized.

Copy link

quarterto commented Jan 30, 2014

Just to confirm that brew upgrade git --without-completions (and hub from HEAD) is sufficient to make this (and git-flow!) work with Prezto.

@maksimr

This comment has been minimized.

Copy link
Contributor

maksimr commented Feb 16, 2014

Hm ... it doesn't work for me :(

Install hub through gem
call eval "$(hub alias -s)"
both git completion(include standard) and hub is not working
use oh-my-zsh. github plugin from oh-my-zsh also doesn't work.

hub --version
git version 1.8.0
hub version 1.11.2-g1c5d3bf
zsh --version
zsh 5.0.2 (x86_64-unknown-linux-gnu)
@mislav

This comment has been minimized.

Copy link
Member

mislav commented Feb 16, 2014

@maksimr The steps you have described isn't enough to enable zsh completion. I'm sorry; this all isn't documented very well.

I would suggest that you uninstall hub that you've installed through gem install since that is slow. That method of installation is only meant as a last resort, and not generally recommended.

What you should do it clone hub repo somewhere, then from the hub's directory:

  1. sudo rake install - it will install hub into /usr/local

  2. copy hub.zsh_completion file to somewhere in your fpath (check echo $fpath) as a file named _hub, e.g.

    sudo cp etc/hub.zsh_completion /usr/share/zsh/site-functions/_hub
    
@maksimr

This comment has been minimized.

Copy link
Contributor

maksimr commented Feb 16, 2014

@mislav Thanks! But it doesn't help ... maybe I do something wrong

My steps

  1. uninstall gem hub gem uninstall hub
  2. clone project g cl https://github.com/github/hub.git
  3. run rake cd hub and export PREFIX="/home/maksimrv/local" && rake install
  4. copy hub completion to directory in $fpath var cp etc/hub.zsh_completion $HOME/dotfiles/hub-zsh-completion/_hub
  5. Add eval "$(hub alias -s)" to .zshrc
  6. run new zsh session
echo $fpath
/home/maksimrv/dotfiles/hub-zsh-completion
ls ~/dotfiles/hub-zsh-completion
_hub
cat /etc/redhat-release
Red Hat Enterprise Linux Server release 6.4 (Santiago)
 hub --version
git version 1.8.0
hub version 1.11.2-3-gaacc92f
@mislav

This comment has been minimized.

Copy link
Member

mislav commented Feb 17, 2014

You did everything right, except that your fpath contains only your custom directory and not any of the zsh's system directories. It's important that zsh's own directories stay on fpath so that zsh can load regular _git completion script from it that _hub script extends. On my system, the _git script that ships with zsh is in /usr/share/zsh/5.0.2/functions/_git

@maksimr

This comment has been minimized.

Copy link
Contributor

maksimr commented Feb 17, 2014

Sorry my fault I just pulled down the rest of the output

all output look like:

echo $fpath
/home/maksimrv/.oh-my-zsh/plugins/github /home/maksimrv/dotfiles/hub-zsh-completion /home/maksimrv/.oh-my-zsh/plugins/git-flow-avh /home/maksimrv/.oh-my-zsh/custom/plugins/st /home/maksimrv/.oh-my-zsh/plugins/debian /home/maksimrv/.oh-my-zsh/custom/plugins/zsh-syntax-highlighting /home/maksimrv/.oh-my-zsh/plugins/history-substring-search /home/maksimrv/.oh-my-zsh/plugins/vi-mode /home/maksimrv/.oh-my-zsh/plugins/vundle /home/maksimrv/.oh-my-zsh/plugins/git /home/maksimrv/.oh-my-zsh/functions /home/maksimrv/.oh-my-zsh/completions /home/maksimrv/local/share/zsh/site-functions /home/maksimrv/local/share/zsh/5.0.2/functions
ls /home/maksimrv/local/share/zsh/5.0.2/functions | grep git
_git
_git-buildpackage
run-help-git
_stgit
_topgit
VCS_INFO_detect_git
VCS_INFO_get_data_git
@mislav

This comment has been minimized.

Copy link
Member

mislav commented Feb 17, 2014

Not sure what is wrong then. Ensure that in your zshrc, nothing accesses git before your custom fpath and hub alias have been set, so that zsh doesn't accidentally load git completions prematurely.

@maksimr

This comment has been minimized.

Copy link
Contributor

maksimr commented Feb 17, 2014

@mislav Thanks!!

Ensure that in your zshrc, nothing accesses git before your custom fpath and hub alias have been set, so that zsh doesn't accidentally load git completions prematurely.

I think the bug is in this. I will try to find it

@kyounger

This comment has been minimized.

Copy link

kyounger commented Feb 25, 2014

OK, would you happen to be using tmux, too? I just figured out that was my problem with completion not working.

I just had to replace all usages of zsh with $SHELL in my tmux.conf, because in various situations I have tmux instantiating shells to do things like copy/paste, renaming windows, etc., and it was using the default osx zsh shell because $PATH wasn't fully defined in the non-login shell. This caused $fpath to be incorrect, also. At least I think that's the explanation... :)

Note that I'm using boxen, which includes homebrew's zsh (5.0.5) and tmux. I use prezto with my prezto modules defined in this order:

    'environment' \
    'custom-early' \
    'terminal' \
    'editor' \
    'history' \
    'directory' \
    'spectrum' \
    'utility' \
    'completion' \
    'custom' \
    'git' \
    'prompt'

(If you're wondering, I include boxen's /opt/boxen/env.sh environment setup in my "custom-early" prezto module. boxen is what sets up homebrew's environment for me, so there could be something to that being included so early in the module loading process.)

@mculp

This comment has been minimized.

Copy link

mculp commented Jul 30, 2014

Been having this issue for a while and just decided to try and fix it. Spent about 45 minutes going through this thread.

Not sure what is wrong then. Ensure that in your zshrc, nothing accesses git before your custom fpath and hub alias have been set, so that zsh doesn't accidentally load git completions prematurely.

THIS.

I'm not sure changing any of the _git or _hub scripts actually did anything, but when I moved this:

"$(hub alias -s)"
fpath=('/usr/local/share/zsh/site-functions' $fpath)

above everything except ZSH and ZSH_THEME in .zshrc, it magically started working.

I'm not sure what the deal was -- I didn't have anything using git that I know of.

Thanks, @mislav and @bradical.

@reem

This comment has been minimized.

Copy link

reem commented Aug 5, 2014

@mculp I have also had this issue for months but decided an hour ago that I was going to fix it.

Reinstall git, etc. did nothing. Moving the alias declaration and modification of fpath above loading prezto fixed everything. Yay completion!

@shioyama

This comment has been minimized.

Copy link

shioyama commented Aug 31, 2014

Just another data point for anyone struggling with this.

I use oh-my-zsh and had trouble getting hub completions to work, then saw this gist and noticed that he had hub in his zsh plugins. Searching around I couldn't find any such plugin, so I just created a directory named hub in .oh-my-zsh/plugins/ and moved etc/hub.zsh_completion in there, renamed to _hub. Then I just added hub to the plugins in my .zshrc and everything now works fine.

(I'm on ubuntu so no homebrew.)

@nightire

This comment has been minimized.

Copy link

nightire commented Sep 7, 2014

👍 @mculp you save my day!

@nTraum

This comment has been minimized.

Copy link

nTraum commented Sep 15, 2014

@shioyama's set up worked for me as well (hub & git installed via homebrew, no aliasing). Thank you so much 🌻

@mawaldne

This comment has been minimized.

Copy link

mawaldne commented Nov 9, 2014

👍 Thanks @shioyama. That works

@skywinder

This comment has been minimized.

Copy link

skywinder commented Nov 25, 2014

The @shioyama solution not works for me on OS X.
I put hub.zsh_completion content to ~/oh-my-zsh/plugins/hub/_hub file. But completions for hub or git not appeared.

@meierjan

This comment has been minimized.

Copy link

meierjan commented Dec 5, 2014

thanks to @shioyama

this will fix it if you are using .oh-my-zsh

mkdir -p ~/.oh-my-zsh/plugins/hub
curl https://raw.githubusercontent.com/github/hub/master/etc/hub.zsh_completion > ~/.oh-my-zsh/plugins/hub/_hub
@BBonifield

This comment has been minimized.

Copy link

BBonifield commented Oct 2, 2015

I'm an oh-my-zsh user, but the above mentioned fix to add the hub oh-my-zsh plugin didn't work for me. I was able to resolve this by adding fpath=('/usr/local/share/zsh/site-functions' $fpath) to my .zshrc above ZSH=....

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment