zmax: a Helix fork with 12 scripting languages compiled in
zmax forks Helix into a zero-configuration terminal IDE: LSP, a debugger, tree-sitter, PTY terminal, magit-style git, a hex editor, a 3-pane merge resolver, and nine keymap presets (spacemacs by default, plus vim, emacs, kakoune, micro, nano, cua and others), working on first launch with no plugin manager and no setup. MPL-2.0 like upstream; provenance is in ATTRIBUTION.md.
The part that isn’t just “Helix with more.” Twelve scripting interpreters are compiled into the binary as pure-Rust crates sharing one host API, with no FFI between them: elisp, vimscript, awk, zsh, ruby, php, python, node, tcl, R, and two of my own. They’re evaluated against the live buffer, and ~/.zmax/init.el and init.vim are sourced at startup.
That buys something beyond scripting. :xpipe filters a selection through a chain of them inside the process:
:xpipe awk '{print $2}' |> php 'echo strtoupper($stdin);' |> ruby 'stdin.reverse'
No fork, no execve, no pipe file descriptors — an N-stage chain is N function calls into interpreters already linked in, and the whole chain lands as one undo step. Stages are separated by |> because a bare | is live syntax in most of the twelve. The same trick drives the fuzzy picker: the fzf.vim commands (:Files, :Rg, :GFiles) run a finder in-process rather than exec’ing fzf, while still honoring $FZF_DEFAULT_OPTS, the user’s existing config, and the FZF_* variables preview commands read. The source command behind a picker is of course still a process; the picker isn’t.
Plugins. Helix ships no plugin system. zmax hosts native compiled Rust plugins — an ordinary cdylib loaded at runtime over a frozen versioned C ABI, registering typable :-commands and reading or editing the buffer through the host API. There’s a package manager over it: :zmax-native add owner/repo clones, builds, installs and loads; installs land in a content-addressed store SHA-256 pinned in installed.toml, and loading is by mmap so the library is paged in rather than copied.
On measurement, since “IDE parity” is the kind of claim that’s usually hand-waved. Coverage is tracked against the feature surface of Vim/Neovim, Emacs, Spacemacs, kakoune, vis, sam, ed, nvi, vile, mg, nano, micro, mcedit, ne, dte, three Neovim distributions, and JetBrains. Every inventory item is parsed from that tool’s own primary source — the Neovim runtime docs, the GNU Emacs manual indexes, kakoune’s doc/pages, vile’s cmdtbl, nano’s src/global.c, ne’s texinfo — never hand-written, so the denominator isn’t something I chose. The numerator is re-derived from zmax source on every run, and a mapping that points at non-existent code is flagged broken rather than counted. Numbers live in the generated report, not the README, specifically so they can’t go stale.
The obvious objection: this is a kitchen sink, and the binary carries twelve interpreters whether you use them or not. That’s deliberate — the thesis is that zero-config means everything ships in the box — but --no-default-features drops every interpreter crate from the dependency graph if you want a lean build.
brew install MenkeTechnologies/menketech/zmax, then zmax -g fetch && zmax -g build for grammars.