>_EMACS-ZSH — ZSHRS IN EMACS
Open a .zshrc and the whole shell lights up. zshrs is the first-ever Rust rewrite of the zsh shell. zshrs-mode derives from prog-mode, font-locks the surface (137 builtins, 113 zshrs extensions, 245 special variables) from the binary's own reflection tables, indents shell blocks, lints with zshrs -n, and wires zshrs --lsp into both eglot and lsp-mode.
Install
The zshrs binary must be on $PATH for the language server and linter (build zshrs).
;; manual
(add-to-list 'load-path "/path/to/emacs-zsh")
(require 'zshrs-mode)
;; use-package + built-in VC
(use-package zshrs-mode
:mode ("\\.zsh\\'" "\\.zsh-theme\\'")
:vc (:url "https://github.com/MenkeTechnologies/emacs-zsh"))
With eglot: M-x eglot in a zsh buffer, or (add-hook 'zshrs-mode-hook #'eglot-ensure).
What you get
Filetype detection
zsh dotfiles (.zshrc, .zshenv, .zprofile, .zlogin, .zlogout, .zpreztorc) and *.zsh / *.zsh-theme use zshrs-mode (auto-mode-alist); zsh / zshrs shebangs via interpreter-mode-alist.
Reflection-driven font-lock
137 builtins, 113 zshrs extensions, 245 special vars — not a hand-curated list.
Generated from the binary
scripts/gen-stdlib.sh dumps .builtins / .extensions / .special_vars from zshrs --dump-reflection and writes zshrs-stdlib.el, so it never drifts.
Extensions stand out
The zshrs-specific extension builtins get their own bold zshrs-extension-face, distinct from the inherited zsh builtins.
Language server & lint
Registers zshrs --lsp for eglot and lsp-mode (lazy); M-x zshrs-lint-buffer runs zshrs -n.
Verified
scripts/face-test.el byte-compiles the package and asserts the face at each probe token — proven to load and classify correctly.
Faces
| Token group | Face |
|---|---|
Control flow / declarations (if for case typeset local) | font-lock-keyword-face |
| Extensions (113 zshrs-specific) | zshrs-extension-face (bold) |
| Builtins (137) | font-lock-builtin-face |
| Special variables (245) | font-lock-variable-name-face |
Sigil variables ($foo ${...} $1) | font-lock-variable-name-face |
Punctuation sigils ($? $@ $# $*) | font-lock-constant-face |
| Strings / comments | via syntax table |
Language server, lint & config
| Setting / command | Effect |
|---|---|
zshrs-executable | "zshrs" — path to the executable used for the server and linter |
zshrs-indent-offset | 4 — spaces per indent level |
M-x zshrs-lint-buffer | pipe the buffer to zshrs -n and show diagnostics |
M-x eglot | start the server via eglot (Emacs 29+) |
M-x lsp | start the server via lsp-mode |
Compatibility
| Target | Status |
|---|---|
| Emacs 27.1+ | Mode + font-lock + indent |
| eglot | Built in since Emacs 29; works on 27/28 if installed |
| lsp-mode | Registered client |
| Syntax highlighting | No binary required (tables are committed) |
sh-mode | Not clobbered — zshrs-mode is opt-in |