diff --git a/share/completions/git.fish b/share/completions/git.fish index abdc69198..f37ce7f82 100644 --- a/share/completions/git.fish +++ b/share/completions/git.fish @@ -183,9 +183,12 @@ function __fish_git_files # We explicitly enable globs so we can use that to match the current token. set -l git_opt -c status.relativePaths -c core.quotePath= + # If the token starts with `./`, we need to prepend that string match -q './*' -- (commandline -ct) and set -l rel ./ or set -l rel + + # If the token starts with `:`, it's from the repo root string match -q ':*' -- (commandline -ct) and set -l colon 1 or set -l colon @@ -195,8 +198,20 @@ function __fish_git_files set -l ver (__fish_git --version | string replace -rf 'git version (\d+)\.(\d+)\.?.*' '$1\n$2') # Version >= 2.11.* has the v2 format. if test "$ver[1]" -gt 2 2>/dev/null; or test "$ver[1]" -eq 2 -a "$ver[2]" -ge 11 2>/dev/null - __fish_git $git_opt status --porcelain=2 $status_opt \ - | while read -la -d ' ' line + set -l stats (__fish_git $git_opt status --porcelain=2 $status_opt) + if set -ql untracked + # Fast path for untracked files - it is extremely easy to get a lot of these, + # so we handle them first + set -l files (string match -rg '^\? (.*)' -- $stats | string trim -c \") + set stats (string match -rv '^\? ' -- $stats) + printf "$rel%s\n" $files\t$untracked_desc + if set -ql colon[1] + or set files (string match '../*' -- $files) + set files (path resolve -- $files | string replace -- "$root/" ":/:") + and printf '%s\n' $files\t$untracked_desc + end + end + printf %s\n $stats | while read -la -d ' ' line set -l file set -l desc # The basic status format is "XY", where X is "our" state (meaning the staging area), @@ -316,12 +331,6 @@ function __fish_git_files set -ql deleted_staged and set file "$line[9..-1]" and set desc $staged_deleted_desc - case "$q"' *' - # Untracked - # "? " - print from element 2 on. - set -ql untracked - and set file "$line[2..-1]" - and set desc $untracked_desc case '! *' # Ignored # "! " - print from element 2 on. @@ -338,7 +347,7 @@ function __fish_git_files # If this contains newlines or tabs, # there is nothing we can do, but that's a general issue with scripted completions. set file (string trim -c \" -- $file) - # The relative filename. + # The (possibly relative) filename. printf "$rel%s\n" "$file"\t$desc # Now from repo root. # Only do this if the filename isn't a simple child,