codemirror-lang-elixir
Elixir language support for the CodeMirror 6 code editor, with syntax highlighting, smart indentation, and code folding.
Repository Health
Technical Analysis
codemirror-lang-elixir is a small, focused language package that teaches CodeMirror 6 how to understand Elixir source code. It wraps the Lezer-based Elixir grammar (lezer-elixir) in a CodeMirror LRLanguage definition, adding indentation rules for do/end blocks, anonymous functions, lists, tuples, bitstrings, maps, and stab clauses (->), plus code folding for block-like constructs.
Beyond static language metadata, the package ships an editor command that automatically inserts a closing end when the user presses Enter inside an unclosed do-block or anonymous function, mirroring the ergonomics Elixir developers expect from language-aware editors like VS Code’s ElixirLS. It is maintained by the Livebook team at Dashbit and is used to power Elixir code editing inside Livebook, the interactive Elixir notebook application, but is generic enough to drop into any CodeMirror 6-based editor that needs Elixir support.
What You Get
- An
elixir()function that returns a ready-to-useLanguageSupportextension for CodeMirror 6, installable in a single line - Indentation rules tuned to Elixir’s block structure:
do/endblocks,else/catch/rescue/afterclauses, anonymous functions, lists, tuples, bitstrings, maps, and multi-clause stab expressions - Code folding support for do-blocks, lists, tuples, bitstrings, anonymous functions, and maps
- An
insertNewlineCloseEndeditor command bound to Enter that automatically inserts the matchingendwhen a block is left open, reducing manual bracket-matching - Bracket auto-closing and string/sigil-aware tokenization, including Elixir’s built-in sigils (
~s,~r,~c,~D,~N, etc.)
Common Use Cases
- Adding Elixir syntax highlighting and indentation to a CodeMirror 6-based web IDE or code playground
- Powering the Elixir cell editor inside Livebook, the interactive computational notebook for Elixir
- Building browser-based Elixir tutorials, documentation sandboxes, or REPL front-ends that need real syntax awareness rather than plain-text editing
- Embedding an Elixir code editor in an admin panel, CMS, or internal tool built on CodeMirror
Under The Hood
Architecture
The package is a thin, purpose-built adapter layer over CodeMirror’s language extension system rather than a parser implementation of its own. src/elixir.ts defines elixirLanguage via LRLanguage.define(), configuring the imported lezer-elixir parser with indentNodeProp and foldNodeProp node-prop tables keyed by Lezer grammar node names (DoBlock, StabClause, AnonymousFunction, List, Tuple, Bitstring, Map, etc.). src/commands.ts implements insertNewlineCloseEnd, a StateCommand that walks the syntax tree from the cursor position to find an unclosed end-delimited node and splices in the appropriate indentation and closing end. src/index.ts composes the language and the command into a single elixir() factory returning a CodeMirror LanguageSupport instance, keeping the public surface to one exported function plus the raw elixirLanguage object. What would break if the core abstraction changed: any modification to lezer-elixir’s grammar node names would silently break the indent/fold node-prop lookups, since they’re matched by string name rather than a typed schema.
Tech Stack
Written in TypeScript and built with @codemirror/buildhelper, which wraps Rollup for CodeMirror’s standard package layout (dist/index.js ESM, dist/index.cjs CJS, dist/index.d.ts types). Runtime dependencies are minimal and precisely scoped: @codemirror/language for the LRLanguage/LanguageSupport/indent/fold primitives, @codemirror/state and @codemirror/view for the editor command and keymap, and lezer-elixir for the actual Elixir grammar/parser (a separate published package this one does not implement itself). No bundler config, database, or server components — this is a pure client-side editor extension distributed as an npm package.
Code Quality
No test directory or test files exist in the published source, despite .gitignore/.npmignore entries that reference a test/ folder — likely inherited boilerplate from CodeMirror’s shared language-package template that was never populated for this repository. Code is fully typed TypeScript with no any usage in the reviewed files, uses small single-purpose functions (endDelimitedParent, checkAllClosed, withContinuedStabClause), and follows the naming and structural conventions common across the wider codemirror/lang-* ecosystem. No CI configuration, linter config, or formatter config is present in the repository root.
What Makes It Unique
The package’s differentiator isn’t the grammar itself (that lives in the separate lezer-elixir project) but its editor-ergonomics layer: the auto-closing end command specifically handles Elixir’s stab-clause (->) constructs used in case, cond, receive, and anonymous functions — tracking whether a new clause continues an existing block or requires closing it, which is a non-trivial indentation problem specific to Elixir’s block-without-braces syntax. This distinguishes it from generic bracket-matching editor behavior found in most language packages.
Used by 4 apps in this directory
Gitea
Devops · Developer Tools · Project Management
Self-hosted DevOps in a single Go binary — Git hosting, GitHub Actions-compatible CI/CD, and 30+ package registries without any SaaS dependency.
hoop
Security · Monitoring
A wire-protocol gateway that enforces data masking, command blocking, approval workflows, and full session recording for engineers and AI agents accessing production infrastructure.
Open WebUI
AI Assistants · AI Agents
The extensible, privacy-first AI platform that runs Ollama, OpenAI, and any LLM backend behind a polished, feature-packed web interface.
Sourcebot
Search · Developer Tools · AI Code Assistants
A self-hosted, AI-powered code search engine that indexes every repo across GitHub, GitLab, Bitbucket, Gitea, Gerrit, and Azure DevOps, so both engineers and coding agents can search, browse, and ask questions about your codebase from one place.