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

Add insert-replace support for completions #1809

Merged
merged 25 commits into from
Sep 12, 2022

Conversation

predragnikolic
Copy link
Member

@predragnikolic predragnikolic commented Jul 25, 2021

output

New:

  • setting for determining the completion_insert_mode(defaults to "insert") Available: "insert" or "replace".
  • enter/tab will commit the completion item with the default insert mode.
  • shift+enter/shift+tab will commit the completion item with the opposite insert mode.

I have tested this only with the LSP-angular server.

Closes #1413

@jwortmann
Copy link
Member

It's pretty cool, but at least Shift+Tab conflicts with a default keybinding when the autocomplete popup is visible (described in the ST preferences under "tab_completion"). Maybe it's better to leave the keybinding commented out by default, like most of the other keybindings? Additionally I would add another context {"key": "lsp.session_with_capability", "operand": "completionProvider"} to it.

An alternative could be Ctrl+Tab ("primary+tab"), which indeed has a default binding too (switch to next file tab), but not specific to when the autocompletion popup is visible. But it's not as easy to type as Shift+Tab.

The possible options "insert"/"replace" should probably also be mentioned in the comment which describes the setting.

@rwols
Copy link
Member

rwols commented Jul 25, 2021

I was thinking of adding additional text in the st_detail field to distinguish insert/replace variants, instead of a command. The current diff isn’t very discoverable. I wonder how many people will really use this feature.

LSP.sublime-settings Outdated Show resolved Hide resolved
@rchl
Copy link
Member

rchl commented Jul 25, 2021

I was thinking of adding additional text in the st_detail field to distinguish insert/replace variants, instead of a command. The current diff isn’t very discoverable. I wonder how many people will really use this feature.

Even knowing about this feature, I probably wouldn't remember to pick the right insert mode by using a different shortcut. Especially if we don't indicate anywhere that the "replace" is supported by the given completion. Without indication, the user would never know if both the server and the given completion supports it and it would be a guessing game.

@jwortmann
Copy link
Member

I would maybe even remove the setting and always use the "insert" mode with the regular Tab/Enter binding for completions - just like it is now, and because it's the way how completions work in general in ST.

Without indication, the user would never know if both the server and the given completion supports it and it would be a guessing game.

I agree, this should be indicated in some way. Otherwise it would be confusing why it doesn't work most of the time (probably most servers don't support it).

I was thinking of adding additional text in the st_detail field to distinguish insert/replace variants

If I understand it correctly, that would mean to duplicate the entries which use InsertReplaceEdit? I don't like this approach a lot, because multiple entries with the same label is the thing I dislike the most in autocompletions. It requires to read more info (from the annotation hint or details field) to pick the correct one, and it breaks the typing flow if you need to scroll down first in case the order is wrong (or if you want to see the details for the other entries). So I think I would prefer a keybinding for the "replace" mode, provided that it doesn't conflict with an existing default binding.

@predragnikolic predragnikolic marked this pull request as draft September 29, 2021 20:54
@TerminalFi
Copy link
Contributor

This feature also looks really slick.

@predragnikolic
Copy link
Member Author

I tried to mimic VS code behavior with this PR.

https://m.youtube.com/watch?v=QIze0qkugNc

In the PR description I haven't explained in detail why I implemented this the way I did
and that is simply that users switching from VS Code to ST could easily transfer their knowledge.


I wanted to create a second draft, that would address all the feedback from this draft and then I would let people decide between the 2 drafts.

Currently I do not think that I will do such a draft in the near time.

@rchl
Copy link
Member

rchl commented Jun 22, 2022

In case it makes it easier, I'm gonna state now that I'm fine with how it is now if you just update the setting description. I will look once again through the changes after it's rebased and addressed.

As far as disabling key bindings by default, I'm not sure... That would make the feature very niche. I think that it would be fine to have them enabled by default as long as the behavior fall backs to ST default if completion doesn't use InsertTextReplace. Not sure how easy that would be though...

