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

Returning a CompletionList() on on_query_completions always do INHIBIT_WORD_COMPLETIONS #4999

Open
evandrocoan opened this issue Nov 2, 2021 · 10 comments

Comments

@evandrocoan
Copy link

evandrocoan commented Nov 2, 2021

Description of the bug

on_query_completions returning an empty CompletionList() always do INHIBIT_WORD_COMPLETIONS.

I use LSP, and it uses this CompletionList() on on_query_completions. This causing the LSP setting prefs.inhibit_word_completions not work because Sublime Text by itself alwasy do INHIBIT_WORD_COMPLETIONS even if CompletionList() is not requesting it.

Steps to reproduce

Create this plugin:

class OnQueryContextBugEventListener(sublime_plugin.EventListener):
    def on_query_completions(self, view, prefix, locations):
        clist = sublime.CompletionList()
        return clist

Try to complete something. You will never complete anything ever unless you give completions to CompletionList().

Expected behavior

Only do INHIBIT_WORD_COMPLETIONS on on_query_completions when returning CompletionList() with INHIBIT_WORD_COMPLETIONS flag.

Actual behavior

Doing INHIBIT_WORD_COMPLETIONS on on_query_completions when not returning CompletionList() with INHIBIT_WORD_COMPLETIONS flag.

Sublime Text build number

4121

Related

  1. on_query_completions fails to return custom completions when some characters are used #819 on_query_completions fails to return custom completions when some characters are used
  2. Allow inhibiting word completions based on a scope selector #3643 Allow inhibiting word completions based on a scope selector
  3. Some completions not shown on pressing dot while handling dynamic completions #4855 Completions not shown on pressing dot while handling dynamic completions
  4. [ST4] Cancel pending completion future when one of the items in auto_complete_triggers matches #3796 [ST4] Cancel pending completion future when one of the items in auto_complete_triggers matches
@evandrocoan evandrocoan changed the title on_query_completions CompletionList() always do INHIBIT_WORD_COMPLETIONS Returning a CompletionList() on on_query_completions always do INHIBIT_WORD_COMPLETIONS Nov 2, 2021
@evandrocoan
Copy link
Author

Adding sublime.set_timeout(lambda: clist.set_completions([], 0)) before return clist seems to "fix" the problem:

class OnQueryContextBugEventListener(sublime_plugin.EventListener):
    def on_query_completions(self, view, prefix, locations):
        clist = sublime.CompletionList()
        sublime.set_timeout(lambda: clist.set_completions([], 0))
        return clist

@rchl
Copy link

rchl commented Nov 2, 2021

a) I believe your way to "fix" the problem would make it impossible to call set_completions later, with actual completions, thus making the whole on_query_completions useless.

b) the behavior seems to me to be like that on purpose since you don't want your word completions to appear until all completions are collected. Otherwise, there might be a situation where the word completions show up just to disappear in 1 second after on_query_completions resolves the completions with the INHIBIT_WORD_COMPLETIONS flag.

That said, maybe it should be possible to decide the value of the INHIBIT_WORD_COMPLETIONS flag earlier (before the completions are resolved).

@evandrocoan
Copy link
Author

I do not see the point for CompletionList having the flags with default value 0. As I am not adding INHIBIT_WORD_COMPLETIONS to the CompletionList flag's value, I would expect Sublime Text to show word completions while CompletionList.set_completions was not called.
image

I agree that accepting flags on CompletionList and on set_completions would create the awkward behavior of completions showing up and disappearing if I do not pass INHIBIT_WORD_COMPLETIONS to CompletionList, but add INHIBIT_WORD_COMPLETIONS to set_completions.

A reasonable solution would be for the flag's value to be accepted only on CompletionList, but not on set_completions.

the behavior seems to me to be like that on purpose since you don't want your word completions to appear until all completions are collected.

This would be an unacceptable behavior for me because I would like to get both word completion and the language server completions. With the current LSP implementation, I was never getting word any completions from Sublime Text (no completions in comments, either anywhere else). And the flag INHIBIT_WORD_COMPLETIONS was not used on set_completions or anywhere else.

