sublime_text icon indicating copy to clipboard operation
sublime_text copied to clipboard

Unexpected completion auto-insertion

Open rchl opened this issue 3 years ago • 5 comments

Description of the bug

Here I'm selecting null in a JSON file and pressing " to surround it with quotes. After quotes are inserted, completions are requested and an LSP server responds with a single completion that suggests a null completion that gets automatically applied:

https://user-images.githubusercontent.com/153197/196772615-9ad7a949-b76c-439f-bc58-f2bc34129989.mov

Steps to reproduce

I haven't bothered creating small repro since I think this seems like a consequence of recent change that automatically applies completions when there is only one result.

Expected behavior

I think this is a case where single completion should not be auto-applied. Not sure if this case could be differentiated from "normal" cases and treated differently...

Actual behavior

Single completions interferes with the intent of adding quotes.

Sublime Text build number

4138

Operating system & version

macOS

(Linux) Desktop environment and/or window manager

No response

Additional information

No response

OpenGL context information

No response

rchl avatar Oct 19 '22 18:10 rchl

I thought that removing null and adding quotes would work but server still suggests null and it's automatically inserted:

https://user-images.githubusercontent.com/153197/196774265-ad4393d2-279f-4616-ae11-897789864847.mov

In light of such cases, it feels like it's not really correct to auto-insert single completions because there is no guarantee that user wants to actually insert that specific completion or just write something else...

rchl avatar Oct 19 '22 18:10 rchl

I suppose related: https://github.com/sublimehq/sublime_text/issues/4421

rwols avatar Oct 19 '22 18:10 rwols

