3.8 KiB
3.8 KiB
Plan — kate-custom
Goal
Build a suite of Kate plugins that make the editor usable without menus, tuned to one specific operator profile:
- mouse-heavy, with the mouse used at the caret rather than at the menubar
- one-handed keyboard typing
- no complex chords; single modifier at most
- compact keyboard where F-keys/nav clusters sit behind a layer toggle
- long Emacs history and some Sublime Text;
M-xand type-to-filter palettes are familiar and welcome
The spine of the suite is a single action registry reached through three
interchangeable doors: M-x (keyboard), a radial caret menu (mouse), and the
: command line (optional). Every feature registers its commands once and
becomes reachable from all three. No action depends on an F-key or a chord.
Why a custom matcher is the keystone
Kate's built-in command bar cannot be fixed in place:
KCommandBar(KConfigWidgets) exposes onlysetActions(). There is no hook to replace or configure its matcher.KFuzzyMatcher(KCoreAddons) is single-needle, strictly in-order subsequence, and not typo tolerant. KDE's own docs state"gti"will not match"git". No orderless, no company-style completion.
Therefore the palette is replaced, not extended, and the replacement is built on
FuzzyRanker, a matcher with:
- orderless tokenization (space-separated needles matched in any order)
- layered scoring, strongest tier first:
- exact
- substring
- word-boundary initials (
rs-> Rename Symbol) - in-order subsequence
- bounded typo (one deletion; recovers transpositions like
gti->git)
- merged highlight ranges for the UI
- AND semantics across needles, case-folded, shorter-candidate preference
Milestones
M1 — FuzzyRanker (keystone) — DONE
- Repo scaffold: top-level CMake (KF6/Qt6/ECM),
src/,src/fuzzy/. src/fuzzy/fuzzyranker.{h,cpp}: tokenize + layered scoring + ranges.src/fuzzy/test_fuzzyranker.cpp: QTest suite, 14 cases, all green, includinggti -> gitandren sym -> Rename Symbol.
M2 — Palette widget (replaces KCommandBar) — NEXT
- Custom
QFrame: filterQLineEdit+ results list (model/view). - Live, company-style updates on every keystroke; top hit preselected;
Enterexecutes; matched characters highlighted viaMatchResult::ranges. - Consumes
FuzzyRanker. Pure Qt widget, independent of Kate for testability.
M3 — KTextEditor plugin + M-x + action registry
KTextEditor::Pluginskeleton producing a loadable.so.- Central action registry aggregating Kate built-in actions + plugin actions.
M-x(Alt+x) opens the M2 palette over the registry.- Frecency ranking: usage history feeds a score bonus.
M4 — Radial caret menu (mouse door)
- Mouse-triggered radial menu positioned at the caret
(
View::cursorToCoordinate), flick-to-select by angle. - Slices invoke registry actions; one slice opens the palette / command line, so the keyboard-expensive paths are never required.
M5 — Command vocabulary + project model + switchers
:-verb pack viaKTextEditor::Command:sort,align,json,b64,uuid,case,pipe <shell>, etc. These populate M-x and the radial.- Project = directory. "Open folder == open project" (VSCode/Sublime model);
no
.kateprojectceremony. - File / symbol switchers scoped to the opened folder (e.g.
git ls-files/fdfor files; LSP or ctags for symbols), all through the M2 palette.
Build and test
cmake -B build -S .
cmake --build build
ctest --test-dir build
# or directly:
QT_QPA_PLATFORM=offscreen ./build/bin/test_fuzzyranker
Environment facts (verified)
- Kate 25.12.3, KDE Frameworks 6, Qt 6.10, cmake 4.2.3, g++, extra-cmake-modules.
- KTextEditor + KCoreAddons + KConfigWidgets + KXmlGui + KRunner dev headers present.
- No Python/Pâté binding installed; C++ is the only first-class plugin path.