kate-deft/docs/PLUMBING.md

5.1 KiB

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.

The implementation (the native 9P client, the edit-port reader, and the in-process handler) lives in src/plumb/ — plumb_lib is the pure codec/9P client and plumbplugin.{h,cpp} is the Kate glue.

How plumbing reaches Kate

plumb <text>                         # 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 <prog> / plumb start <prog> 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
<wdir>
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