Skip to content

Erlang go-to-definition and hover docs#50

Merged
JesseHerrick merged 8 commits intomainfrom
erlang-source-intelligence
May 1, 2026
Merged

Erlang go-to-definition and hover docs#50
JesseHerrick merged 8 commits intomainfrom
erlang-source-intelligence

Conversation

@JesseHerrick
Copy link
Copy Markdown
Member

@JesseHerrick JesseHerrick commented Apr 24, 2026

#30

  • Reuses cached tokenized Elixir documents across LSP handlers to avoid repeated tokenization for completions, aliases/imports/uses, buffer functions, and alias-block checks.
  • Adds token-aware completion context detection so completions ignore strings, comments, and heredocs while still handling Erlang atom modules and dotted module/function prefixes.
  • Hardens the persistent BEAM formatter process by synchronizing stderr capture, restarting when .formatter.exs changes outside DidSave, and invalidating BEAM processes on formatter watcher events.
  • Fixes umbrella formatter config resolution by searching for .formatter.exs up to the LSP project root, so child apps without their own formatter config use the umbrella root config. Closes use umbrella root formatter config when present #35 and Root .formatter.exs support for umbrella projects #34.

Note

High Risk
High risk due to a large refactor of the persistent formatter into a multiplexed BEAM process plus new Erlang definition/hover/completion paths, touching core LSP request handling, process management, and caching/concurrency.

Overview
Adds a new persistent beam_server.exs that multiplexes formatting and CodeIntel over a framed binary protocol (requests/responses/notifications), including OTP module warmup, Erlang source/doc lookup, exports, and runtime fingerprinting.

Replaces the old single-purpose persistent formatter (formatter_server.exs) with a shared per-_build BEAM process in Go, including request demux by request_id, notification handling, stderr tail capture for crash diagnostics, and restart/eviction on .formatter.exs changes (including umbrella-aware config lookup).

Extends LSP features to support Erlang atom module references (:code.all_loaded) for go-to-definition and hover, adds Erlang module/function completions backed by warmed OTP module/exports caches, and introduces token-aware CompletionContextAtCursor to avoid offering completions inside strings/comments and to better handle : vs ::.

Updates snippet insertion (pipe-aware argument indices) and adds snippet completions for Elixir special forms when the client supports snippets, with expanded test coverage for BEAM protocol behavior, formatter config reloads, and Erlang features.

Reviewed by Cursor Bugbot for commit 8d04fec. Bugbot is set up for automated code reviews on this repo. Configure here.

Replace the per-.formatter.exs BEAM process model with a single persistent
BEAM process that hosts multiple formatter children on demand via
DynamicSupervisor + Registry. CodeIntel (Erlang go-to-def, hover docs)
is a singleton — no more picking an arbitrary process for code intel queries.

- Formatter GenServer starts lazily per .formatter.exs path, loads config
  and plugins independently, caches opts for subsequent requests
- Walk findFormatterConfig up to projectRoot instead of mixRoot, fixing
  umbrella projects with a root-only .formatter.exs (#34)
- Add bp.Ready() guard before Erlang go-to-def/hover to prevent stdout
  race between the ready signal reader and request readers
- Collapse Server.formatters map + formattersMu into single beam/beamMu
Comment thread internal/lsp/formatter.go
Comment thread internal/lsp/beam_server.exs
Comment thread internal/lsp/server.go Outdated
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 58c2b4f. Configure here.

Comment thread internal/lsp/elixir.go
Reuse cached token streams for completion and common Elixir source
queries, including token-aware completion contexts that skip strings and
comments. Make the persistent BEAM formatter safer by synchronizing
stderr capture and restarting when formatter config changes outside
DidSave.
@JesseHerrick JesseHerrick merged commit 8930414 into main May 1, 2026
5 checks passed
@JesseHerrick JesseHerrick deleted the erlang-source-intelligence branch May 1, 2026 19:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant