From 5f2feee680b4cb211def15f7480cc5933f6267b3 Mon Sep 17 00:00:00 2001 From: Fabian Homborg Date: Fri, 18 Sep 2015 12:36:32 +0200 Subject: [PATCH] git completion: Bring needs_command in line with git git has options that can appear before commands, but not all of them, and some of them need an argument. This means `__fish_seen_subcommand_from` will give too many false-positives, while `[ (count $cmd) -eq 2 ]` will give too many false-negatives. Instead go through all arguments and check if they are in that list of options that can be before a command and skip the argument for them, if any. --- share/completions/git.fish | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/share/completions/git.fish b/share/completions/git.fish index a845eea48..76025ad13 100644 --- a/share/completions/git.fish +++ b/share/completions/git.fish @@ -57,7 +57,32 @@ end function __fish_git_needs_command set cmd (commandline -opc) if [ (count $cmd) -eq 1 ] - return 0 + return 0 + else + set -l skip_next 1 + # Skip first word because it's "git" or a wrapper + for c in $cmd[2..-1] + test $skip_next -eq 0; and set skip_next 1; and continue + # git can only take a few options before a command, these are the ones mentioned in the "git" man page + # e.g. `git --follow log` is wrong, `git --help log` is okay (and `git --help log $branch` is superfluous but works) + # In case any other option is used before a command, we'll fail, but that's okay since it's invalid anyway + switch $c + # General options that can still take a command + case "--help" "-p" "--paginate" "--no-pager" "--bare" "--no-replace-objects" --{literal,glob,noglob,icase}-pathspecs --{exec-path,git-dir,work-tree,namespace}"=*" + continue + # General options with an argument we need to skip. The option=value versions have already been handled above + case --{exec-path,git-dir,work-tree,namespace} + set skip_next 0 + continue + # General options that cause git to do something and exit - these behave like commands and everything after them is ignored + case "--version" --{html,man,info}-path + return 1 + # We assume that any other token that's not an argument to a general option is a command + case "*" + return 1 + end + end + return 0 end return 1 end