>_EMACS-VIML — VIML IN EMACS
Open a .vim file and the whole Vimscript surface lights up. emacs-viml targets vimlrs, the standalone interpreter that ports Neovim's eval engine to Rust on fusevm. vimlrs-mode derives from prog-mode, font-locks VimL statement keywords, common ex commands, scope-namespaced variables (g: s: b: v: …), special v: variables (v:true v:count v:val), built-in functions and function definitions, indents block keywords, runs the buffer through vimlrs (C-c C-c), serves eldoc + completion for builtins, and wires vimlrs --lsp into both eglot and lsp-mode. Named vimlrs-mode so it does not clash with Emacs' built-in vimrc-mode.
Install
The vimlrs binary must be on $PATH to run buffers and for the language server (build vimlrs with cargo install --path .).
;; manual (add-to-list 'load-path "/path/to/emacs-viml") (require 'vimlrs-mode) ;; use-package + built-in VC (use-package vimlrs-mode :mode "\\.vim\\'" :vc (:url "https://github.com/MenkeTechnologies/emacs-viml"))
Press C-c C-c to run a buffer. With eglot: M-x eglot in a .vim buffer, or (add-hook 'vimlrs-mode-hook #'eglot-ensure).
What you get
Filetype detection
Every *.vim file plus the vimrc/gvimrc/exrc/init.vim family uses vimlrs-mode (auto-mode-alist); vim / nvim / vimlrs shebangs are detected via interpreter-mode-alist.
Scope-aware font-lock
Statement keywords, ex commands, built-in functions, scope variables g:/s:/a:, and special v: variables — each with their own face for scope and special vars.
The `"` ambiguity, solved
A syntax-propertize rule marks a " in command position (line start, or after |) as a comment, while a " in expression position stays a double-quoted string — the classic VimL parse split.
Run via vimlrs
vimlrs-run-buffer (C-c C-c) runs the buffer through vimlrs FILE (positional — no -f) in a *compilation* buffer with next-error navigation over E121:-style messages.
eldoc + completion
One-line builtin signatures in the echo area and completion-at-point over the builtin function names, from vimlrs-stdlib.el.
Language server
Registers vimlrs --lsp for eglot (built in since Emacs 29) and lsp-mode (language id vim), both loaded lazily. Launched with --lsp only — no appended --stdio.
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 |
|---|---|
Statement keywords (if function for let call echo) | font-lock-keyword-face |
Ex commands (set autocmd augroup highlight map) | font-lock-keyword-face |
Scope variables (g: s: b: a: l:) | vimlrs-scope-var-face |
Special v: variables (v:true v:count v:val) | vimlrs-special-var-face |
Built-in functions (len split substitute printf) | font-lock-builtin-face |
| Function definitions | font-lock-function-name-face |
Strings / " comments | via syntax table + syntax-propertize |
Run, language server & config
| Setting / command | Effect |
|---|---|
vimlrs-executable | "vimlrs" — path to the executable used to run buffers and start the server |
vimlrs-indent-offset | 2 — spaces per indent level |
C-c C-c (vimlrs-run-buffer) | run the buffer through vimlrs FILE (positional) via compile |
M-x eglot | start the server via eglot (Emacs 29+) |
M-x lsp | start the server via lsp-mode (language id vim) |
Compatibility
| Target | Status |
|---|---|
| Emacs 27.1+ | Mode + font-lock + indent + run + eldoc + completion |
| eglot | Built in since Emacs 29; works on 27/28 if installed |
| lsp-mode | Registered client |
| Syntax highlighting | No binary required |