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

LST: Add argument names to function completions #3308

Closed
wants to merge 2 commits into from

Conversation

Zhomart
Copy link
Contributor

@Zhomart Zhomart commented Jun 21, 2024

  1. Adds brackets to fns
  2. Adds argument names
  3. Does not include 1st argument if used in the pipeline
  4. Does not include the last argument if used in the "use" expression

Changes:

  1. Add field "arg_names" to ValueConstructorVariant.ModuleFn
  2. Separate "value_completion" into 2: "value_completion" and "value_completion_import"
  3. Use "insert_text" instead of "text_edit", because it allows inserting snippets - https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#insertTextFormat
    • Note: we had an issue with "." previously, but it can be solved by "not" including module name when autocompleting (tested on vscode and nvim)
  4. Updated the tests

before (video)
https://github.com/gleam-lang/gleam/assets/830536/26e9b25a-3c9b-41b6-85ac-c02a4409ec7d

after (video)
https://github.com/gleam-lang/gleam/assets/830536/89cbbceb-93f8-4912-a56b-785b2bd08dbb

gifs
2024-06-21 at 18 12 18 - Tomato Tern

@Zhomart
Copy link
Contributor Author

Zhomart commented Jun 21, 2024

@Zhomart
Copy link
Contributor Author

Zhomart commented Jun 22, 2024

Actually, there's a bug : it doesn't work for std lib functions. I'm investigating...

@movva-gpu
Copy link

I agree, it's better like this already

Copy link
Member

@lpil lpil left a comment

Choose a reason for hiding this comment

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

What a cool PR!!

Judging the by the tests this PR reintroduces the duplication bug we just fixed by removing the text edits. We must continue to use that API, or a different solution must be found. The maintainers of the protocol told us we should use the text edit API so I believe that to be the best approach.

If it does not introduce the issue we need tests to demonstrate how that is the case. I think there's tests missing for the new functionality too?

@Olian04
Copy link

Olian04 commented Jun 22, 2024

Does this PR also cover my final gripe with the previous PR?

We should also only add arguments IF the place where we are using the function isn't a function argument it self, and that function argument accepts a function with the same signature as the one we are completing for.

fn some_func(key, val, cb) -> String { todo } 

fn consumer(cb: fn(a, b, c) -> String) { todo }
consumer(some_func) // <- should not include any args nor parentheses

@lpil
Copy link
Member

lpil commented Jun 22, 2024

Yes I'm unsure myself how we can identify when to safely add parens to function calls. I wouldn't want the programmer to have to remove them.

@Olian04
Copy link

Olian04 commented Jun 22, 2024

Yes I'm unsure myself how we can identify when to safely add parens to function calls. I wouldn't want the programmer to have to remove them.

Maybe we can have this feature be a code action instead? That way users can trigger it when it makes sense and not have to remove anything for most cases?

@Zhomart
Copy link
Contributor Author

Zhomart commented Jun 22, 2024

Yes, that make sense, let me see how other languages do that.

@Zhomart
Copy link
Contributor Author

Zhomart commented Jun 22, 2024

Question: I believe you use rust often. I noticed its LSP adds brackets and arguments. How "annoying" is this?

Do you know if another function as callback used a lot or not? If not often, I think this PR speeds up development. Can you please run this locally and check how useful is this?

2024-06-22 at 15 11 35 - Tomato Sole

@Zhomart
Copy link
Contributor Author

Zhomart commented Jun 22, 2024

It looks like Golang somehow knows how the completion is used and doesn't add brackets:

2024-06-22 at 15 38 16 - Bronze Leopon

@Zhomart
Copy link
Contributor Author

Zhomart commented Jun 23, 2024

Update:

  • Do not add parentheses (and argument names) when auto-completing in call arguments.

Full demo (video):
https://github.com/gleam-lang/gleam/assets/830536/85b663fc-5f53-4937-82f1-d108c20c8a7f

2024-06-22 at 20 22 26 - Tan Planarian

@Zhomart
Copy link
Contributor Author

Zhomart commented Jun 23, 2024

What a cool PR!!

Judging the by the tests this PR reintroduces the duplication bug we just fixed by removing the text edits. We must continue to use that API, or a different solution must be found. The maintainers of the protocol told us we should use the text edit API so I believe that to be the best approach.

If it does not introduce the issue we need tests to demonstrate how that is the case. I think there's tests missing for the new functionality too?

@lpil I believe it can be resolved without "text_edit" (I used is_module_select variable, I've tested this locally with various cases and couldn't reproduce that error.

@lpil
Copy link
Member

lpil commented Jun 23, 2024

Question: I believe you use rust often. I noticed its LSP adds brackets and arguments. How "annoying" is this?

Rust doesn't practically have higher order functions in this way, so it is not a problem.

How about instead for this feature is instead of adding parens and placeholder variables names automatically we instead complete the function name without parens, and then when they add parens we show in a tooltip the documentation, types, etc of each argument as they are added. This keeps the programmer in full control, does not add invalid variables to the code, doesn't use the internal names in external code, and the behaviour is uncontroversial.

Concurrently we can in the github issue we can discuss what heuristics would be appropriate to decide when (if ever) to add parens. I'm currently leaning towards never adding them as always adding them would mean doing the wrong thing half the time, and conditionally adding them means the programmer cannot operate purely by muscle memory and instead must pause to see if parens have been added or not before knowing how to continue typing.

@Zhomart
Copy link
Contributor Author

Zhomart commented Jun 23, 2024

Question: I believe you use rust often. I noticed its LSP adds brackets and arguments. How "annoying" is this?

Rust doesn't practically have higher order functions in this way, so it is not a problem.

How about instead for this feature is instead of adding parens and placeholder variables names automatically we instead complete the function name without parens, and then when they add parens we show in a tooltip the documentation, types, etc of each argument as they are added. This keeps the programmer in full control, does not add invalid variables to the code, doesn't use the internal names in external code, and the behaviour is uncontroversial.

Concurrently we can in the github issue we can discuss what heuristics would be appropriate to decide when (if ever) to add parens. I'm currently leaning towards never adding them as always adding them would mean doing the wrong thing half the time, and conditionally adding them means the programmer cannot operate purely by muscle memory and instead must pause to see if parens have been added or not before knowing how to continue typing.

Let me close this and let me experiment further with your proposal

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.

4 participants