When it comes to marking completion details with something to indicate that insert/replace is supported, this could be done without duplicating completions. The challenge would be to figure out what to show as it might be hard to find a short text/symbol that would be easily recognizable and meaningful to everyone.

…capability to context for shift+enter

// When enabled, pressing tab will insert the best matching completion.
// When disabled, tab will only trigger snippets or insert a tab.
// Shift+tab can be used to insert an explicit tab when tab_completion is
// enabled.
"tab_completion": true,
@predragnikolic
Copy link
Member Author

I removed shift+tab to not cause conflict with ST default behavior.

@predragnikolic
Copy link
Member Author

I added the following text next to the More link in the autcomplete popup, to make it more noticeable.

But I am still unsure if I would like to clutter the autocomplete popup with this text...

image

Note: I had "completion_insert_mode": "replace" in LSP.sublimse-settings, and thus I saw "⇧ + ↵ to insert"

plugin/completion.py Outdated Show resolved Hide resolved
Default.sublime-keymap Outdated Show resolved Hide resolved
plugin/core/views.py Outdated Show resolved Hide resolved
To allow the user to assign different keybindings,
and to avoid showing a keybinding that is not true, "⇧ + ↵" section is removed from the popup.
@predragnikolic predragnikolic marked this pull request as ready for review September 6, 2022 10:24
@predragnikolic
Copy link
Member Author

