Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Try to extract function argument names from signature, before defaulting to the first clause #1362

Closed
MarkoMin opened this issue Aug 18, 2022 · 2 comments · Fixed by #1517
Closed
Labels
code completion contribution welcome The authors do not have expertise on this, so external contributions are welcome feature

Comments

@MarkoMin
Copy link
Contributor

Describe the bug
Some signature suggestions from stdlib are missing, e.g. lists:member/2. Is there a way I can add some of missing suggestions via new PR, or even better, is there a way to automate creating suggestions from source/edoc? Same thing occurs when using Erlang LS with NeoVim.

To Reproduce
VSCode, erlang-ls extension v0.0.35 or erlang_ls 0.41.2 with NeoVim, type "lists:memb" and press enter.

Expected behavior
Suggestions should be "Elem" and "List".

Actual behavior
Actual suggestions are "Arg1" and "Arg2".
Context

  • erlang_ls version (tag/sha): 0.41.2
  • Editor used: VSCode / NeoVim
  • LSP client used: Not really sure what this means, VSCode extension erlang_ls and erlang_ls plugin on NeoVim
@MarkoMin MarkoMin added the bug Something isn't working label Aug 18, 2022
@robertoaloi
Copy link
Member

robertoaloi commented Aug 18, 2022

Hi @MarkoMin,

The logic for extracting the variable names (which you can find here) is currently naive.

The parser looks at each function clause in isolation. If a function argument contains a variable (eg Elem), then the variable name is stored. If not, we default to a more basic ArgN name.

The lists:member/2 is a BIF, so if you look at its definition in the lists module you'll find:

member(_, _) ->
    erlang:nif_error(undef).

The parser finds the _, _ and then it defaults to Arg1 and Arg2.

In principle, a nicer signature could be extracted from the specs:

-spec member(Elem, List) -> boolean() when
      Elem :: T,
      List :: [T],
      T :: term().

But this would require some significant changes to the way the parser works. An easier solution would be to improve the auto-completion code to try and extract the argument names from the signature if available and, only if there's no signature, to report the arguments returned by the parser. This approach would have the nice side effect of providing more precise information to the user, since we currently extract the args from the first clause of a function and that may not be accurate if the user intended to use a different clause.

@robertoaloi
Copy link
Member

Removing the bug label since this is not really due to a bug. It feels more like a (really nice) improvement in the Erlang LS behaviour.

@robertoaloi robertoaloi changed the title Signature Suggestions missing Try to extract function argument names from signature, before defaulting to the first clause Aug 18, 2022
@robertoaloi robertoaloi added contribution welcome The authors do not have expertise on this, so external contributions are welcome code completion and removed bug Something isn't working labels Aug 18, 2022
@plux plux closed this as completed in #1517 May 5, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
code completion contribution welcome The authors do not have expertise on this, so external contributions are welcome feature
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants