fix: Hebrew/Arabic diacritics support + highlight corrections - #520
Open
david-hoze wants to merge 2 commits into
Open
fix: Hebrew/Arabic diacritics support + highlight corrections#520david-hoze wants to merge 2 commits into
david-hoze wants to merge 2 commits into
Conversation
- Strip Hebrew nikud (U+0591-U+05C7) and optional Arabic harakat in removeDiacritics - Use query terms for highlighting instead of MiniSearch result.terms (avoids fuzzy false highlights) - Disable fuzziness for terms length <= 4 to avoid e.g. ׳×׳§׳™׳© matching ׳×׳§׳•׳� - When ignore diacritics: match on original text with optional-diacritics regex so highlight indices and spans are correct (was using normalized-text indices on original, causing wrong highlights) Co-authored-by: Cursor <cursoragent@cursor.com>
…in diacritics regex Co-authored-by: Cursor <cursoragent@cursor.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Issue filed first: Closes #373
Problem
With "Ignore diacritics" enabled, Hebrew (and Arabic) search is broken in multiple ways:
No diacritics stripping — Searching
תקוןdoesn't findתִּקּוּןbecause Hebrew nikud (and Arabic harakat) aren't removed by the current\p{Diacritic}approach, which only covers Latin combining marks.Wrong highlights — Even when results are found, highlights land on the wrong words (e.g. unrelated word parts scattered in excerpts), because match indices from the normalized (shorter) text are applied to the original (longer) text with nikud, cutting the wrong character spans. see:
foundWordswas populated from MiniSearch'sresult.terms, which includes fuzzy expansions, so words the user never searched for get highlighted.Root causes and fixes
Fix 1 — Diacritics stripping (
src/tools/utils.ts)removeDiacritics()uses\p{Diacritic}after NFD normalization, which covers Latin combining marks but not Hebrew nikud (U+0591–U+05C7) or Arabic harakat. These characters aren't decomposed by NFD, so they survive stripping.→ Add explicit stripping of Hebrew nikud (U+0591–U+05BD, U+05BF–U+05C7) and, when
ignoreArabicDiacriticsis on, Arabic harakat. Maqaf (U+05BE ־) is deliberately excluded — it's a hyphen, not a diacritic; stripping it would merge words likeאֶת־הָאָרֶץintoאתהארץ.Fix 2 — Match on original text (
src/tools/text-processing.ts)The highlight code ran the match regex on normalized (shorter) text but used the resulting indices to slice the original (longer) text. Indices don't line up, so the wrong span was highlighted.
→ When "Ignore diacritics" is on, build a regex that matches each query word with optional diacritics between base letters and run it on the original text. Then
match.indexandmatch[0]refer to the real positions and the actual matched string. The regex does not use\bword boundaries — they're unreliable with Hebrew in many JS engines; the pattern is matched anywhere, and prefix matches (e.g.תק→תקון) still work.Fix 3 — Highlight from query terms, not result.terms (
src/search/search-engine.ts)foundWordswas populated from MiniSearch'sresult.terms, which includes fuzzy expansions (e.g.תקישwhen searchingתקון).→ Use
query.query.text,query.getExactTerms(), andquery.getTags()forfoundWordsinstead. Only the user's actual search terms are highlighted. Deduplicated withnew Set().Fix 4 — Best match for excerpt (
src/tools/text-processing.ts)The "best match" logic used
text.indexOf()on normalized text, producing an index that didn't correspond to the original text.→ Find the best match by comparing the normalized version of each actual match to the query, then promote that match to the front of the results array.
Testing
תקון→ findsתִּקּוּןin pointed text ✓café→cafe) still work ✓אֶת־הָאָרֶץdoesn't merge intoאתהארץ✓Adherence to contributing guidelines
תקוןnow bring relevant results and correct highlights; no extra interactions or toggles; existing 100-match / 50ms limits keep results fast..tsfiles modified; formatted with Prettier ESLint.