On 25.02.19 10:46, Daniel Hahler wrote: > What about something like this (against master)? As for _git_checkout, the following appears to work better: Completion/Unix/Command/_git | 54 ++++++++++++++++++++------------------------ 1 file changed, 25 insertions(+), 29 deletions(-) diff --git i/Completion/Unix/Command/_git w/Completion/Unix/Command/_git index b3e54f7f9..e9f6f3587 100644 --- i/Completion/Unix/Command/_git +++ w/Completion/Unix/Command/_git @@ -449,7 +449,7 @@ _git-checkout () { local curcontext=$curcontext state line ret=1 declare -A opt_args - _arguments -C -s \ + _arguments -C -s -S \ '(-q --quiet --progress)'{-q,--quiet}'[suppress progress reporting]' \ '(-f --force -m --merge --conflict --patch)'{-f,--force}'[force branch switch/ignore unmerged entries]' \ '(-q --quiet -2 --ours -3 --theirs --patch)'{-2,--ours}'[check out stage #2 for unmerged paths]' \ @@ -469,37 +469,33 @@ _git-checkout () { '--recurse-submodules=-[control recursive updating of submodules]::checkout:__git_commits' \ '(-q --quiet)--progress[force progress reporting]' \ '(-)--[start file arguments]' \ - '*:: :->branch-or-tree-ish-or-file' && ret=0 + '1: :->first-arg' \ + '*: :->other-arg' && ret=0 case $state in - (branch-or-tree-ish-or-file) - # TODO: Something about *:: brings us here when we complete at "-". I - # guess that this makes sense in a way, as we might want to treat it as - # an argument, but I can't find anything in the documentation about this - # behavior. - [[ $line[CURRENT] = -* ]] && return - if (( CURRENT == 1 )) && [[ -z $opt_args[(I)--] ]]; then - # TODO: Allow A...B - local \ - remote_branch_noprefix_arg='remote-branch-names-noprefix::__git_remote_branch_names_noprefix' \ - tree_ish_arg='tree-ishs::__git_commits_prefer_recent' \ - file_arg='modified-files::__git_modified_files' + (first-arg) + # TODO: Allow A...B + local \ + remote_branch_noprefix_arg='remote-branch-names-noprefix::__git_remote_branch_names_noprefix' \ + tree_ish_arg='tree-ishs::__git_commits_prefer_recent' \ + file_arg='modified-files::__git_modified_files' - if [[ -n ${opt_args[(I)-b|-B|--orphan|--detach]} ]]; then - _alternative $tree_ish_arg && ret=0 - elif [[ -n $opt_args[(I)--track] ]]; then - _alternative remote-branches::__git_remote_branch_names && ret=0 - elif [[ -n ${opt_args[(I)--ours|--theirs|-m|--conflict|--patch]} ]]; then - _alternative $tree_ish_arg $file_arg && ret=0 - else - _alternative \ - $file_arg \ - $tree_ish_arg \ - $remote_branch_noprefix_arg \ - && ret=0 - fi - - elif [[ -n ${opt_args[(I)-b|-B|-t|--track|--orphan|--detach]} ]]; then + if [[ -n ${opt_args[(I)-b|-B|--orphan|--detach]} ]]; then + _alternative $tree_ish_arg && ret=0 + elif [[ -n $opt_args[(I)--track] ]]; then + _alternative remote-branches::__git_remote_branch_names && ret=0 + elif [[ -n ${opt_args[(I)--ours|--theirs|-m|--conflict|--patch]} ]]; then + _alternative $tree_ish_arg $file_arg && ret=0 + else + _alternative \ + $file_arg \ + $tree_ish_arg \ + $remote_branch_noprefix_arg \ + && ret=0 + fi + ;; + (other-arg) + if [[ -n ${opt_args[(I)-b|-B|-t|--track|--orphan|--detach]} ]]; then _nothing elif [[ -n $line[1] ]] && __git_is_treeish ${(Q)line[1]}; then __git_ignore_line __git_tree_files ${PREFIX:-.} ${(Q)line[1]} && ret=0