aboutsummaryrefslogtreecommitdiffhomepage
path: root/share/functions/__fish_complete_cd.fish
diff options
context:
space:
mode:
authorGravatar Fabian Homborg <FHomborg@gmail.com>2015-08-10 16:15:45 +0200
committerGravatar Fabian Homborg <FHomborg@gmail.com>2015-10-07 10:41:05 +0200
commit0a99772572ab8632f103f05570da707683980d17 (patch)
tree906ff88868357ade5af77658d3ab1d98ffc8b2ff /share/functions/__fish_complete_cd.fish
parent2ffb47eba24ad61729676206c6b8cde61c27c219 (diff)
Rewrite __fish_complete_cd
This no longer uses "eval" (which is scary), and is a bit shorter (which is nice). Fixes #2299 Fixes #952 Improves #2300 Improves #562
Diffstat (limited to 'share/functions/__fish_complete_cd.fish')
-rw-r--r--share/functions/__fish_complete_cd.fish69
1 files changed, 20 insertions, 49 deletions
diff --git a/share/functions/__fish_complete_cd.fish b/share/functions/__fish_complete_cd.fish
index de38e436..26e469ad 100644
--- a/share/functions/__fish_complete_cd.fish
+++ b/share/functions/__fish_complete_cd.fish
@@ -1,53 +1,24 @@
function __fish_complete_cd -d "Completions for the cd command"
- #
- # We can't simply use __fish_complete_directories because of the CDPATH
- #
- set -l wd $PWD
-
- # Check if CDPATH is set
-
- set -l mycdpath
-
- if test -z $CDPATH[1]
- set mycdpath .
- else
- set mycdpath $CDPATH
- end
-
- # Note how this works: we evaluate $ctoken*/
- # That trailing slash ensures that we only expand directories
-
- set -l ctoken (commandline -ct)
- if echo $ctoken | __fish_sgrep '^/\|^\./\|^\.\./\|^~/' >/dev/null
- # This is an absolute search path
- # Squelch descriptions per issue 254
- eval printf '\%s\\n' $ctoken\*/
- else
- # This is a relative search path
- # Iterate over every directory in CDPATH
- # and check for possible completions
-
- for i in $mycdpath
- # Move to the initial directory first,
- # in case the CDPATH directory is relative
- builtin cd $wd ^/dev/null
- builtin cd $i ^/dev/null
-
- if test $status -ne 0
- # directory does not exists or missing permission
- continue
- end
-
- # What we would really like to do is skip descriptions if all
- # valid paths are in the same directory, but we don't know how to
- # do that yet; so instead skip descriptions if CDPATH is just .
- if test "$mycdpath" = .
- eval printf '"%s\n"' $ctoken\*/
- else
- eval printf '"%s\tin "'$i'"\n"' $ctoken\*/
- end
+ 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)*/
+ # Check if it's accessible - the glob only matches directories
+ [ -x $d ]; and printf "%s/\t%s\n" $d $desc
end
+ popd
end
-
- builtin cd $wd ^/dev/null
end