-
-
Notifications
You must be signed in to change notification settings - Fork 226
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
Complete common ends completion if the prefix contains a parenthesis #1412
Comments
Good question, and I've seen this problem mentioned in the past. First of all, we should not that it's not the default configuration. I guess most language servers migrated to the other approach, with just printing ellipsis by default. But I'd be glad if we can support it. The essence of the problem is that neither eglot not lsp-mode massage the lists of completions into separating the method names from the arguments. They don't put the arguments into "annotation". So the framework were doesn't know where the "common part" ends. But maybe it's okay: the annotations are used to print types, and we don't have any additional field in the completions popup. Then we need some other way to find where the "common part" stops. This problem isn't specific to Company either: pressing |
I've reproduced this. When configured thusly,
IOW these are completions which only make sense when inserted fully so that the Yet we must show something to the user if the completions are to be of any use. Another way to look at this is to note that Emacs's traditional completion UI doesn't quite fit into LSP's concept of a completion UI, which is probably modeled after simpler clients like VS Code. It's not the first time that the marriage between LSP abstraction and Emacs abstractions isn't perfect. Is there a solution? Well, not that I can see. Or rather, the solution is to somehow mark these completions so that the partial completion logic doesn't consider them. But this will often kill every completion and partial completion will be useless anyway. At least in Clangd's case, even when But absence of partial completion is still better than nonsensical results of partial completion, I guess. Not sure this can be implemented in the CAPF, but maybe it can be done. I think @monnier is the specialist to ping here. |
Just commenting on this part. Eglot has no notion of what are "arguments" because LSP doesn't talk about that. Searching for So even with the "annotation" model there's no good fit. LSP uses a "label" model. The LSP |
Could the LSP client take a completion string and all associated information it already keeps about it, and determine that the opening paren and the text after it are not part of the "completion"? Then the |
Not really. Hacks like these are done for font-locking Eldoc in some situations and they are hairy and brittle. Either you lobby LSP devs and servers devs sufficiently hard to support what they probably see as ancient technology, or I don't think there's a better solution than just giving up. |
I mean, I won't object to someone trying that and showing a patch, then we can evaluate in which servers it makes sense. If it doesn't break the majority use case of users that press RET to "select" a completion, and if the patch isn't extremely ugly, I'll merge it. |
Indeed, I was thinking that falling back to searching for That is, if a better solution couldn't be worked out.
IIUC, "complete up to the first difference" is a pretty integral part of the But as mentioned previously, as long as the default configuration is working okay, we don't have to choose a solution right away. |
Oh, I think it's not impossible to trigger nonsensical stuff with the default
The default UI can also be used to select "full completions", at least sometimes. And definitely not as practical as it is with company. But that should be definitely be improved in that default UI and other built-in UIs that allow this capability should make their way into Emacs. |
Another way to look at this is to note that Emacs's traditional
completion UI doesn't quite fit into LSP's concept of a completion
UI, which is probably modeled after simpler clients like VS Code.
It's not the first time that the marriage between LSP abstraction and
Emacs abstractions isn't perfect.
AFAICT, the LSP protocol is designed under a similar model to the Web,
i.e. the server is in control and the client is just a dumb executor.
This goes against the grain of Emacs, of course.
In the case of completions, I think that the sane/robust approach to deal
with LSP is to use the model of "selection" rather than "completion" :-(
But absence of partial completion is still better than nonsensical
results of partial completion, I guess.
Not sure this can be implemented in the CAPF, but maybe it can be
done. I think @monnier is the specialist to ping here.
BTW, rather than look for a paren, maybe another heuristic could be to
use the `:insertedText` content for the completion and use the `:label`
for annotations (which would be guessed by searching for the
`:insertedText` inside the `:label`).
:-(
|
There's no guarantee that
Exactly, well put. LSP is modelled after "selection" clients. So. Is there a way to say this in a CAPF, that it is not good for the partial completion rituals? |
Looks like the intermediate conclusion is that fixing this while keeping the "complete common" behavior is not trivial. What's your opinion on the proposed workaround? Which is to drop the latter, at least when used together with eglot/lsp-mode. That's easy enough to do with rebinding keys anyway. But do you see this problem often? What would you choose for your config in the meantime?
|
There's no guarantee that `:insertText` is a prefix or even matches
text in `:label`.
I know. We'd be firmly in the domain of heuristics and ugly hacks.
LSP is modelled after "selection" clients.
So. Is there a way to say this in a CAPF, that it is not good for the
partial completion rituals?
The CAPF "protocol" does not distinguish the "what is presented" from
"what is inserted", so the best you can come up with is probably
something like:
- return the `:label` as "the completion for the user to choose".
- use the `:exit-function` to rewrite the erroneously inserted `:label`
string, replacing it with (presumably) the `:insertedText` string.
|
Thank you so much for the detailed explanation. There doesn't seem to be an easy solution that work for all languages. I encounter this problem quite often with this clang setting, so for my use case I will simply skip calling
|
Describe the issue
Completing common prefix causes completion to stop if the common prefix extends after a parenthesis '('.
This can happen in c++ if a function is overloaded, see example below:
After pressing tab:
Steps to reproduce
With the code below:
Expected behavior
I would expect the completion not to end.
company-complete-common
could stop inserting the common prefix at the first parenthesis.The text was updated successfully, but these errors were encountered: