function __fish_complete_cd -d "Completions for the cd command"
    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
        end
    end
end
