Skip to content

Commit f2ae1c7

Browse files
committed
refactor: new completion logic
Signed-off-by: wxiwnd <[email protected]>
1 parent 4bbb0b7 commit f2ae1c7

File tree

2 files changed

+65
-22
lines changed

2 files changed

+65
-22
lines changed

scripts/bash_pinyin_completion

Lines changed: 56 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -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
}

src/main.rs

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use ib_pinyin::{matcher::PinyinMatcher, pinyin::PinyinNotation};
2+
use std::io::{BufRead, BufReader};
23

34
fn main() {
45
let args: Vec<String> = std::env::args().collect();
@@ -10,26 +11,17 @@ fn main() {
1011

1112
let input: &str = &args[1];
1213
let matcher = PinyinMatcher::builder(input)
13-
.pinyin_notations(PinyinNotation::Ascii | PinyinNotation::AsciiFirstLetter)
14-
.build();
14+
.pinyin_notations(PinyinNotation::Ascii | PinyinNotation::AsciiFirstLetter)
15+
.build();
1516

1617
let han_re = regex::Regex::new(r"\p{Han}").unwrap();
1718

18-
let mut results: Vec<String> = Vec::new();
19-
// Read current location
20-
if let Ok(entries) = std::fs::read_dir(".") {
21-
for entry in entries.flatten() {
22-
let path = entry.path();
23-
if let Some(file_name) = path.file_name() {
24-
if let Some(file_name_str) = file_name.to_str() {
25-
if matcher.is_match(file_name_str) && han_re.is_match(file_name_str) {
26-
results.push(file_name_str.to_string());
27-
}
28-
}
29-
}
19+
let stdin = std::io::stdin();
20+
let reader = BufReader::new(stdin.lock());
21+
for line_result in reader.lines() {
22+
let candidate = line_result.unwrap().trim_end().to_string();
23+
if han_re.is_match(&candidate) && matcher.is_match(&candidate) {
24+
println!("{}", candidate);
3025
}
3126
}
32-
for result in results {
33-
println!("{}", result);
34-
}
3527
}

0 commit comments

Comments
 (0)