Open-Source Wikis

/

Helix

/

Packages

/

helix-loader

helix-editor/helix

helix-loader

Locates configuration and runtime directories, fetches and compiles tree-sitter grammars, and gates workspace trust. ~1,250 lines of Rust.

Purpose

helix-loader is the bootstrap layer. Before the editor can start, it needs to know:

  • Where is the user config file?
  • Where are the runtime grammars, queries, themes?
  • Should we trust the current workspace's .helix/config.toml?
  • Are tree-sitter grammars built? If not, can we build them?

This crate answers all of those questions and is one of the few crates main.rs directly depends on at startup.

Directory layout

helix-loader/src
├── lib.rs              # path resolution, TOML merging, exported as helix_loader::*
├── grammar.rs          # tree-sitter grammar fetch, build, dynamic load (~20k chars)
├── config.rs           # default-config TOML (theme keys, etc.)
├── workspace_trust.rs  # Trust/exclusion list for workspace-local config
└── main.rs             # `cargo run --bin hx-loader -- ...` for grammar ops

Key abstractions

Name File Purpose
runtime_dirs() lib.rs Priority-ordered list of runtime/ directories.
runtime_file(rel) lib.rs Resolves a runtime-relative path against the priority list.
config_dir(), cache_dir(), data_dir() lib.rs XDG-compatible directories (via the etcetera crate).
config_file(), lang_config_file(), workspace_config_file() lib.rs Resolved paths once initialize_config_file has run.
merge_toml_values(a, b, depth) lib.rs Recursively merges two TOML values up to depth; used to merge [language] tables.
find_workspace() lib.rs Walks up looking for VCS markers; returns the workspace root.
fetch_grammars(), build_grammars(), get_language(name) grammar.rs Tree-sitter grammar lifecycle.
WorkspaceTrust workspace_trust.rs The trust list lives at data_dir()/trusted_workspaces.

Runtime dir priority

1. sibling of $CARGO_MANIFEST_DIR/runtime    (development)
2. config_dir()/runtime                      (always included)
3. $HELIX_RUNTIME                            (env, if set)
4. $HELIX_DEFAULT_RUNTIME                    (compile-time, for packagers)
5. runtime/ next to the executable           (always last fallback)

When two runtime dirs both contain a file (e.g. a custom theme), the higher-priority one wins. See prioritize_runtime_dirs.

Tree-sitter grammars

grammar.rs implements the full lifecycle:

  • [[grammar]] entries in languages.toml declare a name + source (Git URL with revision, or local path).
  • fetch_grammars() clones each grammar at the pinned revision into runtime/grammars/sources/<name>. It uses git fetch to update existing checkouts.
  • build_grammars() compiles each grammar's parser.c (and optional scanner.c) into a dynamic library named runtime/grammars/<name>.{so,dll,dylib}.
  • get_language(name) opens the dynamic library at runtime and returns a tree-sitter Grammar. The lookup uses runtime_file so user-installed grammars override bundled ones.
  • The BUILD_TARGET constant is set at build time so cross-compiles produce correctly tagged libraries.
  • Setting HELIX_DISABLE_AUTO_GRAMMAR_BUILD skips automatic builds — useful for packagers.

hx --grammar fetch and hx --grammar build (handled in helix-term/src/main.rs) are wrappers around these functions.

Workspace trust

To prevent a malicious .helix/config.toml from running arbitrary commands (e.g. through a format-command), helix-loader requires the user to trust a workspace before applying its local config. Trust state is persisted at data_dir()/trusted_workspaces and data_dir()/excluded_workspaces.

quick_query_workspace(insecure) (workspace_trust.rs) is called by the config loader before applying the local TOML. The insecure flag short-circuits the check and is set by the user-level config (editor.insecure = true).

The interactive trust prompt is implemented in helix-term/src/handlers/workspace_trust.rs.

TOML merging

When global and workspace configs both define [[language]] for rust, the merge needs to combine the language-server settings without dropping fields. merge_toml_values(a, b, depth) walks two toml::Values, replacing scalars and arrays at depths >= depth and recursively merging tables shallower than depth. Helix uses depth 3 in practice.

Integration points

  • main.rs calls initialize_config_file and initialize_log_file before anything else.
  • helix-core uses runtime_file and find_workspace for grammar and language data lookup.
  • helix-view uses config_dir() for theme search and data_dir() for things like the trust list.

Entry points for modification

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

helix-loader – Helix wiki | Factory