I really hate the usage of INHIBIT_WORD_COMPLETIONS because it completely disables autocompletion when:

  1. I am typing a comment
  2. I am refactoring my code and language server cannot decide for completions right
  3. I would like to complete something else because I am about to refactor things
  4. I would like to complete something and I do not have the correct context for the language server to provide completions yet
  5. That is the main reason I hate IDEs and only use Sublime Text, they usually do not show word completions (for example https://intellij-support.jetbrains.com/hc/en-us/community/posts/207017785-word-completion-feature) and use gigabytes of RAM memory to work with a single language only

Sublime Text built-in word completion is incredible for me at least because by itself it decides most of the time the right completion just based on the word usage/frequency. The language server for me is just a complement to get completions from other files which are not currently open.

@rchl
Copy link

rchl commented Nov 3, 2021

Now that you explain it like that, it sounds like a different issue.

Now, the problem with your initial example plugin is that you never resolve the completions so that can affect the results. Can you make a test case that properly resolves the completion (maybe after few seconds)? Does the problem still reproduce then? I would assume that the word completions are shown once the completion list returned from on_query_completions is resolved.

With LSP there should never be the case that the completion list is never resolved. It might take a second or two with slow servers but should always get resolved eventually.

@evandrocoan
Copy link
Author

If I either resolve the completion (one time at least) as done in my "fix" example, or a few seconds later, the word completion shows up, but the difference is that if I add x seconds delay, it takes x seconds for any completion to show up. I rather see the word completion sublime text can build in milliseconds than wait for slower language servers. My LSP was never getting completions for the language server and this is causing word completions to not show up, then, I end up with no completions at all, when I am in places as comments, for example.

@rchl
Copy link

rchl commented Nov 6, 2021

What your are asking for would be a bad experience because user would get word completions right away and then when more relevant completions would come from LSP, the selections would either have to jump to more relevant completions or stay at less relevant. Neither would be good.

Not sure what you mean by

My LSP was never getting completions for the language server and this is causing word completions to not show up

By "my LSP" do you mean LSP package or your own LSP server? Because it sounds like a bug in either.

@evandrocoan
Copy link
Author

evandrocoan commented Nov 6, 2021

What your are asking for would be a bad experience

I am not getting any Sublime Text word completions with https://github.com/sublimelsp/LSP-pylsp language server.

If the user enabled the setting prefs.inhibit_word_completions, he would expect to always have word completions, whether they come after the LSP or before I would not care.

What is the point of using asynchronous word completion, if you do not incrementally add completions when they are available? If words from Sublime text are available, I would like to see them right now instead of waiting a few seconds for all of them.

Whether you like word completion or not, it does not change the fact that CompletionList() accepts the flags argument and it by doing INHIBIT_WORD_COMPLETIONS, even if I am not using INHIBIT_WORD_COMPLETIONS (by adding 0 to it).

  1. No language server will be as fast as the built-in completions from the sublime text, which shows up immediately.
  2. For the LSP, I also removed your flag sublime.INHIBIT_REORDER, I trust more Sublime Text to do the ordering (by usage frequency) other than the language server (unknow sorting algorithm).
  3. I only care to have the completions available. Sublime Text is not an IDE/Pycharm/Android Studio, or whatever. It is a text editor. If I would like to have a strict IDE behavior, I would not use Sublime Text.

@rchl
Copy link

rchl commented Nov 6, 2021

I am not getting any Sublime Text word completions with sublimelsp/LSP-pylsp language server.

Then maybe deal with that issue? Is it because pylsp never responds to the completion request? That would be a bug in it that should be then fixed. Or is it just very slow, which pylsp is kinda known for? You can switch to LSP-pyright or disable the completions handling in LSP-pylsp completely.

If the user enabled the setting prefs.inhibit_word_completions, he would expect to always have word completions, whether they come after the LSP or before I would not care.

I think many would care since then people would get the less relevant (most of the time useless) word completion selected by default rather than something relevant for the given context (like when completing property name).

What you are asking for maybe would make sense to you in which case maybe a new setting could be added in core but changing the behavior of the current settings or flags is not the way to go.

So I have a bit of an issue with how this issue is phrased, making it look like a bug. If you would create a feature request for it, that would make more sense IMO.

3\. I only care to have the completions available. Sublime Text is not an IDE/Pycharm/Android Studio, or whatever. It is a text editor. If I would like to have a strict IDE behavior, I would not use Sublime Text.

ST is not an IDE but the point of LSP is exactly to make the coding work like in an IDE. So maybe don't use LSP then?

@rwols
Copy link

rwols commented Nov 6, 2021

An IDE is is an integrated development environment, that means you download a thing and you'll get a bunch of toolchains to get started easily, no need to use a terminal. Press a "play" button and your GUI program shows up ready to debug. LSP doesn't turn Sublime Text into an IDE.

@rwols
Copy link

rwols commented Nov 6, 2021

When I set inhibit_word_completions to false in Packages/User/LSP.sublime-settings I get word completions among my language server completions, in this case pyright:

Schermopname.2021-11-06.om.20.31.59.mov

I don't get word completions in comments. But that's because the global auto_complete_selector disables them by default:

>>> view.settings().get("auto_complete_selector")
'meta.tag, source - comment - string.quoted.double.block - string.quoted.single.block - string.unquoted.heredoc'

This value is set in the default Preferences.sublime-settings.

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

No branches or pull requests

3 participants