Skip to content

Fix incorrect pinyin comparision for polyphonic characters (e.g. 重启) & Add related UI for polyphonic parsing & Refactor PinyinAlphabet logic - #4544

Open
SparkUiX wants to merge 12 commits into
Flow-Launcher:devfrom
SparkUiX:codex/flow-pinyin-polyphonic-restart
Open

Fix incorrect pinyin comparision for polyphonic characters (e.g. 重启) & Add related UI for polyphonic parsing & Refactor PinyinAlphabet logic#4544
SparkUiX wants to merge 12 commits into
Flow-Launcher:devfrom
SparkUiX:codex/flow-pinyin-polyphonic-restart

Conversation

@SparkUiX

@SparkUiX SparkUiX commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

Summary

  • add a limited pinyin override for the Chinese phrase 重启
  • allow 重启 and 重启 Flow Launcher to match queries like chongqi
  • add unit tests for the polyphonic phrase and the fuzzy match behavior
image

Scope

This does not try to solve every Chinese polyphonic character case. It fixes the common built-in command phrase from #3955 while keeping the behavior for 重庆 as Chong Qing.

Tests

  • dotnet test Flow.Launcher.Test\Flow.Launcher.Test.csproj --filter "FullyQualifiedName~PinyinAlphabetTest"
  • dotnet test Flow.Launcher.Test\Flow.Launcher.Test.csproj --no-restore --filter "FullyQualifiedName~PinyinAlphabetTest|FullyQualifiedName~FuzzyMatcherTest"

Fixes #3955


Summary by cubic

Summary of changes
Improves Pinyin matching for Chinese polyphonic phrases (e.g., 重启) by applying phrase-level overrides and making PinyinAlphabet config/cache thread-safe. Old behavior read 重启 as Zhong Qi; new behavior reads Chong Qi, works with Double Pinyin, and prevents stale results when settings change.

  • Changed logic/behavior: PinyinAlphabet now uses an immutable config snapshot with a lock and a revisioned cache; discards builds if settings change mid-translate; applies phrase overrides before Double Pinyin; reloads on ShouldUsePinyin, UseDoublePinyin, DoublePinyinSchema, and UsePolyphonicPhraseOverrides.
  • New logic/behavior: Loads phrase-level overrides from Resources/polyphonic_pinyin.json to correct common polyphonic words; adds UsePolyphonicPhraseOverrides (default on) with UI and localized strings; JSON loaders accept comments and fail safe; project copies the new resource at build; internal constructor allows injecting a pinyin source for tests; updated Settings card icon glyph.
  • Removed: None.
  • Memory: Additional RAM for the in-memory phrase map when overrides are enabled; no added memory when disabled.
  • Security: Reads only bundled local JSON; no new permissions; robust error handling and fallback on failure.
  • Unit tests: Cover overrides on/off and runtime toggles, cache invalidation on setting changes, precedence over Double Pinyin, fuzzy matching for “重启” via “chongqi” and Double Pinyin, and prevention of publishing stale results.

Release Note
Typing “chongqi” now finds the Restart command, and Pinyin results for many Chinese phrases are more accurate, even with Double Pinyin enabled.

Written for commit ea5d823. Summary will update on new commits.

Review in cubic

Copilot AI review requested due to automatic review settings June 23, 2026 16:56
@github-actions github-actions Bot added this to the 2.2.0 milestone Jun 23, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes pinyin matching for the built-in Chinese restart command phrase 重启 by introducing a small phrase-level override so that queries like chongqi correctly match 重启 (and 重启 Flow Launcher) while preserving existing behavior for unrelated polyphonic words like 重庆.

Changes:

  • Added a polyphonic phrase override map in PinyinAlphabet and applied it during pinyin cache construction.
  • Refactored PinyinAlphabet to support Settings injection (improves testability).
  • Added unit tests covering the 重启 override and fuzzy matching for chongqi.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
Flow.Launcher.Infrastructure/PinyinAlphabet.cs Adds a targeted override for 重启 pinyin output and enables Settings injection for deterministic behavior in tests.
Flow.Launcher.Test/PinyinAlphabetTest.cs Adds unit tests validating translation and fuzzy-match behavior for 重启/chongqi, plus a regression check for 重庆.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 2 files

Re-trigger cubic

@coderabbitai

coderabbitai Bot commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

PinyinAlphabet now loads phrase-level pronunciation overrides from a JSON resource. It applies overrides before Pinyin and double-Pinyin conversion. Revisioned configuration snapshots prevent stale translation results after settings changes. The settings UI and tests cover the new behavior.

Changes

Polyphonic Phrase Pinyin Override

