Skip to content

Conversation

@kxlsx
Copy link

@kxlsx kxlsx commented Jan 19, 2026

This PR implements Intellisense functionality for erlang cells.

Status

The main functionality has been implemented, but the code needs
to be cleaned up & tests need to be added.

At the moment there is a lot of shared code between
Intellisense.Erlang and Intellisense.Elixir. We've opted
for the time being to make the functions we need public,
but we could maybe move them to a separate, shared module.

TODO:

  • Function signature preview
  • Details preview
  • Module member completion
  • Atom name completion
  • Variable completion
  • Bitstring options completion
  • Module attribure completion*
  • Tests

* Builtin module attributes are currently hard-coded into Intellisense.Erlang.IdentifierMatcher, as we haven't yet found a way
to integrate them cleanly.

kxlsx and others added 30 commits November 21, 2025 17:56
1. Added Intellisense completion request handling for
module items (syntax akin to: `MODULE:FUNC_PREFIX`).
2. Added skeleton code for other types of identifier completion

This implementation relies heavily on functionality inside
`Livebook.Intellisense.Elixir`, so a couple of private functions
were made public. I would consider moving a lot of generic functionality
from the Elixir specific modules into a separate one.
Variable completion just utilizes the current elixir infrastructure,
and there's no ambiguity, as erlang variables always start with a capitalized letter.
Also needed to use elixir to erlang variable name conversion from `lib/livebook/runtime/evaluator.ex`
A lot of these exports were always used in the same pipeline anyways, so I made them private and exported them as said pipeline
Erlang Intellisense: module Completion + variable Completion
Not sure whether the heuristic here is the optimal one, but it seems to
work quite well.
Added function signature matching to erlang's intellisense
Atom (module), keyword and bitstring modifier completion
Erlang Intellisense signature info
@CLAassistant
Copy link

CLAassistant commented Jan 19, 2026

CLA assistant check
All committers have signed the CLA.

@jonatanklosko
Copy link
Member

Hey, thanks for the PR! I tried it locally and it is already looking great :)

I found some rough edges, so I will focus on the functionality for now:

  1. When you trigger completions in an empty cell (Cmd + Space), currently there are no completions, but we should actually show all completions (variables, modules, atoms, keywords). The same applies to other "neutral" places like math:pow(CURSOR) and 1 + CURSOR.

  2. Similarly, when you trigger completion in <<X:8, Y/CURSOR>>, we should show all modifiers, but nothing shows up. Completions are only available once there is at least one letter, for example Y/bCURSOR.

  3. Given math:pow(Left, Right)., if you put cursor anywhere within the variable names and trigger signature hint (Cmd + Shift + Space), nothing shows up. The hint only works immediately after ( or ,. Perhaps after tokenization we should remove anything before the cursor until we run into the closest ( or ,.

  4. When hovering over math and pow in math:pow, the hover documentation says :math and :math.pow(X, N) respectively, which is Elixir syntax. It should follow Erlang syntax, so math and math:pow(X, N).

  5. When hovering over pow in math:pow, the spec also uses Elixir syntax:

    @spec pow(x, n) :: float() when x: number(), n: number()

    It should instead be this:

    -spec pow(X, N) -> float() when X :: number(), N :: number().

    ex_doc already does this, as you can see for math:pow/2.

    Both 4. and 5. are because you reuse details formatting from Elixir. I think it should be separate. Some helpers that are language-agnostic we can later move to a shared module.

I would also suggest adding tests next, to cover various edge cases, including the list above. This way you can more confidently refactor/extend the code.

@jonatanklosko
Copy link
Member

  • Builtin module attributes are currently hard-coded into Intellisense.Erlang.IdentifierMatcher, as we haven't yet found a way to integrate them cleanly.

That's totally fine. In Elixir there is Module.reserved_attributes/0, but I don't think Erlang exposes this kind of API. We actually added it to Elixir when we were implementing Elixir intellisense in Livebook :)

@josevalim
Copy link
Contributor

When hovering over pow in math:pow, the spec also uses Elixir syntax:

Here is how ExDoc does it for Erlang: https://github.com/elixir-lang/ex_doc/blob/1b1fe51e479b9bcbf72802e7ef700ed3cedf53ac/lib/ex_doc/language/erlang.ex#L511-L523

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.

7 participants