-
Notifications
You must be signed in to change notification settings - Fork 206
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
Improve autocomplete and signature help #273
Conversation
I didn't remove the keywords suggestions since there's already #259 to address that. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks great! And I tested it out and there's a bunch of great improvements. I do have some stylistic/maintainability suggestions that I've left inline. It would be great to get some of those changed before merging.
} = context | ||
|
||
locals_without_parens = Keyword.get(options, :locals_without_parens) | ||
with_parens? = formatted_with_parens?(name, arity, locals_without_parens) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we make this variable name a little more self-explanatory (including in the keyword list). Maybe something like function_name_with_parens?
. As it currently is, it's a little hard to understand without further context.
apps/language_server/lib/language_server/providers/completion.ex
Outdated
Show resolved
Hide resolved
Also meant to add a suggestion to create a test for apps/language_server/test/language_server/source_file_test.exs:
|
{:ok, code} -> | ||
code | ||
|> to_string() | ||
|> String.split("\n") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is it OK to split only by\n
? will it work with Windows line endings?
@axelson @lukaszsamson thanks for the valuable reviews. |
6a0620b
to
8acf9bd
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, looks great! Thanks for making the changes ❤️
Hey guys, Both Emacs LSP clients use the Note the two weird chars after "function". Could you maybe pick a more compatible default? |
@dgutov thanks for reporting this. I’ll move the signature from the |
Thank you, that's probably better. But then we won't see the arguments at all. While we did in the previous version. Maybe try to keep the signature almost the same, but on the same line somehow? Or are VS Code's popups too small for that? Personally, for functions I would prefer format like |
Unfortunately the specification doesn't make this any easier with only a vague description of
But looking on what other Microsoft-backed language servers return:
|
@lukaszsamson I think the issue is the view without the expanded panel. As you can see, they don't show exactly the spec. They prepend some small info before the spec, e.g. |
They... don't put newlines there? |
Also: |
@dgutov I didn't say we have to do the exact same format. Here's what I wrote:
"That's exactly what we're doing" refers to "prepend some small info before the spec". I didn't say: "prepend some small info before the spec with the exact same format". We don't need to copy the exact same format. I thought that was pretty obvious. What we need to do is try to find a format that can please most users from all different editors, knowing that we will never be able to please everyone 100%. There will be trade-offs. What we know is that the old format was awful for Now let's move to the next level and start proposing solutions. Here's one for discussion:
To make it clear, this is just a suggestion. We can improve it or even discard it. However, if we decide to discard it, let's please try to propose a better solution. |
@msaraiva What do you think of the two proposals I already made? Either should work for us.
OK, sorry for misunderstanding. But following a similar format makes sense to me. Is it also a problem for you because of the VS Code's window size? Do Microsoft's language servers not have that problem?
An improvement, but that would move the signature info farther from Emacs users.
This one sounds better. Any chance for the configuration to default to the previous behavior? You have a dedicated VS Code extension to set the config, after all. FWIW, the previous behavior was not 100% ideal for us either, because when a function had a spec, the detail duplicated both the function name and its arglist (example: Perhaps @joaotavora or @yyoncho have any other suggestions. |
Maybe |
They do have the same problem. There are a bunch of duplicated issues asking to provide a way to customize the window's style, especially because of the size.
The suggestion is to apply
Yes. I think showing |
@joaotavora the original characters are just two line breaks that separate the origin/type info from the signature. As far as could see, the client is replacing them with those strange characters.
We either send it and assume the client replaces it with something that looks better than those characters or we move the signature to the documentation section.
That will depend on the client's maintainer. I have no idea if he/she will be willing to do it. |
OK, I understand. Emacs's is a modular editor. @dgutov is responsible for that part. However, his extension is not the only way that Emacs has to show completions, though. There are others (and I don't know what they are doing vis.a.vis very long "detail" summaries).
This "assuming" is tricky, as you know. You should do what the LSP spec says. It says nothing useful, it's true. But you can open an issue. In the meantime, I think it's relatively safe to assume that a very long "detail" isn't a "detail" at all.
That's up to @dgutov. Personally, in his position, I'd probably replace any type of whitespace with a space, and replace more than one consecutive space with nothing. |
Then perhaps Microsoft will increase the width of the popup, if this is a systemic problem? Or will clarify the semantics, so that all LSP servers follow the new standard. Or introduce a new field, with more clear semantics. If I was making that choice myself, I'd rather keep with the current practice, so that the different clients don't have to handle a multitude of behaviors by servers.
Oh, okay. That makes sense. That leaves one problem, though: I think your idea #3 in the associated issue was basically correct ("Do not add arguments to the snippet when auto-completing"). Because even if one likes to use snippets, in Elixir, with its piping operator, they would delete the inserted arguments a lot of the time anyway. And insertion of arguments in the snippet is basically tied to showing them with the method name, right? By the way, is that a common trend across language servers, to remove arguments insertion? Your screenshots suggest that pretty strongly. |
@joaotavora is the author of one of the LSP clients we have. I maintain the completion frontend on the screenshot. While it can certainly replace anything with anything, doing that for newline characters seems pretty dirty. Right now it's showing a sort of mojibake to notify the users that the backend is sending an incorrect string. A choice to swallow the problem silently might later backfire with some other backend, where the developer will fail to notice a similar problem as a result. |
I think they should define a new field in the specification for that and, regarding VS Code, they should find a way to increase the width of the window. However, the first issue opened I've ever seen about this problem is about 4 years old so I'm not expecting fixes any time soon. The best we can do is cross our fingers and try to do the best we can with the tools we have.
This shouldn't be a problem. Detecting the pipe is easy, The thing I don't like about adding arguments to snippets of function calls is that because the snippets don't know about the context, they just insert the names of the arguments, which almost never match the names of the variables or expressions you actually want to pass to the function, forcing us to delete most of them, most of the time, which is annoying.
Not really. They're sent as different fields.
All editors I know that have signature help do not auto-complete functions with any argument. That includes old stuff like Delphi, Power Builder, MS Visual Studio, Eclipse, as well as newer editors like VS Code. Here's an example I already mentioned of Java in VS Code: The same goes for Typescript, JS and all other language extension I ever worked with. The only cases I think adding the arguments makes sense is when:
|
Did I miss the part of the discussion where you discovered that the LSP spec disallows newlines in |
How is that relevant to which strings company-mode accepts as annotations? |
You said the backend is sending an incorrect string. Is it? I don't know, haven't checked. But, to repeat myself, I said that regardless of that, I think it's reasonable expectation from a server author that the LSP client be able to display that string, somehow. |
Sounds like they could do even just one of these things to some good result.
Guess I don't see the size of the problem, not being a VS Code user myself. But going "your own way" and/or adding configuration options has costs as well. Not my place to decide otherwise, though.
Yeah, from my experiences with IDEs, the editor usually included relevant local variables as suggestions for using them in parameters (with matching types, etc). But it's hard to do that with a dynamic language.
Okay, but the previous version had arguments insertion. The new one doesn't. The configuration option won't bring them back? If so, that sounds fine.
That makes sense. We should implement this in Emacs. We have something similar already, but a bit less feature-ful.
So what did VS Code do with textEdit fields you sent in the previous version? Still added arguments, but scoffed inwardly at that a little bit?
Hmm. That screenshot looks nice, but it could also be implemented as "normal" completion, doesn't it? So I'm not sure of the added value of snippets in this case either. Default inputs would still need to be erased 99% of the time, right? |
It's not reasonable to expect a client to handle just about any arbitrary string in this field. In fact, this discussion is born from VS Code being unable to handle the values from the latest release well. So we're discussing which shapes the string can take. But if you really want to handle this on your end, be my guest. |
It was you who asked for suggestions, remember? My suggestion is: improve the completion popup or at least don't let it choke on what servers are legitimately sending. I don't much care what VS Code does or doesn't and neither should server authors, or you, IMHO. Want a concrete suggestion to improve your completion popup? Have |
I'm sorry I asked. |
Yep, next time, better ask specifically for only the suggestions that you want to hear. |
If the editor has support for snippets but doesn't have support for signature help, it should insert the arguments like before. If it doesn't, it's a bug. Please let me know if that's the case so I can investigate and fix it.
Unfortunately, it doesn't. ElixirSense does not recognize arguments of functions without parenthesis yet. That's why the signature help is also disabled when the cursor is inside one of them. The "normal" complete can't help us here either for the very same reason.
Wrong again :) The new version does not insert default arguments anymore. If it does, let me know. It's a bug. |
Oh, so that's the new approach. The behavior seems to be working fine: we do support signature help, just not as "helpfully" as VS Code does (yet). But I suppose we should just work on improving that.
I see. Perhaps someone could look into fixing that first.
What I meant is, this case (Ecto migrations) also fits your reasoning behind disabling arguments insertion: you end up deleting the snippet's default inputs in 99% of the cases. Not sure why migrations would be different. |
Going back to the original report, after some consideration, I think we'll be okay if you just do this:
Because the signature info is, after all, available through other means. |
This PR addresses the improvements suggested in #251.
Changes
Signature help
Autocomplete/suggestions
IO.inspect
):locals_without_parens
configuration so we know when to add parenthesis or not when autocompleting functions/macros (fix the annoying issue of having to delete the parens when using popular lib DSLs likeEcto
)Screenshots
List without noise and formatted markdown documentation and spec:
Local functions:
Remote functions:
Trigger signature help on autocomplete (no more manually deleting arguments)