# kate-custom A suite of Kate plugins for people who despise menus. The aim is a text editor that is driven by the mouse at the cursor and by plain-letter keyboard input — never by hunting through nested menubars or memorizing complex chords. ## Design constraints These are hard constraints that shape every decision: - **Mouse-heavy.** The fastest input is the mouse, used *locally* at the caret (radial / floating surfaces), not a trek to the menubar. - **One-handed typing.** Keyboard input must work comfortably with one hand. - **No complex chords.** Single modifier at most (`Ctrl`+letter). No leader-key chord trees, no multi-cursor keybinds. - **Compact keyboard.** F-keys and nav clusters live on a layer toggle, so they carry extra cognitive cost and are avoided as primary triggers. - **Emacs/Sublime fluency.** `M-x` (`Alt+x`) is comfortable and welcome as a primary keyboard entry point, as is a Sublime-style type-to-filter palette. ### Unifying principle > **One action registry. Three doors onto it:** > **`M-x` (keyboard), a radial caret menu (mouse), and the `:` command line (optional).** > **No action requires an F-key or a chord.** ## Why not just use Kate's command bar? Kate's `KCommandBar` is a sealed widget: it accepts a list of actions via `setActions()` and exposes **no hook** to customize its matcher. Its matcher, `KFuzzyMatcher`, is single-needle, strictly in-order subsequence, with **no typo tolerance** — by KDE's own documentation, `"gti"` will not match `"git"`. There is no "orderless" (space-separated tokens in any order) and no company-style live completion. So the project replaces the palette rather than extending it, built on a custom matcher (`FuzzyRanker`). ## Environment - Kate 25.12.3, KDE Frameworks 6, Qt 6 - C++20, CMake, extra-cmake-modules - C++ is the only first-class plugin path on this install (no Python/Pâté binding present) ## Build ```sh cmake -B build -S . cmake --build build QT_QPA_PLATFORM=offscreen ./build/bin/test_fuzzyranker # run the matcher tests ctest --test-dir build # or via ctest ``` ## Install the plugin into Kate The plugin builds to `build/bin/kf6/ktexteditor/olliepalette.so`. Drop it where Kate scans for KTextEditor plugins (a user path on `QT_PLUGIN_PATH`): ```sh install -D build/bin/kf6/ktexteditor/olliepalette.so \ ~/.local/lib/x86_64-linux-gnu/qt6/plugins/kf6/ktexteditor/olliepalette.so ``` Then in Kate: Settings → Configure Kate → Plugins → enable **Ollie Command Palette**. Press **Alt+X** (M-x) to open the command palette; type to filter, Enter or click to run. Press **Alt+R** to open the editing radial menu at the caret; move the mouse toward a slice and release (or click) — a branch slice (marked ▸) opens a submenu, the centre hub goes back/cancels. ## Status See [docs/PLAN.md](docs/PLAN.md) for the full roadmap. - **Milestone 1 — FuzzyRanker (keystone): DONE.** Orderless, layered scoring (exact / substring / word-initials / subsequence / bounded typo), merged highlight ranges. 14 unit tests, all green. - **Milestone 2 — custom palette widget: DONE.** `PaletteModel` + `PaletteWidget` (frameless popup, live filtering, highlighted matches, keyboard + mouse activation). 10 model unit tests, all green. - Milestone 3 — KTextEditor plugin + M-x: **DONE.** Loadable `olliepalette.so`; `Alt+X` opens the palette over every action in the window's GUI clients. - Milestone 4 — radial caret menu: **DONE (first increment).** Multi-level radial menu (`Alt+R` default) at the caret, mouse-driven selection, config tree with per-radial triggers. Key/action triggers now; mouse-button and gesture triggers next. - Milestone 5 — command vocabulary + project-as-directory + switchers: next. ## Layout ``` CMakeLists.txt top-level KF6/Qt6/ECM project src/ fuzzy/ fuzzyranker.{h,cpp} orderless + layered fuzzy matcher test_fuzzyranker.cpp QTest suite palette/ palettemodel.{h,cpp} ranked, filterable list model (headless) palettewidget.{h,cpp} frameless command-palette popup test_palettemodel.cpp QTest suite radial/ radialmodel.{h,cpp} radial tree + hit-test geometry (headless) radialmenu.{h,cpp} frameless multi-level radial widget radialconfig.{h,cpp} JSON → radial tree + built-in default test_radialmodel.cpp QTest suite test_radialconfig.cpp QTest suite plugin/ ollieplugin.{h,cpp} KTextEditor::Plugin + M-x + radial wiring ollieplugin.json plugin metadata docs/ PLAN.md goal, constraints, roadmap ```