Skip to content

feat: add hex intelligence#570

Open
dbernheisel wants to merge 3 commits intoexpert-lsp:mainfrom
dbernheisel:dbern/hex-cmp
Open

feat: add hex intelligence#570
dbernheisel wants to merge 3 commits intoexpert-lsp:mainfrom
dbernheisel:dbern/hex-cmp

Conversation

@dbernheisel
Copy link
Copy Markdown

@dbernheisel dbernheisel commented Apr 11, 2026

Adds hex package intelligence to mix.exs — package name completion, version completion, dep option suggestions, and hover documentation. Works across the public hex.pm registry and custom self-hosted repos like Oban with no configuration beyond what Mix already knows.

This is fairly self-contained with a few integrated points, so because of that, I felt a large PR would be ok for completeness. Happy to refactor/reorganize modules as you see fit.

Generally, this is porting hex-cmp

What it does

  • Package completion — type {:phoe and get phoenix, phoenix_live_view, etc. with download counts and descriptions. Custom repo packages (like oban_pro) appear alongside hexpm results with their repo labeled.
  • Version completion — type {:phoenix, "~> 1. and get filtered version candidates sorted newest-first. Retired versions are annotated with the retirement reason. Works for custom repos without needing repo: typed first.
  • Dep option completion — type {:phoenix, "~> 1.7", and get only, runtime, override, repo, etc.
  • Hover docs — hover a package atom to see description, installed vs latest version, license, download count, and links. For custom repos, metadata is extracted from locally-cached tarballs.

How it works

  • Engine.Deps runs in the project's Mix context (where the Hex archive is loaded) and exposes repo config, dep versions, project files, and cached tarball paths over RPC.
  • Hex.Context detects the cursor slot (name/version/opts) inside a deps function tuple using Sourceror's error-recovering parser, with a regex line fallback for cases where both parsers fail (unclosed strings). This assumes the conventional "deps" function within the project file (eg, mix.exs), and will not offer intelligence otherwise.
  • Hex.Api routes through the hex.pm HTTP API via :hex_core dep for public packages and the repo protocol (:hex_repo) for custom repos. Custom repo responses are enriched with tarball metadata if they're already cached.
  • Hex.Cache is a DETS-backed GenServer with 1-hour TTL and stale-on-error fallback so completions survive network failures and LSP restarts. This helps relieve the server from being hammered with repeated known info from the user.

Testing

  • Verified with a custom repo, eg, oban.
  • Verified with public packages
  • Verified with private hex repos.
  • Verified with umbrella apps, but it should work since it uses the engine's current InProject helpers.
  • Verified with projects with a non-standard project file, eg, not named mix.exs
image image image image image image

Comment on lines 20 to -25
document = Document.Container.context_document(params, nil)
projects = ActiveProjects.projects()
project = Project.project_for_document(projects, document)

document = Document.Container.context_document(params, nil)

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

not related, but a duplicated call (document is set on line 20 already)

@dbernheisel dbernheisel changed the title Add Hex intelligence feat: add hex intelligence Apr 11, 2026
@andyl
Copy link
Copy Markdown

andyl commented Apr 12, 2026

@dbernheisel - if this is accepted, will we still need hex-cmp ?

ps hex-cmp has been very handy thanks for this great tool!

@dbernheisel
Copy link
Copy Markdown
Author

Nope! It's more complete within Expert; supports custom repos, displays the installed version of the dep, and has access to the projects actual hex to know these things rather than reinventing what mix/hex do.

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.

2 participants