Dedup is now strictly by QAction pointer identity (functionally lossless:
the same action object listed once). Distinct actions are never collapsed.
When two distinct actions would show the same label, enrich it through a
fallback chain until every visible row is unique: component name ->
objectName -> shortcut -> numeric suffix. Ids remain unique so activation
always hits the intended action.
The same QAction is often reachable through multiple GUI clients; those
are true duplicates and are now collapsed by pointer identity. Distinct
actions that merely share a visible label (common across plugins) are kept
but disambiguated by appending the owning component's display name, and
every entry is assigned a unique, stable id so activating a row always
triggers the intended action rather than whichever one won a hash key.
- OlliePlugin (KTextEditor::Plugin) + OllieView, built as olliepalette.so
via kcoreaddons_add_plugin, installed under kf6/ktexteditor.
- M-x bound to Alt+X (single modifier, adjacent keys on a compact layout,
ApplicationShortcut so it is always live).
- On trigger, aggregates every enabled/visible QAction from the window's
guiFactory()->clients() action collections (keyed by objectName) and
shows them in PaletteWidget; the chosen row triggers the QAction. The
action's current shortcut is surfaced in the group column.
- Enable position-independent code for linking the static palette lib into
the shared plugin module.
- Plugin metadata verified valid via KPluginMetaData.
Frecency wiring deferred (model supports it; plugin passes 0). All three
ctest suites remain green.
- PaletteModel: QAbstractListModel ranking items via FuzzyRanker, with
id/label/group/score and highlight-range roles plus a frecency bonus.
Headless, unit-tested (10 cases).
- PaletteWidget: frameless popup with a filter line and results list.
Live company-style updates, top hit preselected, custom delegate bolds
matched characters. Keyboard (Up/Down/PageUp/PageDown/Enter/Esc, focus
kept in the filter) and mouse (click to activate). No chords.
- Tighten FuzzyRanker typo tolerance: single adjacent transposition instead
of deletion. Still recovers 'gti'->'git' but no longer false-matches
'ren' against 'Open File'.
All tests green: fuzzyranker (14) + palettemodel (10).