A Plan 9 Acme-inspired text editor written in Scala. It follows the Acme mouse-chording model: right-click executes or navigates, middle-click-drag selects and runs — keeping your hands on the mouse and out of modal menus. There is no command palette, no sidebar, and no plugin system; just text, tag lines, and commands.
Built with Scala 3.8.2, sbt 1.10.7, and Java 17+.
Pre-built packages for Linux, macOS, and Windows are available on the Releases page.
| Platform | Package | Notes |
|---|---|---|
| Linux | z-editor_X.X.X_amd64.deb or ZIP |
ZIP includes install.sh |
| macOS | z-X.X.X.dmg or ZIP |
Unsigned — right-click → Open to bypass Gatekeeper |
| Windows | z-X.X.X.msi or ZIP |
Unsigned — choose "More info → Run anyway" in SmartScreen |
All native packages (.deb, .dmg, .msi) bundle a JRE — no separate Java installation required.
The ZIP packages require Java 17+ and include an install script.
sbt assembly
mkdir -p ~/.local/lib/z
cp target/scala-3.8.2/z.jar ~/.local/lib/z/z.jarThen create a launcher script at ~/bin/z (or anywhere on your $PATH):
#!/bin/sh
exec java \
-Dawt.useSystemAAFontSettings=on \
-Dswing.aatext=true \
-jar "${HOME}/.local/lib/z/z.jar" \
"$@"Make it executable:
chmod +x ~/bin/zTo run the tests:
sbt test- Acme-style mouse chording — B3 (right-click) to look/navigate/execute, B2-drag to execute selected text; keyboard capture mode (Ctrl+Enter) lets you type a command with the keyboard, see it highlighted as you go, then execute as a command (Ctrl+Enter) or look/navigate (Ctrl+F)
- Syntax highlighting — powered by RSyntaxTextArea; auto-enabled on
Getfor any file with a known extension (no manual command needed); useHilite [lang]to override,Hilite offto disable,Theme [name]to switch colour themes- Markdown typography — Markdown files get per-level heading fonts (Vera Serif Bold at 18/15/14pt for H1/H2/H3), distinct bold/italic/bold-italic rendering, Hack monospace for inline and fenced code, italic blockquotes, and underlined link text — all overlaid on top of whatever colour theme is active; use
MdFont <elem> '<family>' <size>(app tag line) to restyle any element (h1 h2 h3 bold em bolditalic code quote); settings persist across sessions in~/.z/settingsasmd.font.*
- Markdown typography — Markdown files get per-level heading fonts (Vera Serif Bold at 18/15/14pt for H1/H2/H3), distinct bold/italic/bold-italic rendering, Hack monospace for inline and fenced code, italic blockquotes, and underlined link text — all overlaid on top of whatever colour theme is active; use
- Language Server Protocol (LSP) — use
Lspto start a language server for the current file:- Squiggly underlines for errors and warnings
- Hover tooltips with type information and documentation
- Code completion popup via
Completeor Ctrl+Space - Diagnostics listed in a
+Diagnosticsscratch window - Configure servers in
~/.z/lsp.conf(onelangId = commandper line):go = gopls python = pylsp scala = metals
- Split status bar — the bottom status bar has two lanes: the left shows live window state (line/col, font, wrap/indent/scroll, LSP) updated on mouse hover; the right shows a timestamped echo of the last command run (
[HH:mm:ss] cmd), updated only when a command actually executes — the two never overwrite each other - Command history —
History(app tag line) opens a+Historyscratch buffer listing every command run during the session with timestamp, level (app/col/wnd), and source. Plain text, so you can search, filter with> grep, or B3-click any line to re-run it. The ring buffer size defaults to 500 and is configurable viahistory.limitin~/.z/settings - Session persistence —
Dump/Loadsave and restore the full editor layout - Configurable tag line defaults — set
tag.app,tag.col,tag.wnd, andtag.cmdin~/.z/settingsto customise the commands pre-loaded into each tag line at startup - Property inspection —
Propsopens a+Propsscratch window listing the current properties of the app, column, or window (depending on where it is run from) - Scratch buffers — filenames containing
+are never written to disk (e.g.+scratch,+Results) - Rotatable layout —
RotateViewtoggles window stacking within a column between top-to-bottom and side-by-side; from the app tag line it also rotates the column layout itself. Rotation state is persisted across sessions - Batch commands —
X 'regexp' cmd/Y 'regexp' cmdrun a command across matching/non-matching windows - Interactive processes —
Inputmode lets you send text line-by-line to a running process - Brace matching — Ctrl+B1 selects the region between matching
{}[]()<>or any delimiter pair - Line numbers — toggle with
Ln - Path expansion — tag lines and commands support
~,./, and../prefixes - Relative path style preservation — when a window has a relative path, B3 navigation (directory listings, body text, tag path segments) opens new windows with relative tags rather than absolute paths, keeping the project-relative style consistent
- Root directory control —
Dir <path>changes where relative paths resolve, where external commands run, and the LSP workspace root; works from window, column, or app tag line - User scripts — place executable scripts in
.z/scripts/(project-local) or~/.z/scripts/(global) and invoke them from any tag line with a comma prefix:,Build,,Format,,Deploy. Use,,cmdto run on every open window. Additional directories can be configured in~/.z/scripts.conf - Plumbing rules — user-configurable dispatch rules in
~/.z/plumbingthat intercept B3 actions before normal look/execute logic. Rules follow Plan 9 Acme's block format: blank-line-separated blocks with condition verbs (data matches,arg isfile,arg isdir,wdir matches,src is) and action verbs (data set,attr add,plumb to edit|exec,plumb start). Built-in rules open URLs in the browser and navigate tofile:line(:col)compiler output (guarded byarg isfileso only existing files trigger navigation). Reload rules at any time withPlumb - Fuzzy file picker (Ctrl+P) — keyboard-driven file search that replaces the system file dialog. Type to fuzzy-filter files under the current root; prefix with
/,~/,./, or../to re-root the search interactively. Results are scored by consecutive runs, filename matches, and segment-start matches. When invoked from a tag line the chosen file opens immediately as a new window; when invoked from the body the path is inserted as text - Font control —
Font/FONTset the variable/fixed-width body font;TagFontsets the tag line font. All three cascade from the app tag line (sets editor-wide default), column tag line (that column), or window tag line (that window only) - Keyboard shortcuts for navigation, selection, editing, and tools — see the help screen for the full list
- Tutorial — start here if you are new to z
- Command Reference — full command listing
