From 376a190b5233ba4642f60a6e33224e01183fef5e Mon Sep 17 00:00:00 2001 From: Levi Neely Date: Thu, 8 Oct 2026 16:14:41 +0200 Subject: [PATCH] docs: add docs/PLUMBING.md for configuring ~/lib/plumbing Document the user-side plumber rules that make files and directories open in Kate: the edit-port routing model, setting editor = /usr/bin/kate so files (with their addr line/col) open in Kate instead of acme, the isdir rule that opens a directory as a folder (plumb start kate $dir), reloading a running plumber (9p write plumb/rules), verification, and troubleshooting. Cross-link from PLAN.md. Note: ~/lib/plumbing itself lives in the user's home, not the repo; this documents how to configure it. --- docs/PLAN.md | 4 ++ docs/PLUMBING.md | 139 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 143 insertions(+) create mode 100644 docs/PLUMBING.md diff --git a/docs/PLAN.md b/docs/PLAN.md index cc1daa6..fb4cdf0 100644 --- a/docs/PLAN.md +++ b/docs/PLAN.md @@ -357,6 +357,10 @@ Kate flow through the real plumber rules. plumber/namespace is reachable, so CI stays green. The live round-trip was confirmed passing. The GUI open/cursor path (`openUrl`/`setCursorPosition`) is not exercisable headless and is unverified on a live display. +- **User configuration**: routing (what a plumbed string means, and that files + and directories open in Kate) is set in `~/lib/plumbing`. See + **`docs/PLUMBING.md`** for the editor variable, the directory rule, reloading + the plumber, and troubleshooting. ### Sam — structural-regexp editing panel — DONE A dockable tool view ("Sam", left sidebar) runs the plan9 **sam** command diff --git a/docs/PLUMBING.md b/docs/PLUMBING.md new file mode 100644 index 0000000..143bcd4 --- /dev/null +++ b/docs/PLUMBING.md @@ -0,0 +1,139 @@ +# Plumbing — configuring `~/lib/plumbing` for Kate + +Kate is a full plan9port **plumb client**: it sends plumb messages (plumb a +token under the caret) and receives them on the `edit` port (open a file at a +line, or a directory as a folder). The *routing* — what a plumbed string means — +lives in the plumber's rules, not in Kate. This document covers the user-side +rules in `~/lib/plumbing` that make files and directories open in Kate. + +See `PLAN.md` → "Plumbing" for the implementation (the native 9P client, the +edit-port reader, and the in-process handler). + +## How plumbing reaches Kate + +``` +plumb # or Kate's F2 on the caret token + │ + ▼ +plumber ── applies ~/lib/plumbing rules ──► routes to a PORT + │ + ▼ (edit port) +Kate's reader thread ──► onPlumbEdit() ──► open file@line / open folder +``` + +- The plumber matches the message against rules **top to bottom; first match + wins**. +- A rule routes to a **port** (`plumb to edit`, `plumb to web`, …). The `edit` + port is where editors listen. +- `plumb client ` / `plumb start ` name what to run **if no + application currently holds that port**. A ruleset may contain **only one** + `client`/`start` action. + - `client` — the started program is expected to *open the port itself*; the + message is then delivered through the port. acme and Kate both work this + way (Kate via its edit-port reader). + - `start` — just runs the program with the given arguments. + +## Make Kate the editor + +Set the editor variable near the top of `~/lib/plumbing`: + +``` +editor = /usr/bin/kate +``` + +Every file rule ends with `plumb to edit` + `plumb client $editor`, so this +alone makes **files open in Kate**: + +- If Kate is already running, its reader holds the `edit` port and receives the + message directly. +- If nothing holds `edit`, the plumber cold-starts `/usr/bin/kate`; once its + reader attaches, the message is delivered. + +The **line/column** travels in the message as an `addr` attribute (e.g. +`addr=42`), *not* as a command-line argument. `plumb client` delivers it through +the port, and Kate's handler jumps to it — so `foo.c:42` opens `foo.c` at line +42. + +> The `edit` port is single-consumer. If acme and Kate run at the same time, +> whichever holds `edit` wins; you cannot have both receive plumbed files. With +> `editor = /usr/bin/kate`, Kate is the one cold-started and holding the port. + +## Open a directory as a folder + +The stock `basic` rules only match **regular files** (`arg isfile`), so a bare +directory path fails with *"couldn't find destination for message."* Add a +directory rule. Place it **before** the generic file rules (those use `isfile`, +which fails on a directory, so ordering is not strictly required, but keeping it +with the other specific rules is clearest): + +``` +# any existing directory opens as a folder in Kate +type is text +data matches '[a-zA-Z¡-￿0-9_\-./@~]+' +arg isdir $0 +data set $dir +plumb to edit +plumb start kate $dir +``` + +- `arg isdir $0` succeeds only for an existing directory and sets `$dir`. +- `data set $dir` makes the directory path the message payload. +- `plumb to edit` delivers to Kate's reader when it is running (the in-process + handler opens the folder; `start` does **not** fire). +- `plumb start kate $dir` cold-starts Kate on the directory when nothing holds + `edit`. Kate registers `inode/directory` in its desktop entry and opens a + directory as a folder. + +Note the one-`client`/`start`-per-ruleset limit: this rule uses `start` (not +both `client` and `start`), which covers running and cold-start cases together. + +## Apply changes to a running plumber + +Rules reload without restarting the plumber: + +``` +cat ~/lib/plumbing | 9p write plumb/rules +``` + +A malformed ruleset is rejected whole (the write fails with an error such as +`ruleset has more than one client or start action`); the previous rules stay +in effect until a valid file is written. + +## Quick verification + +``` +# a file (should route to the edit port, carrying addr=3) +plumb /path/to/file:3 + +# a directory (should route to the edit port, data = the dir) +plumb /path/to/dir +``` + +To watch what a plumb actually delivers, read the edit port in another shell: + +``` +9p read plumb/edit # prints the message: src/dst/wdir/type/attr/ndata/data +``` + +A successful file message looks like: + +``` +plumb +edit + +text +addr=3 +15 +/path/to/file +``` + +and a directory message has an empty attr line and `data = /path/to/dir`. + +## Troubleshooting + +| Symptom | Cause | Fix | +|---|---|---| +| `plumb: can't send message: couldn't find destination` | no rule matched (e.g. a directory with only `isfile` rules) | add the directory rule above | +| files open in **acme**, not Kate | `editor` still points at acme | set `editor = /usr/bin/kate` and reload | +| `9p write plumb/rules` fails | malformed rule, or two `client`/`start` actions in one ruleset | keep a single `client`/`start` per rule; fix the reported line | +| directory plumb starts Kate but no folder | Kate build without `inode/directory` handling | verify `kate /some/dir` opens the folder from a shell |