CLI Behavior
Understand Lumis CLI input handling, auto-detection, parser caching, data directories, and theme discovery.
Input sources
- if a path is provided, Lumis reads that file
- if no path is provided, Lumis reads from stdin
- you can pipe content directly into
lumis highlightor anylumis dumpcommand - terminal output is the default highlight formatter unless you pass
--formatter
cat main.rs | lumis highlight -l rust
echo 'fn main() {}' | lumis highlight -l rustWhen to set --language
Pass --language when you already know the correct parser and do not want detection to depend on the filename or input content.
lumis highlight main.txt --language rustWhen to rely on auto-detection
Omit --language when the path, shebang, or source content should drive detection.
lumis highlight main.rsIf no language can be inferred, plaintext is the safe fallback for highlighting.
Dump commands instead ask you to pass --language, because they need a parser.
Parser and query debugging
Use lumis dump tree to inspect named syntax nodes as branch lines with
language and range metadata. --text, --highlights, and --injections add
source text, resolved highlight-query results, and injected syntax trees. Text
uses an 80-character middle preview by default; use --text=<limit> or
--text=full to change it. Syntax nodes use [name]; resolved highlights use
@name. Use lumis dump events when you need the raw highlight event stream.
lumis dump tree component.svelte
lumis dump tree component.svelte \
--injections --text --highlights
lumis dump tree component.svelte --format sexp
echo 'function increment() { count++; }' \
| lumis dump events -l svelteBoth commands use the same path, stdin, language detection, parser download,
and cache behavior as lumis highlight. See the
CLI command reference for output details.
Theme selection
When --theme is omitted, Lumis uses [highlight].theme from its config file. On macOS and Linux, the default path is ${XDG_CONFIG_HOME:-~/.config}/lumis/config.toml; on Windows it is %XDG_CONFIG_HOME%/lumis/config.toml, or %APPDATA%/lumis/config.toml when XDG is unset. The default value is auto.
[highlight]
theme = "auto"For terminal output, auto asks for the background, foreground and ANSI accent colors in one exchange. It chooses a light or dark theme from the foreground against the background, or from background lightness if only the background is available. Monochrome themes and themes with poor default text contrast are excluded.
The closest backgrounds are considered first. Within a small background tolerance, the foreground and then the ANSI accents distinguish similar themes. This can recognize a theme whose background has been changed slightly, but cannot identify every terminal theme. Use an explicit --theme when you want a particular one, including a monochrome theme.
If the terminal reports no background, does not answer within one second, or has no close match, Lumis renders without a theme and explains why on stderr. Partial replies still work: foreground and ANSI colors are optional.
A terminal reply that arrives after Lumis exits can appear as text at the shell prompt. Set a theme explicitly if this happens; an explicit theme skips the terminal query.
Automatic selection only queries when stdout is a terminal and the formatter is terminal. Pipes, redirected output and HTML output render without a theme and print the reason on stderr. For colored output through a pager or styled HTML, select a theme explicitly:
lumis highlight main.rs --theme dracula | less -R
lumis highlight main.rs --formatter html-inline --theme github_light > main.htmlAn explicit --theme takes precedence over the config file. Set XDG_CONFIG_HOME, LUMIS_CONFIG, or --config to use a different config location.
Parser cache lifecycle
Highlighting downloads, verifies and loads whatever a file turns out to need, including languages injected inside it, and caches them for every later run. A Markdown file with a fenced Rust block highlights that block; a language that cannot be fetched leaves its own block plain rather than failing the file.
The CLI stores language-package metadata and integrity-verified parser WASM files under the data directory. A cold cache resolves the runtime's compatible package range, then loads the exact parser version and matching queries named there. Parser filenames contain the package version and SHA-256 digest.
A compatible manifest already in the store is used as is and never checked against the registry again. So a store staged during a build gives every run the same parser and query bytes, with no network at run time, and two stores filled on different days can hold different patch releases. Bytes that fail their digest check are discarded and fetched again, so a damaged store repairs itself.
- first use of a language downloads its parser
lumis languages download ...persists selected parsers ahead of time, so no run pays for a download and the Wasmtime compile that follows itlumis languages download ... --forceresolves the package range again and replaces valid cached parsers
lumis languages download rust javascript elixir
lumis languages download rust --forceParsers you build or vendor yourself go in the same parsers/ directory as
downloaded ones; lumis --data-dir <dir> languages download ... writes that layout.
Data directory
Default location depends on the OS. Override it with:
--data-dirLUMIS_DATA_DIR
The data dir stores:
- language-package metadata, as
parsers/<name>.lumis.json - parser WASM files, in the same
parsers/directory - custom theme JSON files
The metadata names the exact parser version, queries, and integrity digest, so a directory holding both is self-sufficient offline.
Local custom themes
Pass a JSON path directly to use a theme without installing it:
lumis highlight main.rs --theme ./my-theme.json
lumis themes show ./my-theme.json
lumis themes build-css ./my-theme.json > my-theme.cssPaths are relative to the current working directory unless absolute. A missing or malformed explicit file produces an error rather than silently rendering without a theme.
For short-name lookup, Lumis checks built-in names and then
<data-dir>/themes/<name>.json. lumis themes list discovers JSON files in that
folder and marks them (file). The name is the filename stem: my-theme.json
is selected with --theme my-theme, regardless of the JSON's name field.
Use an explicit path to select a file whose stem matches a built-in theme.
The same lookup applies to themes show, themes build-css, and every
--themes key:theme pair in multi-theme HTML, so
--themes dark:./my-theme.json selects the same file as --theme ./my-theme.json.
See Generate a theme from a Neovim colorscheme for generation, loading examples, and license considerations, or CLI for highlight workflow examples.
Nested languages and parser availability
Some formats depend on nested parsers. If embedded languages are missing from the cache, those nested regions cannot be fully highlighted.
If you work with mixed-language content, cache all relevant parsers.
Verbose mode
Use --verbose to inspect cache hits, parser paths, and downloads.