RunOrComp
Elixir compile-time detection via compiler tracing. Produces a JSON database that editor plugins can use to highlight code that runs at compile time vs runtime.
Includes a Neovim plugin that highlights compile-time lines with a subtle background tint and virtual text labels.
How it works
RunOrComp uses Elixir's compilation tracer to observe which code constructs execute at compile time:
- Macro calls from non-stdlib dependencies (e.g.,
Plug.Builder.plug/1) - Module-level function calls (e.g.,
Mix.env/0,Application.compile_env/3) - Compile-time callbacks — dynamically discovered by scanning dependency
source for
__before_compile__macros and the callbacks they invoke (e.g.,Plug.Buildercallsinit/1at compile time)
Standard library modules, Kernel constructs, and language plumbing are filtered out so only meaningful compile-time indicators remain.
Setup
Add runorcomp to your project's dependencies:
defp deps do
[
{:runorcomp, "~> 0.1.0", only: [:dev, :test], runtime: false}
]
endThen configure the tracer and compiler in your project:
def project do
[
compilers: Mix.compilers() ++ [:runorcomp],
elixirc_options: [tracers: [Runorcomp.Tracer]],
# ...
]
end
The tracer runs during mix compile and the compiler writes the database to
_build/{env}/runorcomp.json after each compilation pass. Incremental
compilation is supported — only recompiled files are re-traced, and existing
data for unchanged files is preserved.
Note: .exs files (like mix.exs or test support files) are not traced —
only .ex files compiled by mix compile are included.
Neovim plugin
The included Neovim plugin reads the JSON database and highlights compile-time lines with a subtle background tint and optional virtual text labels.
Installation (lazy.nvim)
{
"dbernheisel/runorcomp",
ft = "elixir",
config = function()
vim.api.nvim_set_hl(0, "RunorcompCompileTime", { bg = "#1a1a2e" })
vim.api.nvim_set_hl(0, "RunorcompLabel", { fg = "#6e6ea8", italic = true })
require("runorcomp").setup()
end,
}Commands
:RunorcompRefresh— re-read the database and update highlights:RunorcompClear— remove all highlights:RunorcompToggleLabels— toggle virtual text labels on/off
Options
require("runorcomp").setup({
virtual_text = true, -- show "← target" labels (default: true)
})Highlight groups
| Group | Default | Purpose |
|---|---|---|
RunorcompCompileTime |
links to CursorLine | Background tint on compile-time lines |
RunorcompLabel |
links to Comment | Virtual text label color |
Compile-time callbacks (like init/1 called by Plug.Builder) highlight the
entire function body, not just the def line.