cd completion: No description for absolute paths

This also removes the "pushd/popd" dance and only executes the CDPATH
stuff when we need to.
This commit is contained in:
Fabian Homborg 2016-04-04 18:22:48 +02:00
parent 411d573ba9
commit 0953590cca

View File

@ -1,24 +1,32 @@
function __fish_complete_cd -d "Completions for the cd command"
set -l cdpath $CDPATH
[ -z "$cdpath" ]; and set cdpath "."
# Remove the real path to "." (i.e. $PWD) from cdpath if we're in it
# so it doesn't get printed in the descriptions
set -l ind
if begin; set ind (contains -i -- $PWD $cdpath)
and contains -- "." $cdpath
end
set -e cdpath[$ind]
end
for i in $cdpath
set -l desc
# Don't show description for current directory
# and replace $HOME with "~"
[ $i = "." ]; or set -l desc (string replace -r -- "^$HOME" "~" "$i")
pushd $i
for d in (commandline -ct)*/
set -l token (commandline -ct)
# Absolute path - no descriptions and no CDPATH
if string match -q '/*' -- $token
for d in $token*/
# Check if it's accessible - the glob only matches directories
[ -x $d ]; and printf "%s\t%s\n" $d $desc
[ -x $d ]; and printf "%s\n" $d
end
else # Relative path - check $CDPATH and use that as description
set -l cdpath $CDPATH
[ -z "$cdpath" ]; and set cdpath "."
# Remove the real path to "." (i.e. $PWD) from cdpath if we're in it
# so it doesn't get printed in the descriptions
if set -l ind (contains -i -- $PWD $cdpath)
and contains -- "." $cdpath
set -e cdpath[$ind]
end
# TODO: There's a subtlety regarding descriptions - if $cdpath[1]/foo and $cdpath[2]/foo exist, we print both
# but want the first description to win - this currently works, but is not guaranteed
for i in $cdpath
set -l desc
# Don't show description for current directory
# and replace $HOME with "~"
[ $i = "." ]; or set -l desc (string replace -r -- "^$HOME" "~" "$i")
# This assumes the CDPATH component itself is cd-able
for d in $i/$token*/
# Remove the cdpath component again
[ -x $d ]; and printf "%s\t%s\n" (string replace -r "^$i/" "" -- $d) $desc
end
end
popd
end
end