You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[Bug]: Text replacements never match Chinese/Japanese text (word boundary treats CJK as word characters) #177
Text replacements never fire when the phrase sits inside text written in a script that does not separate words with spaces. A replacement like 一首 -> issue only matches when it sits at the start or end of the transcript, or next to an ASCII space or punctuation. Inside a running Chinese sentence every neighbour is a Han character, so the boundary check rejects every occurrence.
The same failure applies to Japanese, Thai, Lao, Khmer, Myanmar (Burmese), Tibetan, and — differently — Korean, where spaces exist but particles attach to the word they modify (사과를), so a rule matching 사과 is still rejected.
Why
src/text_replacements.rs:196-210:
fnphrase_boundary(text:&str,start:usize,end:usize) -> bool{let before = text[..start].chars().next_back();let after = text[end..].chars().next();
!before.is_some_and(word_character) && !after.is_some_and(word_character)}fnword_character(character:char) -> bool{
...Regex::new(r"^\w$").expect("Unicode word regex must compile")}
\w in the Unicode-aware regex crate includes Han, Kana, Hangul, Thai, Lao, Khmer, Myanmar, and Tibetan letters. For 这是一首颜色 the char before 一首 is 是 and the char after is 颜; both sides count as word characters and the boundary check fails. There is no setting that can express a replacement in any of these languages today.
Steps to reproduce
Settings -> text replacements, add 一首 -> issue.
Dictate 让我看一下,一首颜色,严肃. The transcript is unchanged.
The same replacement does apply when the phrase is surrounded by ASCII spaces.
Expected
Replacements should match in scripts that do not delimit words with spaces, since the boundary check cannot express anything there.
Suggested direction
Treat characters of the unspaced scripts as boundary-transparent and keep \w for space-delimited scripts:
fnword_character(character:char) -> bool{space_delimited_script(character) && (character.is_alphanumeric() || character == '_')}
with space_delimited_script false for \p{Han}, \p{Hiragana}, \p{Katakana}, \p{Hangul}, \p{Thai}, \p{Lao}, \p{Khmer}, \p{Myanmar}, \p{Tibetan}. This keeps reissues and übercool blocked while letting 这个issue很重要 match. A per-replacement "match anywhere" toggle would also work and is more explicit, but it puts the burden on every user of these languages.
Related but distinct: #139 covers a replacement being skipped when a match overlaps a word boundary. This one is that these sentences never get past the boundary check at all.
Thanks for reporting this! We're working on a brand-new version of Hex (rebuilt from the ground up), and it'll be out soon. This issue is about the current release, so we're closing it to keep the tracker focused on the new version. You can try the new dev build now — download links are in the README: https://github.com/anomalyco/hex#install-hex. If this still happens on the dev build, please open a new issue (or reply here) and we'll take a look.
Activity
thdxr commentedon Oct 28, 2026
Thanks for reporting this! We're working on a brand-new version of Hex (rebuilt from the ground up), and it'll be out soon. This issue is about the current release, so we're closing it to keep the tracker focused on the new version. You can try the new dev build now — download links are in the README: https://github.com/anomalyco/hex#install-hex. If this still happens on the dev build, please open a new issue (or reply here) and we'll take a look.
— from 𝕺𝖕𝖊𝖓𝕮𝖔𝖉𝖊