Layer / File(s) Summary
Override setting and resource wiring
Flow.Launcher.Infrastructure/UserSettings/Settings.cs, Flow.Launcher/Flow.Launcher.csproj, Flow.Launcher/Languages/en.xaml, Flow.Launcher/SettingPages/...
Adds UsePolyphonicPhraseOverrides, change notifications, the bundled JSON resource, localized strings, and a Pinyin-dependent settings toggle.
Override loading and cache integration
Flow.Launcher.Infrastructure/PinyinAlphabet.cs
Adds injected settings, immutable configuration snapshots, comment-tolerant JSON loading, error fallback, phrase-length tracking, synchronized reloads, cache invalidation, longest-first phrase matching, and explicit double-Pinyin tables.
Translation and fuzzy-match validation
Flow.Launcher.Test/PinyinAlphabetTest.cs
Tests phrase overrides, disabled overrides, cache invalidation, XiaoHe conversion, override precedence, fuzzy matching, and stale-result suppression during concurrent settings changes.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Settings
  participant PinyinAlphabet
  participant PinyinProvider
  Settings->>PinyinAlphabet: Change phrase-override setting
  PinyinAlphabet->>PinyinAlphabet: Reload snapshot and invalidate cache
  PinyinAlphabet->>PinyinProvider: Generate character Pinyin
  PinyinProvider-->>PinyinAlphabet: Return Pinyin tokens
  PinyinAlphabet->>PinyinAlphabet: Apply phrase overrides
  PinyinAlphabet->>PinyinAlphabet: Convert using double-Pinyin configuration
Loading

Possibly related PRs

Suggested reviewers: taooceros, victoriousraptor, jjw24

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The changes address issue #3955 by enabling matching for 重启 and preserving context-dependent pronunciation behavior.
Out of Scope Changes check ✅ Passed The configuration, UI, resource, caching, conversion, and test changes support the linked issue and stated PR objectives.
Title check ✅ Passed The title accurately identifies the polyphonic Pinyin fix and related UI and refactoring changes.
Description check ✅ Passed The description clearly explains the polyphonic Pinyin fix, scope, UI changes, and associated tests.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
Flow.Launcher.Infrastructure/PinyinAlphabet.cs (1)

185-188: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Defensively validate override span writes.

The override loop assumes phrase length and pinyin token count always align. A future bad entry can throw IndexOutOfRangeException at Line 187. Add a guard before writing the span to keep translation resilient.

