Add accent-insensitive search option#13215
Add accent-insensitive search option#13215yyyyyyyan wants to merge 3 commits intokeepassxreboot:developfrom
Conversation
|
A couple of things I'd like to get input on:
|
There was a problem hiding this comment.
Pull request overview
Adds a user-facing search toggle to control accent/diacritics sensitivity in the KeePassXC GUI, wiring it through the existing SearchWidget → DatabaseWidget → EntrySearcher flow and implementing Unicode NFD + combining-mark stripping when accent-insensitive matching is enabled.
Changes:
- Add an “Accent sensitive” toggle to the search menu and persist it via a new GUI config key.
- Extend
EntrySearcherto support accent-insensitive matching by stripping diacritics from both query terms and searched fields (with an ASCII fast path). - Add unit tests covering accent-insensitive matching across fields/modifiers and interactions with case sensitivity.
Reviewed changes
Copilot reviewed 12 out of 12 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
tests/TestEntrySearcher.h |
Adds a new test slot for accent-insensitive search. |
tests/TestEntrySearcher.cpp |
Introduces comprehensive coverage for accent-insensitive search behavior and modifiers. |
src/gui/SearchWidget.h |
Adds signal/slot and action member for the new toggle. |
src/gui/SearchWidget.cpp |
Adds the menu action, persists the setting, and emits the new policy signal on DB changes. |
src/gui/DatabaseWidget.h |
Adds a slot to apply the accent-sensitivity setting to searching. |
src/gui/DatabaseWidget.cpp |
Initializes EntrySearcher from config and applies updates via setSearchAccentSensitive(). |
src/core/Tools.h |
Declares Tools::stripDiacritics() utility. |
src/core/Tools.cpp |
Implements diacritics stripping via NFD decomposition + combining-mark removal (ASCII fast path). |
src/core/EntrySearcher.h |
Extends constructor/state with accentSensitive and adds setters/getters. |
src/core/EntrySearcher.cpp |
Applies diacritics stripping to both parsed terms (regex source) and matched fields/lists. |
src/core/Config.h |
Adds new config key GUI_SearchAccentSensitive. |
src/core/Config.cpp |
Registers the new config key with default true (accent-sensitive). |
|
I am a fan of making the default more "liberal" and actually remove the option entirely. We already have an "exact match" prefix (ie, |
|
@droidmonkey done! |
EntrySearcher was always initialized with accentSensitive=true (constructor default), ignoring the user's saved config. Due to a signal/multiplexer race in the database open sequence, the config value from the UI toggle never reached the new DatabaseWidget. Now read the config directly at construction time.
Search is now accent-insensitive by default — no config option needed. The + (exact match) modifier implicitly enables accent-sensitive matching per-term, giving users fine-grained control without a separate UI toggle. This removes the GUI_SearchAccentSensitive config key, the menu action, and the EntrySearcher accentSensitive member in favor of a per-SearchTerm accentSensitive flag.
fff3bb3 to
782b5f7
Compare
| QString word; | ||
| QRegularExpression regex; | ||
| bool exclude; | ||
| bool accentSensitive; |
There was a problem hiding this comment.
SearchTerm::accentSensitive defaults to false when callers value-initialize SearchTerm{} (e.g. src/fdosecrets/objects/Collection.cpp:279), which makes programmatic searches silently become accent-insensitive. This changes existing behavior for callers that use EntrySearcher::search(const QList<SearchTerm>&, ...) and currently rely on exact (diacritic-sensitive) matching (notably Secret Service attribute matching built with EXACT_MATCH | CASE_SENSITIVE). Consider giving accentSensitive a default member initializer of true (so programmatic terms remain accent-sensitive unless explicitly overridden) while keeping parseSearchTerms() setting it based on the + modifier.
| bool accentSensitive; | |
| bool accentSensitive = true; |
|
@droidmonkey is anything needed on my end? Let me know if it needs any adjustments!! |
|
Nope you are gtg, I just need to manually test this to confirm functionality |
Make search accent-insensitive by default: both the search term and
entry field values are normalized by decomposing to Unicode NFD and
stripping combining marks, so that e.g. "pouzivatel" matches "používateľ"
and vice versa.
The
+(exact match) modifier implicitly forces accent-sensitive matchingper-term, giving users fine-grained control without a separate UI toggle.
For example,
+cafématches only "café" and not "cafe".AI Disclosure: This PR was developed with assistance from Claude (Opus 4.6). I created an implementation plan in an interactive session with Claude, and Claude executed the initial implementation. After my review and tests I manually refined the code (added ASCII fast path, added some edge-case unit tests, fixed signal/multiplexer race condition in db open sequence).
Fixes #6181
Screenshots
Accent-insensitive search (default): "testingabc" matches accented entry "téstîñgàbç":

Exact match (+) forces accent-sensitive: "+testingabc" does not match accented entry:

Exact match (+) with accented query: "+téstîñgàbç" matches the accented entry:

Testing strategy
testAccentInsensitiveSearchtoTestEntrySearchercovering:Type of change