mirror of
https://github.com/fish-shell/fish-shell
synced 2024-12-27 05:13:10 +00:00
completions/git: Add fast path for untracked files
It's super easy to get a lot of these and they'll otherwise slow down the completions a lot. This makes `git add <TAB>` ~5-6x faster with about 4000 untracked files (a copy of the fish build directory). It goes from 1.5 seconds to 250ms. This is just for the git >= 2.11 path, but the other one would require more checking and since git 2.11 is almost 7 years old now that's not worth it.
This commit is contained in:
parent
1f1975689e
commit
7f76f75966
1 changed files with 18 additions and 9 deletions
|
@ -183,9 +183,12 @@ function __fish_git_files
|
||||||
# We explicitly enable globs so we can use that to match the current token.
|
# We explicitly enable globs so we can use that to match the current token.
|
||||||
set -l git_opt -c status.relativePaths -c core.quotePath=
|
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)
|
string match -q './*' -- (commandline -ct)
|
||||||
and set -l rel ./
|
and set -l rel ./
|
||||||
or set -l rel
|
or set -l rel
|
||||||
|
|
||||||
|
# If the token starts with `:`, it's from the repo root
|
||||||
string match -q ':*' -- (commandline -ct)
|
string match -q ':*' -- (commandline -ct)
|
||||||
and set -l colon 1
|
and set -l colon 1
|
||||||
or set -l colon
|
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')
|
set -l ver (__fish_git --version | string replace -rf 'git version (\d+)\.(\d+)\.?.*' '$1\n$2')
|
||||||
# Version >= 2.11.* has the v2 format.
|
# 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
|
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 \
|
set -l stats (__fish_git $git_opt status --porcelain=2 $status_opt)
|
||||||
| while read -la -d ' ' line
|
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 file
|
||||||
set -l desc
|
set -l desc
|
||||||
# The basic status format is "XY", where X is "our" state (meaning the staging area),
|
# 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
|
set -ql deleted_staged
|
||||||
and set file "$line[9..-1]"
|
and set file "$line[9..-1]"
|
||||||
and set desc $staged_deleted_desc
|
and set desc $staged_deleted_desc
|
||||||
case "$q"' *'
|
|
||||||
# Untracked
|
|
||||||
# "? <path>" - print from element 2 on.
|
|
||||||
set -ql untracked
|
|
||||||
and set file "$line[2..-1]"
|
|
||||||
and set desc $untracked_desc
|
|
||||||
case '! *'
|
case '! *'
|
||||||
# Ignored
|
# Ignored
|
||||||
# "! <path>" - print from element 2 on.
|
# "! <path>" - print from element 2 on.
|
||||||
|
@ -338,7 +347,7 @@ function __fish_git_files
|
||||||
# If this contains newlines or tabs,
|
# If this contains newlines or tabs,
|
||||||
# there is nothing we can do, but that's a general issue with scripted completions.
|
# there is nothing we can do, but that's a general issue with scripted completions.
|
||||||
set file (string trim -c \" -- $file)
|
set file (string trim -c \" -- $file)
|
||||||
# The relative filename.
|
# The (possibly relative) filename.
|
||||||
printf "$rel%s\n" "$file"\t$desc
|
printf "$rel%s\n" "$file"\t$desc
|
||||||
# Now from repo root.
|
# Now from repo root.
|
||||||
# Only do this if the filename isn't a simple child,
|
# Only do this if the filename isn't a simple child,
|
||||||
|
|
Loading…
Reference in a new issue