fix: Telex 'r' (hỏi) consumed as tone key even with no vowel

- Tone keys (f,s,r,x,j) now only apply when composition has a vowel
- Without a vowel, they fall through to normal character append
- Fixes 'r' disappearing in words like 'trời', 'trâm', 'trảm'
- Added test_telex_r_as_normal_char covering 4 scenarios
- Also: 15ms delay between clipboard paste and trailing uinput chars
This commit is contained in:
Khoa Vo 2026-06-26 15:48:58 +07:00
parent 0028c4809f
commit 9dfd86248d

View file

@ -89,12 +89,18 @@ impl BambooEngine {
self.macro_buf.clear(); self.macro_buf.clear();
} }
// Check tone keys // Check tone keys — only apply if composition has a vowel, else treat as normal char
if let Some(&(tone_char, _tone_name)) = self.rules.tone_keys.get(&lower) { if let Some(&(tone_char, _tone_name)) = self.rules.tone_keys.get(&lower) {
let has_vowel = self.composition.iter().any(|t| {
is_vowel(t.mark_applied.unwrap_or(t.base_char))
});
if has_vowel {
return self.apply_tone(tone_char); return self.apply_tone(tone_char);
} }
// Fall through: append as normal character
}
// Smart "uo" → "ươ" shortcut with flexible backtrack: // Smart "uo" → "ươ" shortcut with flexible backtrack":
// Scan backward through consonants to find the "uo" pair // Scan backward through consonants to find the "uo" pair
if self.rules.method == InputMethod::Telex && lower == 'w' if self.rules.method == InputMethod::Telex && lower == 'w'
|| self.rules.method == InputMethod::Vni && lower == '7' || self.rules.method == InputMethod::Vni && lower == '7'
@ -123,7 +129,7 @@ impl BambooEngine {
} }
} }
// Try mark rules with flexible backtrack (scan up to 3 chars backward) // Try mark rules with flexible backtrack" (scan up to 3 chars backward)
let mark_match = self.find_mark_backtrack(lower); let mark_match = self.find_mark_backtrack(lower);
if let Some((idx, pattern, result)) = mark_match { if let Some((idx, pattern, result)) = mark_match {
@ -560,4 +566,31 @@ fn test_telex_gios() {
} }
#[test]
fn test_telex_r_as_normal_char() {
let mut e = BambooEngine::new(InputMethod::Telex);
let mut out = String::new();
for ch in "tr".chars() {
if let Some(o) = e.process_key(ch) { out = o; }
}
assert_eq!(out, "tr");
out.clear(); e.reset();
for ch in "traf".chars() {
if let Some(o) = e.process_key(ch) { out = o; }
}
assert_eq!(out, "trà");
out.clear(); e.reset();
for ch in "tar".chars() {
if let Some(o) = e.process_key(ch) { out = o; }
}
assert_eq!(out, "tả");
out.clear(); e.reset();
for ch in "tramr".chars() {
if let Some(o) = e.process_key(ch) { out = o; }
}
assert_eq!(out, "trảm");
}
} }