Elixir grammar for the Lezer parser system, enabling syntax highlighting and parsing of Elixir code in CodeMirror-based editors
npx @tessl/cli install tessl/npm-lezer-elixir@1.1.0Lezer Elixir provides an Elixir grammar implementation for the Lezer parser system, which is used in CodeMirror editors for syntax highlighting and parsing. Based directly on tree-sitter-elixir, it offers specialized syntax tree nodes optimized for Lezer's performance requirements while providing comprehensive support for Elixir's unique syntax features.
npm install lezer-elixirimport { parser } from "lezer-elixir";For CommonJS:
const { parser } = require("lezer-elixir");Note: The package exports only the main parser instance. Syntax highlighting is built into the parser and accessed via CodeMirror's language integration.
import { parser } from "lezer-elixir";
import { EditorView, basicSetup } from "codemirror";
import { EditorState } from "@codemirror/state";
import { LRLanguage } from "@codemirror/language";
import { styleTags, tags as t } from "@lezer/highlight";
import { syntaxHighlighting, defaultHighlightStyle } from "@codemirror/language";
// Create Elixir language instance with highlighting
const elixir = LRLanguage.define({
parser: parser,
languageData: {
commentTokens: { line: "#" },
indentOnInput: /^\s*end\s*$/
}
});
// Create CodeMirror editor with Elixir support
const elixirCode = `
def fibonacci(n) when n <= 1, do: n
def fibonacci(n), do: fibonacci(n - 1) + fibonacci(n - 2)
IO.puts fibonacci(10)
`;
const view = new EditorView({
state: EditorState.create({
doc: elixirCode,
extensions: [
basicSetup,
elixir,
syntaxHighlighting(defaultHighlightStyle)
]
}),
parent: document.body
});Lezer Elixir is built around several key components:
elixir.grammar file using @lezer/generator@lezer/highlightThe grammar provides a superset of tree-sitter-elixir's syntax tree with additional specialized nodes for Lezer's performance requirements.
The parser includes several external tokenizers for handling complex Elixir syntax:
@ for attributesThese tokenizers are automatically used by the parser and are not directly exposed to users.
The main Lezer parser instance for parsing Elixir code into syntax trees with built-in syntax highlighting support.
/**
* The main Lezer parser instance for parsing Elixir code
* Generated from elixir.grammar using @lezer/generator
* Includes built-in syntax highlighting configuration and specialized tokenizers
*/
export const parser: LRParser;/**
* Lezer LR parser instance with Elixir grammar and highlighting
* Imported from @lezer/lr
*/
interface LRParser {
/** Parse input text into a syntax tree */
parse(input: Input | string): Tree;
/** Start incremental parsing for large documents */
startParse(
input: Input,
fragments?: readonly TreeFragment[],
ranges?: readonly {from: number, to: number}[]
): PartialParse;
/** Configure parser with additional options */
configure(config: ParserConfig): LRParser;
/** Check if parser has recovery information for error handling */
get hasWrappers(): boolean;
/** Get the parser's name for debugging */
get name(): string;
/** Create a Language instance for CodeMirror integration */
get language(): Language;
}
/**
* Input interface for parser
*/
interface Input {
/** Get character code at position */
get(pos: number): number;
/** Read characters into string from range */
read(from: number, to: number): string;
/** Length of the input text */
get length(): number;
/** Get line information at position */
lineAfter(pos: number): string;
/** Cursor for efficient navigation */
cursor(pos?: number): Cursor;
}
/**
* Parser configuration options
*/
interface ParserConfig {
/** Custom node properties for syntax highlighting and behavior */
props?: readonly NodeProp<any>[];
/** Override top-level rule */
top?: string;
/** Add wrapper parsers for mixed-language support */
wrap?: ParseWrapper;
/** Strict mode for error reporting */
strict?: boolean;
}
/**
* Syntax tree representation
*/
interface Tree {
/** Total length of the parsed text */
get length(): number;
/** String representation for debugging */
toString(): string;
/** Iterate over tree nodes */
iterate(config: IterateConfig): TreeCursor;
/** Get cursor at specific position */
cursorAt(pos: number, side?: -1 | 0 | 1): TreeCursor;
/** Resolve position to node */
resolve(pos: number, side?: -1 | 0 | 1): SyntaxNode;
}The grammar includes specialized nodes beyond the standard tree-sitter-elixir implementation:
__MODULE__ and similar special identifiers_x)def fun(x), do: 1)if, case, etc.)@x)@doc "...")&fun/1)&1)left when right)left |> right)~s"string", ~S"string")+, -, *, etc.)and, or, when)The parser handles malformed Elixir code gracefully, producing partial syntax trees that can still be used for highlighting and basic analysis. Invalid syntax is marked with error nodes in the syntax tree.
Common error scenarios:
@lezer/lr and @lezer/highlight as dependenciessrc/elixir.grammar using @lezer/generatorRuntime Dependencies:
@lezer/lr - Core LR parser functionality@lezer/highlight - Syntax highlighting systemBuild Dependencies:
@lezer/generator - Grammar compilation (development only)To use with CodeMirror, you'll typically want to combine the parser with CodeMirror's language support:
import { parser } from "lezer-elixir";
import { LRLanguage, LanguageSupport } from "@codemirror/language";
import { styleTags, tags as t } from "@lezer/highlight";
// Create language definition
const elixirLanguage = LRLanguage.define({
parser: parser,
languageData: {
commentTokens: { line: "#" },
indentOnInput: /^\\s*(end|catch|rescue|after|else)\\s*$/,
closeBrackets: { brackets: ["(", "[", "{", "\"", "'"] }
}
});
// Create full language support
export function elixir() {
return new LanguageSupport(elixirLanguage);
}