>_EXECUTIVE SUMMARY
emacs-zsh is the Emacs major mode for zshrs — the first-ever Rust rewrite of the zsh shell. zshrs-mode derives from prog-mode and provides font-lock, a syntax table, shell-block-aware indentation, filetype detection, a buffer linter (zshrs -n), and an LSP client that launches zshrs --lsp. It does not clobber the built-in sh-mode.
Design principle: the highlighted surface is generated, not hand-picked. scripts/gen-stdlib.sh dumps .builtins, .extensions, and .special_vars from zshrs --dump-reflection and writes zshrs-stdlib.el — 137 builtins, 113 zshrs extensions, 245 special vars. Regenerate after a zshrs upgrade and it stays in sync.
~WHY PLAIN REGEXP-OPT, NOT HASH TABLES
emacs-stryke stores its 10,450 builtins as hash tables because a single (regexp-opt names 'symbols) over that many names overflows Emacs' regexp compiler (invalid-regexp "Regular expression too big"). zshrs is different: the surface is small — 137 builtins, 113 extensions, 245 special vars. Each category fits comfortably under the limit, so the generator emits one precomputed regexp-opt alternation per category (zshrs-builtins-regexp, zshrs-extensions-regexp, zshrs-special-vars-regexp). The font-lock keyword list references those regexps directly — no matcher function, no hash lookup. Extensions are listed before builtins so the zshrs-specific names win their own bold zshrs-extension-face; the categories are disjoint by construction (builtins exclude keyword + extension names).
| Component | Detail |
|---|---|
zshrs-mode.el | Major mode — syntax table (# comments, string quotes, sigils as punctuation), font-lock keyword list, zshrs-indent-line, zshrs-lint-buffer, eglot + lsp-mode registration, auto-mode-alist + interpreter-mode-alist. |
zshrs-stdlib.el | Generated data — three regexp-opt alternations. Byte-compiles cleanly; loads instantly. |
scripts/gen-stdlib.sh + gen-stdlib.el | Dump .builtins / .extensions / .special_vars from the binary; build the regexps entirely inside Emacs (no shell escaping touches the data). |
scripts/face-test.el | Fontify a sample buffer and assert the face at each probe token. |
$VERIFICATION
CI byte-compiles the package with byte-compile-error-on-warn (warnings are errors) and runs the batch face test. Each probe asserts the actual face text-property after font-lock-ensure.
| Sample token | Asserted face |
|---|---|
typeset / for / do / done / local | font-lock-keyword-face |
bindkey (builtin) | font-lock-builtin-face |
base64 (zshrs extension) | zshrs-extension-face |
$PATH (special var) | font-lock-variable-name-face |
| double-quoted string | font-lock-string-face |
# comment | font-lock-comment-face |