aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Fabian Homborg <FHomborg@gmail.com>2015-09-18 12:36:32 +0200
committerGravatar Fabian Homborg <FHomborg@gmail.com>2015-09-30 15:14:09 +0200
commit5f2feee680b4cb211def15f7480cc5933f6267b3 (patch)
tree64c374dc312f229a9fd8dc7f1e0446da4be5fe8d
parent9ecd73d956198ea0c545db8769471e5ea8c8fb02 (diff)
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.
-rw-r--r--share/completions/git.fish27
1 files changed, 26 insertions, 1 deletions
diff --git a/share/completions/git.fish b/share/completions/git.fish
index a845eea4..76025ad1 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