From b8aacc29cd92224614944382a9f1f9b25118bfec Mon Sep 17 00:00:00 2001 From: Kurtis Rader Date: Thu, 1 Jun 2017 17:49:01 -0700 Subject: [PATCH] remove redundant output from __fish_complete_cd Fixes #4085 --- share/functions/__fish_complete_cd.fish | 64 +++++++++++++------------ 1 file changed, 33 insertions(+), 31 deletions(-) diff --git a/share/functions/__fish_complete_cd.fish b/share/functions/__fish_complete_cd.fish index 381e0b0b7..190f9b935 100644 --- a/share/functions/__fish_complete_cd.fish +++ b/share/functions/__fish_complete_cd.fish @@ -1,36 +1,38 @@ +# This function only emits completions that might result from matches against $CDPATH. We rely on +# the core file name completion logic to include all other possible matches. function __fish_complete_cd -d "Completions for the cd command" + set -q CDPATH[1] + or return 0 # no CDPATH so rely solely on the core file name completions + set -l token (commandline -ct) - # Absolute path or explicitly from the current directory - no descriptions and no CDPATH - if string match -qr '^\.?\.?/.*' -- $token - for d in $token*/ - # Check if it's accessible - the glob only matches directories - [ -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 + if string match -qr '^\.{0,2}/.*' -- $token + # Absolute path or explicitly relative to the current directory. Rely on the builtin file + # name completions since we no longer exclude them from the `cd` argument completion. + return + end + + # Relative path. Check $CDPATH and use that as the description for any possible matches. + # We deliberately exclude the `.` path because the core file name completion logic will include + # it when presenting possible matches. + set -l cdpath (string match -v '.' -- $CDPATH) + + # Remove the CWD if it is in CDPATH since, again, the core file name completion logic will + # handle it. + set -l cdpath (string match -v -- $PWD $cdpath) + set -q cdpath[1] + or return 0 + + # 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 cdpath in $cdpath + # Replace $HOME with "~". + set -l desc (string replace -r -- "^$HOME" "~" "$cdpath") + # This assumes the CDPATH component itself is cd-able. + for d in $cdpath/$token*/ + # Remove the cdpath component again. + test -x $d + and printf "%s\tCDPATH %s\n" (string replace -r "^$cdpath/" "" -- $d) $desc end end end