Should we rename
lsp_commit_completion_with_opposite_insert_mode to something more `short:

a) lsp_complete_with_opposite_insert_mode
b) lsp_insert_replace_complete

{
"command": "lsp_commit_completion_with_opposite_insert_mode",
"keys": [
"shift+enter"
Copy link
Member

Choose a reason for hiding this comment

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

This also conflicts with the built-in key binding to insert a newline if the completion popup is visible.

It doesn't affect me personally, because I activated the "auto_complete_commit_on_tab" setting, but I would expect this to disturb many users if the built-in functionality suddenly isn't available anymore. It might be acceptable to provide key bindings which are direct replacements of built-in functionality, but with an override like this one here, I doubt that the LSP package would get accepted to Package Control if it had to re-apply for it.

Copy link
Member Author

Choose a reason for hiding this comment

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

Can you point to the conflicting keybinding?

There are of shift+enter keybindings in ST,
but none with a context when auto_complete_visible is visible.

            {
                "key": "auto_complete_visible",
                "operator": "equal",
                "operand": true
            },

So I did not see it conflicting.

Copy link
Member

Choose a reason for hiding this comment

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

Unbenannt

The "context" only applys restrictions to a key binding. This one doesn't have a "context" restriction, so it is always activated. If the key binding from this PR gets added, it will be loaded after the default one, and therefore the default binding will be shadowed and won't work anymore.

Or do I have some misconception somewhere in my thoughts?

Copy link
Member Author

Choose a reason for hiding this comment

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

Nope, you are correct. In this case the lsp_commit_completion_with_opposite_insert_mode keybinding will have precedence. :)

But is that bad?
I mean other "shift+enter" ST keybinding also have contexts
and could also be seen as conflicting with this "shift+enter" insert \n keybinding, right?

In our case,
the lsp_commit_completion_with_opposite_insert_mode will conflict only if the auto complete popup is visible and the user is in a file supported by LSP.

Copy link
Member

Choose a reason for hiding this comment

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

Maybe this will make it more clear:
If you start ST in safe mode (all default settings), then you can commit a completion with Enter. But if you instead want to add a linebreak when the completion popup is visible, you can press Shift+Enter.
Now someone installs the LSP package and suddenly and without any warning Shift+Enter doesn't work anymore if a language server is running. Because it will then still commit the completion (with the opposite LSP insert mode), instead of the usual linebreak.

But is that bad? I mean other "shift+enter" ST keybinding also have contexts and could also be seen as conflicting with this "shift+enter" insert \n keybinding, right?

But the other ST key bindings are for when the command palette or find or replace panel has focus. So they are not relevant regarding auto completions.
If we start overriding built-in key bindings for different functionality, then I guess we could also hijack for example Ctrl+R for ... let's say e.g. LSP's formatting feature. And if users want to keep using ST's "Goto Symbol" they can just reassign another key binding for it :D
Or maybe let's reassing ST's key binding for toggle_comment to something different, because who needs that anyway... :)

In our case, the lsp_commit_completion_with_opposite_insert_mode will conflict only if the auto complete popup is visible and the user is in a file supported by LSP.

Well, but this is exactly the critical point. If the auto complete popup is not visible, then the built-in Shift+Enter binding is not useful anyway, because you can just press regular Enter without the Shift key to insert a linebreak.

Copy link
Member Author

Choose a reason for hiding this comment

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

You explained that well, thanks!
OK, I will remove the keybinding, and let the user configure it :)

Copy link
Member Author

Choose a reason for hiding this comment

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

@predragnikolic
Copy link
Member Author

Closes #1413

@rchl
Copy link
Member

rchl commented Sep 7, 2022

Closes #1413

I think this needs to be added to the initial comment to actually have an effect on merging.

tests/test_completion.py Outdated Show resolved Hide resolved
sublime-package.json Outdated Show resolved Hide resolved
LSP.sublime-settings Outdated Show resolved Hide resolved
sublime-package.json Outdated Show resolved Hide resolved
LSP.sublime-settings Outdated Show resolved Hide resolved
Copy link
Member

@rchl rchl left a comment

Choose a reason for hiding this comment

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

Given that it's a functionality that is not bound to a key binding by default and even when bound the discoverability is low (not clear when "replace" can be used), I find it a bit hard to justify.

But who am I judge, maybe someone will find it useful.
Let's merge after one more person gives an approval.

@predragnikolic
Copy link
Member Author

predragnikolic commented Sep 9, 2022

How about "alt+enter" for the default keybinding?

@rchl
Copy link
Member

rchl commented Sep 10, 2022

Seems fine to me. Someone might still be using it to insert a line break but since shift+enter works it might not be a problem.

@rchl
Copy link
Member

rchl commented Sep 10, 2022

I'm still thinking how we could visualize if completion supports insert/replace...

  • It shouldn't mention specific key binding as we can't tell which one is defined.
  • It shouldn't take too much space.

Some ideas:

  • add [I/R] in the details field -- a bit too cryptic perhaps?
  • say "(supports replace)" if "insert" is the default mode and "(supports insert)" if "replace" is the default mode -- a bit long?
  • ???

@predragnikolic predragnikolic marked this pull request as draft September 11, 2022 12:56
@predragnikolic
Copy link
Member Author

predragnikolic commented Sep 12, 2022

How about the following?

Provide a default keybinding "alt+enter",
"Replace" or "Insert" will be show at the bottom of the AC popup. So that can give an indication that the server supports insert/replace.

output1

Copy link
Member

@rchl rchl left a comment

Choose a reason for hiding this comment

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

I like the idea.

plugin/completion.py Outdated Show resolved Hide resolved
Comment on lines +1029 to +1030
text_edit = item.get('textEdit')
if text_edit and 'insert' in text_edit and 'replace' in text_edit:
Copy link
Member

Choose a reason for hiding this comment

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

Sorry, don't have time to check the spec now, but is it necessary to check for textEdit?

Copy link
Member Author

@predragnikolic predragnikolic Sep 12, 2022

Choose a reason for hiding this comment

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

yes, there is a type error otherwise :)

- if text_edit and 'insert' in text_edit and 'replace' in text_edit:
+ if 'insert' in text_edit and 'replace' in text_edit:

docs/src/features.md Outdated Show resolved Hide resolved
@predragnikolic predragnikolic marked this pull request as ready for review September 12, 2022 09:03
@rchl rchl changed the title Add insert replace support Add insert-replace support for completions Sep 12, 2022
@rchl rchl merged commit 1be82e1 into main Sep 12, 2022
@rchl rchl deleted the completion-item-insert-replace-support branch September 12, 2022 19:30
rchl added a commit that referenced this pull request Sep 27, 2022
* main:
  Add insert-replace support for completions (#1809)
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.

Look into InsertReplaceEdit for completions
5 participants