// EMACS-ZSH — EMACS MAJOR MODE FOR THE ZSHRS SHELL

filetype detection (zsh dotfiles + zsh/zshrs shebang) · font-lock generated from the zshrs binary (137 builtins, 113 extensions, 245 special vars) · shell-block-aware indent · lint via zshrs -n · LSP via zshrs --lsp

eglot + lsp-mode · settings zshrs-executable / zshrs-indent-offset · Package-Requires emacs 27.1

Report GitHub

>_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 groupFace
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 / commentsvia syntax table

Language server, lint & config

Setting / commandEffect
zshrs-executable"zshrs" — path to the executable used for the server and linter
zshrs-indent-offset4 — spaces per indent level
M-x zshrs-lint-bufferpipe the buffer to zshrs -n and show diagnostics
M-x eglotstart the server via eglot (Emacs 29+)
M-x lspstart the server via lsp-mode

Compatibility

TargetStatus
Emacs 27.1+Mode + font-lock + indent
eglotBuilt in since Emacs 29; works on 27/28 if installed
lsp-modeRegistered client
Syntax highlightingNo binary required (tables are committed)
sh-modeNot clobbered — zshrs-mode is opt-in