#compdef git-forgit #description Utility tool for using git interactively # # forgit completions for zsh # # Place this file in your $fpath (e.g. /usr/share/zsh/site-functions) to enable # tab completions for forgit as a git subcommmand. When using forgit as a shell # plugin, additionally source completions/git-forgit.zsh after # forgit.plugin.zsh to enable tab completion for shell functions and aliases. _git-branches() { _alternative "branches:branchname:($(git branch -a --format '%(refname:short)'))" } _git-checkout-file() { _alternative "files:filename:($(git ls-files --modified))" } _git-stash-show() { _alternative "files:filename:($(git stash list | sed -n -e 's/:.*//p'))" } # The completions for git already define a _git-diff completion function, but # it provides the wrong results when called from _git-forgit because it heavily # depends on the context it's been called from (usage of $curcontext and # $CURRENT), so we use a simplified version here which always provides the same # results independent of the context. _git-forgit-diff() { _alternative \ 'commit-ranges::__git_commit_ranges' \ 'blobs-and-trees-in-treeish::__git_blobs_and_trees_in_treeish' \ 'files::__git_changed-in-working-tree_files' \ 'blobs::__git_blobs ' } _git-staged() { _alternative "files:filename:($(git diff --name-only --staged))" } _git-forgit() { local subcommand cword cmd subcommand="${words[1]}" if [[ "$subcommand" != "forgit" ]]; then # Forgit is obviously called via a git alias. Get the original # aliased subcommand and proceed as if it was the previous word. cmd=$(git config --get "alias.$subcommand" | cut -d ' ' -f 2) cword=$((CURRENT + 1)) else cword=$CURRENT cmd=${words[2]} fi case ${cword} in 1) ;; 2) local -a subcommands subcommands=( 'add:git add selector' 'blame:git blame viewer' 'branch_delete:git branch deletion selector' 'checkout_branch:git checkout branch selector' 'checkout_commit:git checkout commit selector' 'checkout_file:git checkout-file selector' 'checkout_tag:git checkout tag selector' 'cherry_pick:git cherry-picking' 'cherry_pick_from_branch:git cherry-picking with interactive branch selection' 'clean:git clean selector' 'diff:git diff viewer' 'fixup:git fixup' 'ignore:git ignore generator' 'log:git commit viewer' 'rebase:git rebase' 'reset_head:git reset HEAD (unstage) selector' 'revert_commit:git revert commit selector' 'stash_show:git stash viewer' 'stash_push:git stash push selector' ) _describe -t commands 'git forgit' subcommands ;; *) case ${cmd} in add) _git-add ;; branch_delete) _git-branches ;; checkout_branch) _git-branches ;; checkout_commit) __git_recent_commits ;; checkout_file) _git-checkout-file ;; checkout_tag) __git_tags ;; cherry_pick) _git-cherry-pick ;; cherry_pick_from_branch) _git-branches ;; clean) _git-clean ;; diff) _git-forgit-diff ;; fixup) __git_branch_names ;; log) _git-log ;; rebase) _git-rebase ;; reset_head) _git-staged ;; revert_commit) __git_recent_commits ;; stash_show) _git-stash-show ;; esac ;; esac }