Skip to content
Edward Fitz Abucay edited this page May 20, 2026 · 3 revisions

Config and schema

Config discovery order

ee merges configuration from multiple layers, lowest to highest:

  1. /etc/ee/config.toml
  2. $XDG_CONFIG_HOME/ee/config.toml
  3. legacy ~/.ee.toml only when XDG config is missing
  4. every ancestor .ee.toml from outermost to innermost

A root = true setting in any .ee.toml stops discovery above that file.

If you want to bypass discovery, use:

ee --config /path/to/config.toml <file>

Sample config layout

root = true
indent_style = "spaces"
indent_size = 4
tab_width = 4
end_of_line = "lf"
charset = "utf-8"
trim_trailing_whitespace = true
insert_final_newline = true
number_style = "relative"
color_column = 80
show_visible_whitespace = true
scroll_offset = 3
wrap_lines = true
sign_column = true
cursor_line = true
statusline_format = "default"

[lsp.servers.rust]
language_name = "Rust"
command = "rust-analyzer"
args = ["--stdio"]
extensions = ["rs", "ron"]
supports_single_file = true
workspace_identifier = "Cargo.toml"
enabled = true
env = { RUST_LOG = "info" }
initialization_options = { diagnostics = { enable = true } }

[keymap]
inherit_defaults = true
sequence_timeout_ms = 500

[[keymap.unbind]]
mode = "normal"
key = "q"

[[keymap.bindings]]
mode = "insert"
key = "C-s"
action = "save"

[[keymap.sequence_bindings]]
mode = "normal"
keys = ["g", "g"]
action = "goto_start"
description = "Go to start of file"

Config schema

Field Type Default Notes
root bool false stop ancestor config discovery when true
indent_style string spaces spaces, space, tabs, or tab
indent_size integer editor default spaces count per indent level
tab_width integer editor default visual width for tabs
end_of_line string lf lf, crlf, or cr
charset string utf-8 file charset hint
trim_trailing_whitespace bool false remove trailing whitespace on save
insert_final_newline bool false add newline at EOF on save
number_style string absolute absolute, relative, relative_absolute
color_column integer unset hard wrap guide column
show_visible_whitespace bool false render whitespace markers
scroll_offset integer unset minimum rows between cursor and edge
wrap_lines bool false soft wrap long lines
sign_column bool false show sign column margin
cursor_line bool false highlight the cursor line
statusline_format string default default or minimal
lsp table {} LSP server configuration block
keymap table {} keymap override block

lsp.servers.<id> schema

Each server has the following fields:

Field Type Default Notes
language_name string required for custom servers human-readable language label
command string required executable or command name
args array of strings [] extra process arguments
extensions array of strings [] legacy extension fallback and server metadata
supports_single_file bool true whether single-file mode is allowed
workspace_identifier string unset file that identifies a project root
enabled bool true disable server with false
env table {} env vars for the language server process
initialization_options TOML value null extra LSP init options

Preferred routing attaches server ids from languages instead of selecting servers directly by extension:

[lsp.servers.typescript]
language_name = "TypeScript"
command = "typescript-language-server"
args = ["--stdio"]

[lsp.servers.eslint]
language_name = "ESLint"
command = "vscode-eslint-language-server"
args = ["--stdio"]

[languages.typescript]
lsp = ["typescript", "eslint"]

Routing semantics:

  • resolved runtime language id wins first
  • [languages.<id>].lsp list order is deterministic and defines primary then secondary servers
  • first attached server owns interactive pull-style features such as completion, hover, definition, references, symbols, formatting, and rename
  • all attached servers still receive didOpen/didChange/didSave/didClose and may publish diagnostics
  • when no explicit lsp attachment exists for a language, legacy extension fallback still applies

languages.<id> runtime schema

Runtime tree-sitter language configuration lives under [languages.<id>]. The <id> key is the stable runtime language id used for merged language ownership, query directories, and runtime build output.

Required fields for enabled runtime languages:

Field Type Default Notes
name string required human-readable display name
file_types array of strings required file extensions without leading dot
grammar table required grammar library, symbol, and source

Optional fields:

Field Type Default Notes
enabled bool true disable a runtime language with false
lsp array of strings unset attached LSP server ids in primary-to-secondary order
aliases array of strings [] alternate lookup names
globs array of strings [] path globs checked before file type
shebangs array of strings [] first-line interpreter markers
scope string source.<id> for config-only languages tree-sitter scope
query_language string <id> or built-in language name query directory name
content_regex string unset content-based detection
first_line_regex string unset first-line detection
injection_regex string unset matches injected language identifiers for runtime injection resolution; not used for top-level file detection
match_priority integer 0 breaks file-type ownership ties
supported_query_kinds array of strings all supported kinds highlights, injections, locals, tags, textobjects, indents, folds, rainbows

languages.<id>.grammar

Field Type Default Notes
library string required shared library stem, for example tree-sitter-rust
symbol string required exported grammar symbol, for example tree_sitter_rust
source table required exactly one crate or git source

grammar.source must be exactly one of:

[languages.gleam.grammar.source.crate]
name = "tree-sitter-gleam"
version = "1.0.0"
[languages.demo_branch.grammar.source.git]
url = "https://github.com/example/tree-sitter-demo"
branch = "main"
[languages.demo_tag.grammar.source.git]
url = "https://github.com/example/tree-sitter-demo"
tag = "v1.0.0"
[languages.demo_rev.grammar.source.git]
url = "https://github.com/example/tree-sitter-demo"
rev = "33f12ef0f6f2d9f2fcb6f6c2d69b4eb9b6a0b4d2"

Use rev for reproducible release builds. Use branch only for local development when moving refs are acceptable.

Runtime workflow:

ee do runtime languages --file path/to/file.rs
ee do runtime --injection-language tsx
ee do runtime fetch --all
ee do runtime build --all
scripts/build-runtime.sh --output-root target/runtime-package
EE_RUNTIME_DIR="$PWD/target/runtime-package" cargo run -p ee-cli -- path/to/file.rs

Limitations:

  • Native grammar code requires a trusted source before workspace config should be allowed to supply it.
  • One effective runtime language owns a file type after config merge; equal-priority duplicates fail closed.
  • LSP server definitions stay under [lsp.servers.<id>], but preferred routing attaches them from [languages.<id>].lsp.

keymap schema

Field Type Default Notes
inherit_defaults bool true merge default keymap before overrides
sequence_timeout_ms integer 500 timeout for key sequence input
unbind array [] remove default bindings
bindings array [] add or override key bindings
sequence_bindings array [] add sequence bindings

keymap.unbind and keymap.bindings

Each entry requires:

  • mode: string
  • key: string
  • action: string
  • prefix: optional string

keymap.sequence_bindings

Each entry requires:

  • mode: string
  • keys: array of strings
  • action: string
  • description: optional string