113 lines
5.6 KiB
Markdown
113 lines
5.6 KiB
Markdown
# AGENTS.md
|
|
|
|
Working notes for anyone (human or agent) hacking on **Deft**, a suite of Kate /
|
|
KTextEditor plugins. Read this before changing code.
|
|
|
|
## What this repo is
|
|
|
|
Six independent KTextEditor plugins, one `.so` per feature, plus a few shared
|
|
static libraries. Each plugin is a `KTextEditor::Plugin` with its own
|
|
`K_PLUGIN_FACTORY_WITH_JSON` factory and `.json` metadata. Kate loads one plugin
|
|
per `.so`.
|
|
|
|
| `.so` | display name | source dir | links |
|
|
|-------|--------------|------------|-------|
|
|
| `deft_palette` | `[deft:util] palette` | `src/palette/` | `palette`, `deftcommands_lib` |
|
|
| `deft_switch` | `[deft:util] switch` | `src/switch/` | `palette`, `project_lib` |
|
|
| `deft_radial` | `[deft:util] radial` | `src/radial/` | `radial` |
|
|
| `deft_sloppyfocus` | `[deft:util] sloppyfocus` | `src/sloppyfocus/` | self-contained |
|
|
| `deft_acme` | `[deft:nineify] acme` | `src/acme/` | self-contained |
|
|
| `deft_sam` | `[deft:nineify] sam` | `src/sam/` | `sam_lib` |
|
|
| `deft_plumb` | `[deft:nineify] plumb`| `src/plumb/` | `plumb_lib` |
|
|
|
|
Shared static libs (headless, unit-tested in isolation):
|
|
`fuzzyranker`, `palette` (model + widget + `FrecencyStore`), `deftcommands_lib`
|
|
(text transforms + the `:`-verb `KTextEditor::Command`), `project_lib`
|
|
(project/symbol index, `ProjectIndexer`, `KateProjectBridge`), `sam_lib`,
|
|
`plumb_lib`.
|
|
|
|
## Build / test / install
|
|
|
|
```sh
|
|
cmake -B build -S . # configure (defaults: RelWithDebInfo, prefix ~/.local)
|
|
cmake --build build -j # build everything
|
|
QT_QPA_PLATFORM=offscreen ctest --test-dir build # 18 tests, must stay green
|
|
cmake --install build # installs the 6 .so to ~/.local/.../qt6/plugins/kf6/ktexteditor
|
|
```
|
|
|
|
- **Always build and run the full `ctest` after a change.** Tests need
|
|
`QT_QPA_PLATFORM=offscreen` (they create real `KTextEditor` docs/views).
|
|
- The symbol-switcher path and its tests need **`ctags`** on `PATH`; those tests
|
|
skip gracefully when it is absent.
|
|
- Installing is wired for a user-local prefix: see `CMakeLists.txt`. It also
|
|
drops `~/.config/plasma-workspace/env/99-deft.sh` to put the install dir on
|
|
`QT_PLUGIN_PATH` (generated from `99-deft.sh.in`). Don't hand-roll install
|
|
paths — `KDE_INSTALL_PLUGINDIR` is pointed at `QT6_INSTALL_PLUGINS` so plugins
|
|
land where Kate scans.
|
|
- An unqualified `cmake -B build` produces an **optimized** build on purpose
|
|
(`CMAKE_BUILD_TYPE=RelWithDebInfo`); the palette re-rank and indexing are
|
|
several times slower at `-O0`.
|
|
|
|
## Conventions that matter
|
|
|
|
- **Namespace `deft`, `Deft`-prefixed names in all code.** The project was once
|
|
called Ollie; nothing should reintroduce `Ollie`/`ollie` in identifiers,
|
|
config paths (`~/.config/deft/…`), or id prefixes (`deft:cmd:`, `deft:file:`,
|
|
`deft:sym:`).
|
|
- **Match the existing style.** No pointless indirection; file-local helpers
|
|
duplicated across plugins are preferred over a shared lib for a few trivial
|
|
functions.
|
|
- **Never rewrite a file from memory.** Read it first, then make targeted edits.
|
|
|
|
## Two load-bearing design decisions
|
|
|
|
Changing either of these will break the suite in non-obvious ways.
|
|
|
|
### 1. Launcher keys are intercepted in an `eventFilter`, not registered shortcuts
|
|
|
|
The door keys — palette `Alt+X`, switch `Alt+P`/`Alt+G` — are **not** registered
|
|
as `QAction` shortcuts. Kate already binds many `Alt+<letter>` combos; a
|
|
registered duplicate makes Qt refuse to fire *either* and report an "ambiguous
|
|
shortcut". So each view installs an application `eventFilter`, matches the key
|
|
itself (scoped to its own window via `isAncestorOf`), and consumes it. The
|
|
`QAction`s still exist for their `objectName`/label and discoverability, just
|
|
without a shortcut. `plumb`'s `F2` is the exception — it has no Kate collision,
|
|
so it is a normal registered shortcut.
|
|
|
|
### 2. Cross-plugin calls go through action `objectName`, never direct calls
|
|
|
|
The plugins are separate `.so`s with no link dependency on each other. When
|
|
`palette` offers "Go to File/Symbol", or `radial` has a launcher slice, it
|
|
resolves the target by `objectName` at runtime and triggers it:
|
|
|
|
- `switch` registers window actions `deft_goto_file` and `deft_goto_symbol`.
|
|
- `palette` registers `deft_command_palette`.
|
|
- `findActionByName` searches the window's GUI-factory client action collections
|
|
**and** `window()->actions()` (sibling doors are added with
|
|
`QWidget::addAction`, not via an XMLGUI client — so the window-actions search
|
|
is required, not optional).
|
|
|
|
If you add a new cross-plugin entry point, register the action under a stable
|
|
`deft_*` objectName and resolve it the same way. Never `#include` another
|
|
plugin's header or add a link dependency between plugins.
|
|
|
|
## Gotchas
|
|
|
|
- The `:`-verb sort is registered as **`osort`**, not `sort`: the KTextEditor
|
|
command registry drops an entire `Command` object if any one of its names
|
|
collides with a built-in, and Kate ships `sort`. `test_deftregistration`
|
|
guards against reintroducing a colliding name. `runVerb` still accepts bare
|
|
`sort` for palette entries.
|
|
- Each plugin keeps its **own** `FrecencyStore` file (`deft/palette.frecency.json`,
|
|
`deft/switch.frecency.json`) — separate files, so two independent rankings
|
|
can't clobber one another through a shared file.
|
|
- Live Kate behaviour (plugin discovery, the Plasma env snippet pickup, actual
|
|
gesture handling) can only be verified in a real KDE session. CI/sandbox runs
|
|
cannot confirm it — flag anything that depends on it as unverified.
|
|
|
|
## Reference docs
|
|
|
|
- `docs/PLUMBING.md` — configuring the Plan 9 plumber to route into Kate.
|
|
- `docs/SAM.md` — the sam structural-regexp dialect and semantics.
|
|
- `docs/radials.example.json` — example radial-menu config.
|