// EMACS-VIML — EMACS MAJOR MODE FOR VIML (VIMLRS)

filetype detection (*.vim + vimrc/exrc family + vim/nvim shebang) · font-lock for keywords, ex commands, scope/special vars, builtins, function defs · block-keyword indent · run via vimlrs · LSP via vimlrs --lsp

eglot + lsp-mode · eldoc + completion · settings vimlrs-executable / vimlrs-indent-offset · Package-Requires emacs 27.1

Report GitHub

>_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 groupFace
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 definitionsfont-lock-function-name-face
Strings / " commentsvia syntax table + syntax-propertize

Run, language server & config

Setting / commandEffect
vimlrs-executable"vimlrs" — path to the executable used to run buffers and start the server
vimlrs-indent-offset2 — spaces per indent level
C-c C-c (vimlrs-run-buffer)run the buffer through vimlrs FILE (positional) via compile
M-x eglotstart the server via eglot (Emacs 29+)
M-x lspstart the server via lsp-mode (language id vim)

Compatibility

TargetStatus
Emacs 27.1+Mode + font-lock + indent + run + eldoc + completion
eglotBuilt in since Emacs 29; works on 27/28 if installed
lsp-modeRegistered client
Syntax highlightingNo binary required