Skip to main content

Crate vimlrs

Crate vimlrs 

Source
Expand description

vimlrs — a faithful Rust port of the Vimscript (VimL) interpreter, compiled to fusevm bytecode and run on its VM + Cranelift JIT.

VimL is the 4th language frontend on fusevm, after zshrs (zsh), strykelang (stryke), and awkrs (awk). Like zshrs, it has no local VM and no local JIT: source is lexed and parsed into an AST, lowered to fusevm bytecode, and executed by fusevm.

§Two-zone layout (the zshrs porting discipline)

  • ported — strict 1:1 ports of the Neovim eval C source under vendor/. Exact C names, // c:NNN citations, no invented helpers/structs. See docs/PORT.md.
  • Crate-root carve-outs — net-new synthesis with no C counterpart (Neovim’s eval is a string-walking interpreter with no AST/bytecode): viml_lexer, viml_ast, viml_parser, compile_viml, fusevm_bridge. These mirror zshrs’s compile_zsh.rs/fusevm_bridge.rs carve-outs and are clearly headed “EXTENSION — NO vendor/ counterpart”.

Re-exports§

pub use fusevm_bridge::eval_expr;
pub use fusevm_bridge::eval_source;
pub use ported::eval::typval_defs_h::typval_T;

Modules§

aot
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ EXTENSION — NO vendor/ COUNTERPART. Ahead-of-time build: bake one or more .vim scripts into a copy of the running vimlrs binary as a zstd-compressed trailer, producing a self-contained executable. At startup vimlrs detects the trailer and runs every embedded script in input order as one program. Same design as zshrs’s aot.rs (which has no C counterpart either — Vim’s .vim scripts have no compile-into-binary form).
banner
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ EXTENSION — NO vendor/ COUNTERPART. VIMLRS ASCII wordmark + live-stats box banner. Single source of truth shared by:
builtin_docs
GENERATED doc corpus for the LSP hover provider and the gen-docs binary. Regenerate by re-running the authoring pipeline; do not hand-edit casually.
cli
viml command-line driver (the vimlrs crate’s binary).
compile_viml
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ EXTENSION — NO vendor/ COUNTERPART. Lowers the synthesis AST to a fusevm::Chunk. Neovim has no bytecode compiler; this is the net-new piece that makes VimL run on fusevm (the role zshrs’s compile_zsh.rs plays for zsh). Each expression compiles to a sequence leaving one value on the stack; faithful VimL semantics are never inlined here — every operator routes to a VIML_* builtin whose handler calls the canonical ports. ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
dap
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ EXTENSION — NO vendor/ COUNTERPART. Debug Adapter Protocol server (stdio) — vimlrs --dap. Mirrors zshrs’s dap.rs architecture: the script runs IN-PROCESS on an executor thread; the compiler emits a SET_LINENO marker before each statement whose handler calls check_line, which consults the shared breakpoint state and condvar-waits to pause. While paused, the executor thread also services variables / evaluate requests (so they read the executor’s own globvardict), then resumes when the client sends continue / next.
fusevm_bridge
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ EXTENSION — NO vendor/ COUNTERPART. The vimlrs analogue of zshrs’s src/fusevm_bridge.rs: pure fusevm plumbing, no operator logic. It only
fusevm_disasm
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ EXTENSION — NO vendor/ COUNTERPART. fusevm bytecode listing to stdout when vimlrs is invoked with --disasm (ported from zshrs’s fusevm_disasm.rs). ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
lsp
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ EXTENSION — NO vendor/ COUNTERPART. Language Server Protocol (stdio) for editors — vimlrs --lsp. Self-contained, reusing the synthesis lexer/parser: diagnostics come from per-line crate::viml_parser::parse_stmt; completion / hover draw on the Phase-3 builtin set, the ex-command words, and the predefined v: constants. No output reaches the terminal — JSON-RPC on stdio only. Structure ported from awkrs’s lsp.rs. ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
ported
Strict 1:1 ports of the Neovim eval C source vendored under vendor/.
repl
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ EXTENSION — NO vendor/ COUNTERPART. Interactive REPL for vimlrs — a utop-style line editor backed by reedline. Adapted from strykelang’s repl.rs (same reedline 0.47 API), trimmed for vimlrs’s thread-local interpreter model.
script_cache
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ EXTENSION — NO vendor/ COUNTERPART. rkyv-backed bytecode cache for .vim scripts, the same architecture as awkrs/strykelang/zshrs’s script_cache.
viml_ast
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ EXTENSION — NO vendor/ COUNTERPART. Neovim’s eval.c parses and evaluates in one pass over the source string; there is no AST. This tree is net-new, its shape dictated by the eval1eval7 precedence ladder so the compiler can lower it to fusevm bytecode. ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
viml_lexer
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ EXTENSION — NO vendor/ COUNTERPART. (PORT.md synthesis-layer carve-out, the vimlrs analogue of zshrs’s crate-root fusevm_bridge.rs/compile_zsh.rs.)
viml_parser
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ EXTENSION — NO vendor/ COUNTERPART. Recursive-descent parser building the synthesis AST. The expression grammar transcribes the precedence ladder in eval.c (eval1eval7) but builds a tree instead of evaluating inline:
viml_regex
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ EXTENSION — implements Vim’s regex DIALECT, not a line-by-line port of regexp_bt.c/regexp_nfa.c (which compile a pattern to a bytecode program and match it with a backtracking / NFA VM). This is the vimlrs analogue of the bytecode-compiler carve-out: a backtracking matcher over a parsed AST that reproduces Vim’s documented pattern behavior (:help pattern) in the default magic mode. It backs =~/!~, matchstr(), match(), substitute(), pattern split(), and :catch /pat/.