@@ -21,10 +21,61 @@ _comp_compgen_filedir() {
2121 # ignore empty
2222 [ -z " $cur " ] && return
2323
24- local -a pinyin_matches=()
25- while IFS= read -r line; do
26- pinyin_matches+=( " $line " )
27- done < <( bash-pinyin-completion-rs " $cur " 2> /dev/null )
2824
29- COMPREPLY+=( " ${pinyin_matches[@]} " )
25+ local dirpart=" $( dirname -- " $cur " ) "
26+ local basepart=" $( basename -- " $cur " ) "
27+
28+ [[ " $dirpart " == " ." && " $cur " != * /* ]] && dirpart=" "
29+
30+ local savedPWD=" $PWD "
31+ local resolved_dir
32+ local compgen_opts=(-f)
33+ [[ " ${1-} " == -d ]] && compgen_opts=(-d)
34+
35+ if [[ -n " $dirpart " ]]; then
36+ resolved_dir=" $( realpath -- " $dirpart " 2> /dev/null) "
37+ if [[ -d " $resolved_dir " ]]; then
38+ cd -- " $resolved_dir " 2> /dev/null || return
39+ else
40+ cd " $savedPWD " || return
41+ return
42+ fi
43+ fi
44+
45+ local -a pinyin_matched
46+ mapfile -t pinyin_matched < <(
47+ compgen " ${compgen_opts[@]} " -- " " | while IFS= read -r line; do
48+ if [[ " ${compgen_opts[0]} " == -d ]]; then
49+ printf " %s/\n" " ${line%%/ } "
50+ else
51+ if [ -d " $line " ]; then
52+ printf " %s/\n" " ${line%%/ } "
53+ else
54+ printf " %s\n" " $line "
55+ fi
56+ fi
57+ done | bash-pinyin-completion-rs " $basepart " 2> /dev/null
58+ )
59+
60+ if [[ -n " $dirpart " ]]; then
61+ for i in " ${! pinyin_matched[@]} " ; do
62+ pinyin_matched[$i ]=" ${dirpart} /${pinyin_matched[$i]} "
63+ done
64+ fi
65+
66+ cd " $savedPWD " || return
67+
68+ # merge result
69+ local -a old_candidates=(" ${COMPREPLY[@]} " )
70+ COMPREPLY=(" ${old_candidates[@]} " " ${pinyin_matched[@]} " )
71+
72+ # remove dup
73+ IFS=$' \n ' read -r -d ' ' -a COMPREPLY < <(
74+ printf ' %s\n' " ${COMPREPLY[@]} " | awk ' !seen[$0]++' | sort
75+ )
76+
77+ # fix space postfix
78+ if (( ${# COMPREPLY[@]} == 1 )) && [[ ${COMPREPLY[0]} != * / ]]; then
79+ compopt -o nospace 2> /dev/null
80+ fi
3081}
0 commit comments