Skip to content

Commit 017e823

Browse files
committed
enh: hook another function
Signed-off-by: wxiwnd <wxiwnd@outlook.com>
1 parent 2065023 commit 017e823

File tree

2 files changed

+95
-226
lines changed

2 files changed

+95
-226
lines changed

scripts/bash_pinyin_completion

Lines changed: 95 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -1,78 +1,82 @@
11
#!/usr/bin/env bash
22

3-
# Load bash-completion if not loaded
4-
# [ -f /usr/share/bash-completion/bash_completion ] && \
5-
# . /usr/share/bash-completion/bash_completion
3+
# Anthon Open Source Community
4+
# Pinyin Completion Hook for Bash-Completion
65

76
# Detect bash-completion
8-
if ! declare -F _comp_compgen_filedir &>/dev/null; then
9-
echo "No function _comp_compgen_filedir found. Please install bash-completion first."
7+
if ! declare -F _comp_compgen__call_builtin &>/dev/null; then
8+
echo "No function _comp_compgen__call_builtin found. Please install bash-completion first."
109
exit 1
1110
fi
1211

13-
eval "function __bak_comp_compgen_filedir() { $(declare -f _comp_compgen_filedir | tail -n +2) }"
14-
eval "function __bak_comp_compgen_filedir_xspec() { $(declare -f _comp_compgen_filedir_xspec | tail -n +2) }"
15-
eval "function __bak_comp_complete_minimal() { $(declare -f _comp_complete_minimal | tail -n +2) }"
16-
eval "function __bak_comp_expand_glob() { $(declare -f _comp_expand_glob | tail -n +2) }"
17-
18-
# replace _comp_compgen_filedir
19-
_comp_compgen_filedir() {
20-
__bak_comp_compgen_filedir "$@"
21-
_pinyin_completion "$@"
22-
}
23-
24-
_comp_compgen_filedir_xspec() {
25-
__bak_comp_compgen_filedir_xspec "$@"
26-
_pinyin_completion "$@"
27-
}
28-
29-
_comp_complete_minimal() {
30-
__bak_comp_complete_minimal "$@"
31-
_pinyin_completion "$@"
32-
}
33-
34-
_comp_expand_glob() {
35-
__bak_comp_expand_glob "$@"
36-
_pinyin_completion "$@"
12+
# Backup the original function
13+
eval "function __bak_comp_compgen__call_builtin() { $(declare -f _comp_compgen__call_builtin | tail -n +2) }"
14+
15+
16+
_comp_compgen__call_builtin() {
17+
__bak_comp_compgen__call_builtin "$@"
18+
local original_result=$?
19+
20+
# Only add pinyin completion for file/directory completions
21+
local is_file_completion=false
22+
local compgen_args=("$@")
23+
24+
# Check for file completion indicators
25+
for arg in "${compgen_args[@]}"; do
26+
case "$arg" in
27+
-f|-d|-A|file|directory)
28+
is_file_completion=true
29+
break
30+
;;
31+
esac
32+
done
33+
34+
# If this looks like file completion, add pinyin matches
35+
if [[ "$is_file_completion" == true ]]; then
36+
_add_completion "$@"
37+
fi
38+
39+
return $original_result
3740
}
3841