It looks like that issue was misunderstood (not sure if by developer or the reporter but @jwortmann got it right in https://github.com/sublimehq/sublime_text/issues/4421#issuecomment-856805966) because it never seemed to behave in ST3 like it behaves now. ST3 would not insert the completion automatically. It would still show the popup when there was only one completion.

The part that was not working in ST4 was the case of manually pressing ctrl+space which did not insert the completion automatically anymore.

This is how it works in ST3:

https://user-images.githubusercontent.com/153197/196777015-ca9e991a-32f8-41c1-961f-7b82120b2ba6.mov

rchl avatar Oct 19 '22 18:10 rchl

The part that was not working in ST4 was the case of manually pressing ctrl+space which did not insert the completion automatically anymore.

Don't think this statement is very correct.

In ST3 you can enter html and hit tab to directly insert the one and only available completion/snippet (insert_best_completion is called). The result is <html>|</html>.

This behavior was broken by ST4. The completion popup is displayed instead. To commit the one and only item requires another tab.

With ST4138 the old behavior of insert_best_completion is restored.

Without having investigated it, may the described issue be triggered by how and when LSP triggers auto_complete command or by the auto_complete_selector and/or auto_complete_triggers it adds for certain languages?

EDIT:

Just installed LSP-pylsp. Can insert quotes around null with LSP-json enabled normally in ST4138 on Windows.

deathaxe avatar Oct 20 '22 15:10 deathaxe

In ST3 you can enter html and hit tab to directly insert the one and only available completion/snippet (insert_best_completion is called). The result is <html>|</html>.

Note how in ST3 it only expands on tab if the text matches html exactly and not when text is htm, even though ctrl+space still works to expand. So maybe ST3 considers it "best" only when the prefix matches exactly (in this case snippet).

EDIT: So in ST3 tab triggers insert_best_completion and requires that the prefix is matched exactly. ctrl+space triggers auto_complete and also auto-inserts but only if there is one completion.

With ST4138 the old behavior of insert_best_completion is restored.

I think that in 4138 it works "by accident" because the functionality is overzealous.

In any case, I guess the initial statement could be changed to say that this functionality should only be triggered when explicitly triggered by the user (using tab or ctrl+space) and not just on typing.

rchl avatar Oct 20 '22 17:10 rchl

Yes, html is the tab trigger for the html.sublime-snippet. ST3 seems to hide the html completion as there is a snippet with exectly the same tab trigger. Not sure, whether this is intented or a bug.

Nevertheless, html is expanded on perfect match only as the snippet is the only candidate.

If you try the same with e.g. table you'll see you can enter tabl hit tab key and it gets expanded to <table></table> directly.

I agree with the final statement. But tbh, this is what I see on my end. ST doesn't commit single completions while typing - at least when trying static sublime-completions or even PackageDev's or HTML's completion plugins. Hence I wonder whether and how it might be related or caused by how LSP handles completions.

EDIT:

In your example of surrounding null with quotes the following output is generated as soon as " is typed.

command: insert_snippet {"contents": "\"${0:$SELECTION}\""}
command: auto_complete
command: insert_snippet {"contents": "null"}

By default - with LSP disabled - only the insert_snippet command is inserted and everything is fine.

LSP seems to actively invoke auto_complete command, which is also executed by hitting ctrl+space. ST sees an explicit call and commits the one and only candidate.

Hence I'd blame LSP to cause the fault behavior by calling auto_complete explicitly.

Even after removing all tab triggers/selectors by ...

view.settings().set("auto_complete_selector", "")
view.settings().set("auto_complete_triggers", [])

... typing " still triggers auto_complete command after insert_snippet, which doesn't happen without LSP.

...

Wait ... it seems to be caused by LSP-json....

deathaxe avatar Oct 21 '22 15:10 deathaxe

The issue is caused by LSP-json

https://github.com/sublimelsp/LSP-json/blob/12f3548217f64c33f9196c38c8dc972571f6463e/plugin.py#L82-L87

which invokes auto_complete when typing "".

So I'd close this one as "invalid".

deathaxe avatar Oct 21 '22 16:10 deathaxe

Good point. I forgot about that...

I suppose it might be invalid then.

I've checked ST3 in a similar situation and it seems to only auto-insert single completion on second try for some reason but it feels buggy so hard to use it as an argument...

rchl avatar Oct 21 '22 18:10 rchl

Completions that have TextEdits(LSP-json uses text edits) are not implemented correctly in LSP for ST3... I would not even try to use LSP on ST3.

predragnikolic avatar Oct 21 '22 19:10 predragnikolic

ST 4139 extends the auto_complete command by an "commit_single": true argument to control, whether the command should auto commit a single completion candidate. This should fix this issue and maintain backward compatibility with plugins using it to force displaying auto completion panel.

deathaxe avatar Oct 29 '22 14:10 deathaxe

@deathaxe commit_single: true seems to only work for me if tab_completion is also true; I thought tab_completion was used only in the context of some default keybindings but that doesn't seem to be the case

aveia avatar Nov 11 '22 16:11 aveia

The difference between tab_completion: false and true is just whether a snippet's trigger must be fully entered or not to be directly committed.

In HTML for instance:

  • with tab_completion: false html needs to be entered for tab to expand the html snippet
  • with tab_completion: true ht is enough for tab to expand the html snippet

deathaxe avatar Nov 11 '22 17:11 deathaxe

@deathaxe the issue I have with this is tab_completion apparently has nothing to to with the tab key (except for being used in the context field of the key bindings); I have a ctrl+space key binding for auto_complete command being affected by this setting, which doesn't sound right. I thought adding commit_single would be enough to enable the "auto commit on single suggestion" behavior

aveia avatar Nov 11 '22 17:11 aveia

This sounds like a separate issue to me. Maybe you should open a new issue with some code examples and steps to reproduce the issue.

I tried some syntaxes and a single tab is very much enough to directly commit a single completion. But maybe I am missing some relevant detail.

EDIT: The only difference being tab_completion expanding "snippets" only - not completions.

deathaxe avatar Nov 11 '22 18:11 deathaxe

Fixed in Build 4139

hartsublime avatar Dec 14 '22 07:12 hartsublime