Suggested hardening
                 while (index >= 0)
                 {
+                    if (pinyin.Length != phrase.Length || index + pinyin.Length > resultList.Length)
+                    {
+                        index = content.IndexOf(phrase, index + phrase.Length, StringComparison.Ordinal);
+                        continue;
+                    }
+
                     for (var i = 0; i < pinyin.Length; i++)
                     {
                         resultList[index + i] = pinyin[i];
                     }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Flow.Launcher.Infrastructure/PinyinAlphabet.cs` around lines 185 - 188, The
loop at line 185-188 that writes pinyin characters to resultList lacks bounds
validation and assumes the phrase length always matches the pinyin token count.
Add a guard condition before the for loop that iterates over pinyin to validate
that index plus pinyin.Length does not exceed resultList.Length, preventing
potential IndexOutOfRangeException when future bad entries are encountered. If
the bounds check fails, handle it gracefully by skipping the write or logging a
warning to keep the translation resilient.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@Flow.Launcher.Infrastructure/PinyinAlphabet.cs`:
- Around line 31-33: The PinyinAlphabet constructor does not validate that the
injected settings parameter is null before assigning it to the _settings field.
Add a null guard at the beginning of the PinyinAlphabet constructor that throws
an ArgumentNullException if the settings parameter is null, ensuring the error
fails fast instead of allowing a NullReferenceException to occur later when
_settings is dereferenced.

---

Nitpick comments:
In `@Flow.Launcher.Infrastructure/PinyinAlphabet.cs`:
- Around line 185-188: The loop at line 185-188 that writes pinyin characters to
resultList lacks bounds validation and assumes the phrase length always matches
the pinyin token count. Add a guard condition before the for loop that iterates
over pinyin to validate that index plus pinyin.Length does not exceed
resultList.Length, preventing potential IndexOutOfRangeException when future bad
entries are encountered. If the bounds check fails, handle it gracefully by
skipping the write or logging a warning to keep the translation resilient.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 19d08c6a-e4e2-492c-adb9-1621554a762a

📥 Commits

Reviewing files that changed from the base of the PR and between 5413d40 and 410db08.

📒 Files selected for processing (2)
  • Flow.Launcher.Infrastructure/PinyinAlphabet.cs
  • Flow.Launcher.Test/PinyinAlphabetTest.cs

Comment thread Flow.Launcher.Infrastructure/PinyinAlphabet.cs
@VictoriousRaptor

Copy link
Copy Markdown
Contributor

Nice workaround. Our 3rd party pinyin nuget is not good while dealing with polyphonic.

@Jack251970 Jack251970 added the bug Something isn't working label Jun 25, 2026

@Jack251970 Jack251970 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! Could you please add more pairs in PolyphonicPhraseOverrides? Currently, we just have one pair in it.

Here is some tools for your reference: https://chatgpt.com/share/6a428475-1ba4-83ea-b48c-ef9ab02c3859.

@Jack251970
Jack251970 marked this pull request as draft August 7, 2026 08:36
Significantly increased the polyphonic pinyin dictionary by adding many new Chinese words, idioms, place names, and technical terms with accurate pinyin mappings. No existing entries were modified or removed; all changes are additive and improve pinyin conversion coverage.
@Jack251970 Jack251970 changed the title Fix pinyin match for Chinese restart command Fix pinyin match for Chinese restart command & Fix incorrect pinyin highlight for polyphonic characters Aug 7, 2026
- Load polyphonic phrase data from `polyphonic_pinyin.json`
- Add `UsePolyphonicPhraseOverrides` setting with UI and localization
- Apply phrase-level overrides in `PinyinAlphabet` with cache invalidation
- Add tests for override enabled, disabled, and toggled at runtime
- Update project file to deploy new resource file
The _usePolyphonicPhraseOverrides field in Settings.cs now defaults to true instead of false, making UsePolyphonicPhraseOverrides enabled by default.
Added three unit tests in PinyinAlphabetTest.cs to verify:
- Polyphonic phrase overrides take precedence over double pinyin.
- Double pinyin enabled after caching respects polyphonic overrides.
- Fuzzy matching uses override pronunciation with both features enabled.
@Jack251970
Jack251970 marked this pull request as ready for review August 7, 2026 09:11
@cubic-dev-ai

cubic-dev-ai Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

This PR has 238,359 reviewable changed lines after ignored/generated files are excluded, above cubic's default 50,000-changed-line automatic review limit.

Most of the diff comes from:

  • Flow.Launcher/Resources/polyphonic_pinyin.json (~238,087 changed lines)
  • Flow.Launcher.Test/PinyinAlphabetTest.cs (~124 changed lines)
  • Flow.Launcher.Infrastructure/PinyinAlphabet.cs (~105 changed lines)
  • Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml (~17 changed lines)
  • Flow.Launcher.Infrastructure/UserSettings/Settings.cs (~15 changed lines)

Comment @cubic-dev-ai review this to review it anyway. If the largest files are generated or fixture data, add them to your ignored files in review settings or ignorePatterns in cubic.yaml - cubic will then review the rest automatically. You can also raise this limit in review settings.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@Flow.Launcher.Infrastructure/PinyinAlphabet.cs`:
- Around line 36-59: Make cache invalidation atomic with cache construction in
the settings-change handler and the cache flow around BuildCacheFromContent:
synchronize replacement of pronunciation tables and maxPolyphonicPhraseLength
with cache lookup and publication, ensuring a worker cannot publish results
built from stale settings after _pinyinCache.Clear(). Alternatively, add a
configuration revision to each cache entry and reject results built against an
older revision.

In `@Flow.Launcher/Flow.Launcher.csproj`:
- Around line 181-183: Add a None item for Resources\polyphonic_pinyin.json in
Flow.Launcher.Test.csproj with CopyToOutputDirectory set to PreserveNewest,
matching the existing resource staging pattern so PinyinAlphabet can load the
test override from AppContext.BaseDirectory.

In `@Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml`:
- Around line 563-578: Update the SettingsPaneGeneralViewModel.ShouldUsePinyin
setter to raise PropertyChanged after changing the setting, so the Visibility
binding on the UsePolyphonicPhraseOverrides SettingsCard refreshes immediately
when Pinyin is toggled.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: cea32d0f-5ea9-44e1-afe5-01cc860e4a61

📥 Commits

Reviewing files that changed from the base of the PR and between f9ac9b7 and aa09301.

📒 Files selected for processing (8)
  • Flow.Launcher.Infrastructure/PinyinAlphabet.cs
  • Flow.Launcher.Infrastructure/UserSettings/Settings.cs
  • Flow.Launcher.Test/PinyinAlphabetTest.cs
  • Flow.Launcher/Flow.Launcher.csproj
  • Flow.Launcher/Languages/en.xaml
  • Flow.Launcher/Resources/polyphonic_pinyin.json
  • Flow.Launcher/SettingPages/ViewModels/SettingsPaneGeneralViewModel.cs
  • Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml

Comment thread Flow.Launcher.Infrastructure/PinyinAlphabet.cs
Comment thread Flow.Launcher/Flow.Launcher.csproj
Comment thread Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml
Refactored PinyinAlphabet to encapsulate configuration in an immutable PinyinConfiguration record, protected by a lock. Updated pinyin cache to use content and config revision as key, preventing stale translations after settings changes. Rewrote Translate to handle concurrent config changes and avoid publishing outdated results. Made table/override loaders static and return values. Added unit test to ensure stale results are not published if config changes during translation. Improves correctness and thread safety during config updates.
@Jack251970 Jack251970 added the enhancement New feature or request label Aug 7, 2026
Jack251970
Jack251970 previously approved these changes Aug 8, 2026
@Jack251970 Jack251970 changed the title Fix pinyin match for Chinese restart command & Fix incorrect pinyin highlight for polyphonic characters Fix incorrect pinyin highlight for polyphonic characters (e.g. 重启) & Add related UI for polyphonic parsing & Refactor PinyinAlphabet logic Aug 8, 2026
@Jack251970 Jack251970 changed the title Fix incorrect pinyin highlight for polyphonic characters (e.g. 重启) & Add related UI for polyphonic parsing & Refactor PinyinAlphabet logic Fix incorrect pinyin comparision for polyphonic characters (e.g. 重启) & Add related UI for polyphonic parsing & Refactor PinyinAlphabet logic Aug 10, 2026
@Jack251970

Copy link
Copy Markdown
Member

@VictoriousRaptor Sorry for any misleading in the title of this PR.

I have not fixed pinyin highlight for polyphonic characters in this PR. So could you please merged the changes of #4607 into this PR if the changes are pretty minor?

If you think there are plenty of changes to fix the polyphonic highlight, I think we can merge this PR first and then you can continue your fix in another PR.

Changed the glyph icon in the SettingsCard header from "&#xE8D7;" to "&#xF87E;" for improved UI consistency. No functional changes were made.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 8 changed files in this pull request and generated no new comments.

Suppressed comments (2)

Flow.Launcher.Infrastructure/PinyinAlphabet.cs:86

  • Every relevant settings change rebuilds both resources, so changing only the double-pinyin schema synchronously reparses and reallocates the entire 47,111-entry phrase dictionary while holding _configurationLock. This runs from the settings property-change callback and can stall the UI while also blocking translations. Cache the immutable phrase data after its first load, or reload only the resource affected by the changed setting instead of recreating both tables on every revision.
            var doublePinyinTable = LoadDoublePinyinTable(useDoublePinyin, doublePinyinSchema);
            var (polyphonicPhraseOverrides, maxPolyphonicPhraseLength) =
                LoadPolyphonicPhraseOverrides(shouldUsePinyin, usePolyphonicPhraseOverrides);

Flow.Launcher.Infrastructure/PinyinAlphabet.cs:320

  • The override data uses spellings such as , , and Lüe, but the existing double-pinyin tables only accept the ToolGood-style keys Nv, Lv, and Lve. Assigning those values unchanged means ToDoublePinyin falls back to the full syllable, so phrases such as 女儿 and 略知一二 cannot be matched with their configured double-pinyin forms (and full-pinyin nv/lv queries also diverge from the library output). Normalize the override syllables to the same v convention before storing them, and add an umlaut-case test.
                        resultList[start + i] = pinyin[i];

@VictoriousRaptor

Copy link
Copy Markdown
Contributor

@VictoriousRaptor Sorry for any misleading in the title of this PR.

I have not fixed pinyin highlight for polyphonic characters in this PR. So could you please merged the changes of #4607 into this PR if the changes are pretty minor?

If you think there are plenty of changes to fix the polyphonic highlight, I think we can merge this PR first and then you can continue your fix in another PR.

#4607 may have performance issue in some cases because it matches every potential polyphonic combinations. I thought it was some issue unrelated to polyphonic so assigned it to Copilot.

@VictoriousRaptor

VictoriousRaptor commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

I have an idea about the issue: instead of creating our patch for polyphonic characters, use another external library (like ib_matcher)for MATCHING Chinese queries rather than just converting Chinese to pinyin and use our fuzzy matcher to match.

Another feasible solutions besides creating our own solution: fixing the dictionary of ToolGoods.Pinyin(may solve "重启" and “核查”).

Any thoughts? @SparkUiX @Jack251970

Comment thread Flow.Launcher.Test/PinyinAlphabetTest.cs
@VictoriousRaptor

Copy link
Copy Markdown
Contributor

I think the PR is good to go. But can we check the json have some redundant phrases in ToolGood's dictionary?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

BUG: Chinese polyphonic characters pinyin search issue

4 participants