39-
_pinyin_completion() {
40-
# Check COMP_WORDS existence
41-
if [ ${#COMP_WORDS[@]} -eq 0 ] || [ -z "${COMP_CWORD+x}" ]; then
42+
# Function to add completion results
43+
_add_completion() {
44+
# Check if we have the necessary variables
45+
if [[ -z "${_cur-}" ]] || [[ -z "${_var-}" ]]; then
4246
return
4347
fi
44-
45-
local cur="${COMP_WORDS[COMP_CWORD]}"
46-
47-
# Detect "~/"
48-
local homeStart
49-
if [ "${cur:0:2}" = "~/" ]; then
50-
homeStart=true
51-
else
52-
homeStart=false
53-
fi
54-
55-
# ignore empty
56-
[ -z "$cur" ] && return
57-
58-
_expand || return 0
59-
48+
49+
local cur="$_cur"
50+
local var_name="$_var"
51+
52+
# Skip empty
53+
[[ -z "$cur" ]] && return
54+
_expand || return 0
55+
56+
local dirpart basepart
6057
if [[ "${cur:0:1}" == "'" || "${cur:0:1}" == "\"" ]]; then
61-
local dirpart="$(dirname -- "${cur:1}")"
62-
local basepart="$(basename -- "${cur:1}")"
58+
dirpart="$(dirname -- "${cur:1}")"
59+
basepart="$(basename -- "${cur:1}")"
6360
else
64-
local dirpart="$(dirname -- "$cur")"
65-
local basepart="$(basename -- "$cur")"
61+
dirpart="$(dirname -- "$cur")"
62+
basepart="$(basename -- "$cur")"
6663
fi
67-
68-
# realpath resolve current path as ".", if user did not enter "./" then ignore.
64+
6965
[[ "$dirpart" == "." && "${cur:0:2}" != "./" ]] && dirpart=""
70-
66+
7167
local savedPWD="$PWD"
7268
local resolved_dir
7369
local compgen_opts=(-f)
74-
[[ "${1-}" == -d ]] && compgen_opts=(-d)
75-
70+
71+
local is_dir_only=false
72+
for arg in "$@"; do
73+
if [[ "$arg" == "-d" ]]; then
74+
is_dir_only=true
75+
compgen_opts=(-d)
76+
break
77+
fi
78+
done
79+
7680
if [[ -n "$dirpart" ]]; then
7781
resolved_dir="$(realpath -- "$dirpart" 2>/dev/null)"
7882
if [[ -d "$resolved_dir" ]]; then
@@ -82,60 +86,50 @@ _pinyin_completion() {
8286
return
8387
fi
8488
fi
85-
89+
8690
local -a pinyin_matched
87-
if [[ "${compgen_opts[0]}" == -d ]]; then
91+
if [[ "$is_dir_only" == true ]]; then
8892
mapfile -t pinyin_matched < <(
89-
compgen -d -- |
93+
compgen -d -- 2>/dev/null |
9094
bash-pinyin-completion-rs "$basepart" 2>/dev/null
91-
)
95+
)
9296
else
9397
mapfile -t pinyin_matched < <(
94-
compgen -f -- |
98+
compgen -f -- 2>/dev/null |
9599
bash-pinyin-completion-rs "$basepart" 2>/dev/null
96100
)
97-
if [ ${#pinyin_matched[@]} -ne 0 ]; then
98-
compopt -o filenames 2>/dev/null
99-
fi
100-
fi
101-
102-
if [[ -n "$dirpart" ]]; then
103-
local sep="/"
104-
# dirpart is root
105-
if [[ "$dirpart" == "/" ]]; then
106-
sep=""
107-
fi
108-
109-
for i in "${!pinyin_matched[@]}"; do
110-
pinyin_matched[$i]="${dirpart}${sep}${pinyin_matched[$i]}"
111-
done
112101
fi
113-
102+
103+
# Restore directory
114104
cd "$savedPWD" || return
115-
116-
# merge result
117-
local -a old_candidates=("${COMPREPLY[@]}")
118-
COMPREPLY=("${old_candidates[@]}" "${pinyin_matched[@]}")
119-
120-
# mapfile -t COMPREPLY < <(printf "%s\n" "${COMPREPLY[@]}" | awk '!seen[$0]++')
121-
declare -A seen
122-
local -a unique_compreply=()
123-
for item in "${COMPREPLY[@]}"; do
124-
if [[ -z "${seen[$item]}" ]]; then
125-
seen["$item"]=1
126-
unique_compreply+=( "$item" )
105+
106+
if [[ ${#pinyin_matched[@]} -gt 0 ]]; then
107+
if [[ -n "$dirpart" ]]; then
108+
local sep="/"
109+
[[ "$dirpart" == "/" ]] && sep=""
110+
111+
for i in "${!pinyin_matched[@]}"; do
112+
pinyin_matched[$i]="${dirpart}${sep}${pinyin_matched[$i]}"
113+
done
127114
fi
128-
done
129-
COMPREPLY=( "${unique_compreply[@]}" )
130-
131-
if [[ "$homeStart" == true ]]; then
132-
local home="$HOME"
133-
for i in "${!COMPREPLY[@]}"; do
134-
case "${COMPREPLY[$i]}" in
135-
"$home"/*)
136-
COMPREPLY[$i]="~${COMPREPLY[$i]#"$home"}"
137-
;;
138-
esac
115+
116+
117+
local current_results_var="current_results"
118+
eval "local -a $current_results_var=(\"\${$var_name[@]}\")"
119+
120+
# Merge results and remove duplicates
121+
local -a all_results
122+
eval "all_results=(\"\${$current_results_var[@]}\" \"\${pinyin_matched[@]}\")"
123+
124+
declare -A seen
125+
local -a unique_results=()
126+
for item in "${all_results[@]}"; do
127+
if [[ -z "${seen[$item]}" ]]; then
128+
seen["$item"]=1
129+
unique_results+=("$item")
130+
fi
139131
done
132+
133+
eval "$var_name=(\"\${unique_results[@]}\")"
140134
fi
141135
}

scripts/bash_pinyin_completion_debug

Lines changed: 0 additions & 125 deletions
This file was deleted.

0 commit comments

Comments
 (0)