#compdef git-now
#
# git-now ZSH completion function
#
# Installation
# ------------
# Drop this somewhere in your $fpath (like /usr/share/zsh/site-functions)
# and rename it _brew
#
# altered from _fink
#

__git-now-add ()
{
  local curcontext="$curcontext" state line expl
  typeset -A opt_args

  _arguments -s :\
    '(--all -h --help)-n[do not actually add files; only show which ones would be added]'\
    '(--all -h --help)-v[show files as they are added]'\
    '(-f --force --all -h --help)'{-f,--force}'[allow adding otherwise ignored files]'\
    '(-i --interactive --all -h --help)'{-i,--interactive}'[add contents interactively to index]'\
    '(-p --path --all -h --help)'{-p,--path}'[like -i but go directly into patch mode for specified files]'\
    '(-e --edit --all -h --help)'{-e,--edit}'[open diff against index in editor]'\
    '(-u --update --all -h --help)'{-u,--update}'[update only files git already knows about]'\
    '(-N --intent-to-add --all -h --help)'{-N,--intent-to-add}'[record only that path will be added later]'\
    '(-s --stat -h --help)'{-s,--stat}'[generate diffstat instead of patch]'\
    '(-h --help)--push[push to remote after performing finish]'\
    '(-n -v -f --force -i --interactive -p --path -e --edit -u --update -N --intent-to-add -h --help)--all[add --update and add .]'\
    '(-n -v -f --force -i --interactive -p --path -e --edit -u --update -N --intent-to-add -h --help --all --push)'{-h,--help}'[show help message]'\
    ':filepattern:_files'
}

__git_remotes () {
  local expl gitdir remotes

  gitdir=$(_call_program gitdir git rev-parse --git-dir 2>/dev/null)
  __git_command_successful || return

  remotes=(${${(f)"$(_call_program remotes git config --get-regexp '"^remote\..*\.url$"')"}//#(#b)remote.(*).url */$match[1]})
  __git_command_successful || return

  # TODO: Should combine the two instead of either or.
  if (( $#remotes > 0 )); then
    _wanted remotes expl remote compadd $* - $remotes
  else
    _wanted remotes expl remote _files $* - -W "($gitdir/remotes)" -g "$gitdir/remotes/*"
  fi
}

__git_branch_names () {
  local expl
  declare -a branch_names

  branch_names=(${${(f)"$(_call_program branchrefs git for-each-ref --format='"%(refname)"' refs/heads 2>/dev/null)"}#refs/heads/})
  __git_command_successful || return

  _wanted branch-names expl branch-name compadd $* - $branch_names
}

__git_command_successful () {
  if (( ${#pipestatus:#0} > 0 )); then
    _message 'not a git repository'
    return 1
  fi
  return 0
}

local curcontext="$curcontext" state line expl
typeset -A opt_args

_arguments -C \
  ':command:->command' \
  '*::options:->options'

case $state in
  (command)

    local -a subcommands
    subcommands=(
    'add:default subcommand.'
    'rebase:rebase for temporary commits.'
    'push:remove remote branch and push to remote repoistory for rebase commits.'
    'grep:grep temporary commits.'
    )
    _describe -t commands 'git now' subcommands
    __git-now-add
    ;;

  (options)
    case $line[1] in

      (add)
        __git-now-add
        ;;

      (rebase)
        _arguments \
          '(-m --mine -h --help)'{-m,--mine}'[limit git-now commits by your name]'\
          '(-m --mine -h --help)'{-h,--help}'[show help message]'\
          ':base-branch-name:__git_branch_names'
        ;;

      (push)
        _arguments \
          ':remote-repostory:__git_remotes'
        ;;

      (grep)
        _arguments -s : \
          '(-p --patch -h --help)'{-p,--patch}'[generate diff in patch format]'\
          '(-s --stat -h --help)'{-s,--stat}'[generate diffstat instead of patch]'\
          '(-m --mine -h --help)'{-m,--mine}'[limit git-now commits by your name]'\
          '(-m --mine -s --stat -p --patch -h --help)'{-h,--help}'[show help message]'\
          ':base-branch-name:__git_branch_names'
        ;;
      (*)
        __git-now-add
        ;;
    esac
    ;;
esac

