helix-editor/helix
Debugging
How to figure out what Helix is doing when something doesn't work.
Logging
Helix logs to a file using the log crate plus fern for formatting (set up in helix-term/src/main.rs::setup_logging).
Verbosity flags:
| Flag | Level |
|---|---|
| (none) | warn |
-v |
info |
-vv |
debug |
-vvv |
trace |
Custom log path:
hx -vv --log /tmp/helix.log
# in another terminal
tail -f /tmp/helix.logThe default log lives at helix_loader::default_log_file() (typically ~/.cache/helix/helix.log). The :log-open typable command opens it in Helix.
When debugging from cargo run:
cargo run -- -v --log /tmp/helix.log <files>Print debugging is the recommended starter: drop log::info!("…") calls, run with -v, follow the log.
Health check
hx --health
hx --health <language>
hx --health clipboard
hx --health all-languageshelix-term/src/health.rs reports on:
- Configured clipboard providers and which ones work.
- Terminal capabilities (true color, undercurl, kitty keyboard protocol).
- Per-language tooling: language servers, formatter, debugger, query files.
hx --health is the first thing to run when "completion isn't working" or "the diff gutter is empty".
Common failure modes
"Editor doesn't start / panics on startup"
- A bad config file. Helix prints the offending TOML and offers to continue with defaults — press Enter to skip the bad config.
- A missing runtime directory. Set
HELIX_RUNTIMEor copy/symlinkruntime/to the user config dir. - A missing tree-sitter grammar. Run
hx --grammar fetch && hx --grammar build. If you don't want grammars at all, setHELIX_DISABLE_AUTO_GRAMMAR_BUILD=1.
"Language server doesn't start"
hx --health <lang>— confirms the binary is on$PATH.- Check the log with
-vv— LSP transport errors are logged at debug level. Look for "spawn failed", "stderr from server". - Confirm the
language-serverentry inlanguages.tomlmatches the configured server name. - Some servers need a workspace root marker (
Cargo.toml,package.json); Helix picks the deepest matching directory walking up from the file.
"Tree-sitter highlighting is wrong"
cargo xtask query-checkagainst just your language:cargo xtask query-check rust.- Check the loaded grammar version:
hx --health rustshows the resolved grammar path. - Multiple
runtime/directories can shadow each other — the priority order inhelix-loader/src/lib.rs::prioritize_runtime_dirsdetermines which file wins.
"Edit produced wrong cursor position"
Most cursor bugs come from Range::map with the wrong Assoc. The default After is right for typing forward; AfterWord keeps the cursor at the end of an inserted word; Before is for marks that should not move with insertions on top of them. See primitives/transaction.
"Test passes locally but fails in CI"
- The CI uses MSRV (1.90). If you used an unstable feature, it'll fail.
- File handle limits on macOS: see the testing page.
- The
windowsrunner usescrossterm. Backend differences can surface as input handling bugs.
Debugging the editor with itself
:debug-start lets you debug a binary built from the workspace using the configured DAP adapter. For Helix itself:
cargo build --profile dev
# in helix
:debug-start binary target/debug/hxSet breakpoints with space g b, step with the keys under the space g prefix.
RUST_BACKTRACE
For panics:
RUST_BACKTRACE=1 cargo run -- <files>
RUST_BACKTRACE=full cargo run -- <files>The integration test workflow sets RUST_BACKTRACE=1 automatically.
When you must dbg!
dbg! writes to stderr. Helix's terminal claims stdout/stderr while running, so dbg! output gets eaten. Two workarounds:
- Use
log::info!("{:?}", x)and follow the log file. eprintln!to a log file you redirect:cargo run -- 2>/tmp/helix.err. Note this still gets garbled if the terminal is in raw mode — best for early-startup debugging.
Profiling
For CPU profiles, cargo flamegraph --profile opt --bin hx -- <files> works (you'll need flamegraph installed). The opt profile is what releases use, so the flamegraph reflects production behaviour.
For UI freezes, the most useful tool is :log-open followed by :reload-config to inspect what handlers are firing. Long-running synchronous work in a hook is the usual culprit — switch to an AsyncHook.
Asking for help
Include in your bug report:
hx --versionhx --healthoutput (sanitized).- Steps to reproduce.
- Relevant log excerpt with
-vv. - Your terminal emulator and OS.
The Matrix room and GitHub issues both expect this minimum.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.