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

Make it easier to remove the text inserted by completion and to apply edits afterwards #2898

Closed
ul opened this issue May 6, 2019 · 7 comments

Comments

@ul
Copy link
Contributor

ul commented May 6, 2019

Use case: kak-lsp receives completions as text edits from language server and need to discard completion item suffix inserted by Kakoune's completions system to apply text edit properly. Also, kak-lsp need to be able to do it for all selections before it fans out text edit on them.

I mostly solved this problem by doing some selection based on the cursor positions when completion was triggered and the length of the label provided to completion system. But when a user commits completion candidate with <ret> things get tricky because of the lines shift.

I would be nice to trigger InsertCompletionHide before inserting the character which user pressed a key for. It will solve removing suffix and translating text edit to multiple selections.

As a further improvement, InsertCompletionHide could provide selection_descs as hook_param for inserted suffixes so removal could happen in lsp.kak without need to generate command on a Rust side of the plugin.

@ul
Copy link
Contributor Author

ul commented May 12, 2019

Related: #2347

@mawww
Copy link
Owner

mawww commented Jun 27, 2019

Running InsertCompletionHide before inserting the user selected character would be a bit tricky, but we can definitely change the parameter to pass the set of inserted ranges. Would that be sufficient to fix your use case ?

@ul
Copy link
Contributor Author

ul commented Jun 28, 2019

Yes, providing inserted ranges would be enough. To double-check that we understand each other let me use a specific example:

first line
second l<main 1-char selection of space> foo
third l<secondary 1-char selection of space> bar

and completions menu is open and shows line as a selected option. The user than presses <ret> and the file looks like:

first line
second line
<main 1-char selection of space> foo
third line
<secondary 1-char selection of space> bar

I'd expect ranges provided by InsertCompletionHide to be something like this: 2.9,3.1 4.8,5.1. Does it make sense?

@mawww
Copy link
Owner

mawww commented Jun 28, 2019

Hum, in the case you describe, I would have expected 2.9,2.2.12 4.8,4.11 as ranges are inclusive, and the last element of the inserted text is the end of line. Basically, I would expect evaluate-commands select "%val{hook_param}"; execute-keys d to get back to the initial state.

@ul
Copy link
Contributor Author

ul commented Jun 28, 2019

Oh right, I included character which was selected before insertion, sorry for confusion. What you described is more logical and convenient behaviour.

@mawww
Copy link
Owner

mawww commented Dec 1, 2019

I consider that fix experimental, please give it a go, but I must say I am not entirely happy about it in the end (it feels a bit brittle)

@ul
Copy link
Contributor Author

ul commented Dec 24, 2019

Thank you! I think I'll have time to play with it soon. Can't wait to finally resolve kak-lsp#40 =)

krobelus added a commit to krobelus/kakoune that referenced this issue May 29, 2022
… menu

Insert mode completions are accepted by typing any key.  For example,
if there is a completion "somefunction()", then typing

	some<c-n>;

will insert

	somefunction();

and then the InsertCompletionHide hook will fire.  The hook parameter
is a range that contains the entire thing: the actual completion plus
the trailing semicolon that closed the completion menu.

The [original motivation] for the hook parameter was to support
removing text inserted by completion, so we can apply text edits
or expand snippets instead. One problem is that we don't want to
remove the semicolon. Another problem came up in a discussion
about [snippets]: let's say we have a snippet "add" that expands to

	add(?, ?)

where ? are placeholders. After snippet expansion the cursor replaces
the first placeholder. If I type "ad<c-n>1" I expect to get "add(1, ?)".
If the InsertCompletionHide hook only runs after processing the "1"
keystroke, this is not possible without evil hacks.

Fix these problems by running InsertCompletionHide when a completion is
accepted _before_ inserting anything else into the buffer.  This should
make it much easier to fully implement [LSP text edits]. I doubt
that anyone besides kak-lsp is using the hook parameter today so this
should be a low-risk fix.

[original motivation]: mawww#2898
[snippets]: kakoune-lsp/kakoune-lsp#616 (comment)
[LSP text edits] kakoune-lsp/kakoune-lsp#40
krobelus added a commit to krobelus/kakoune that referenced this issue May 29, 2022
… menu

Insert mode completions are accepted by typing any key.  For example,
if there is a completion "somefunction()", then typing

	some<c-n>;

will insert

	somefunction();

and then the InsertCompletionHide hook will fire.  The hook parameter
is a range that contains the entire thing: the actual completion plus
the trailing semicolon that closed the completion menu.

The [original motivation] for the hook parameter was to support
removing text inserted by completion, so we can apply text edits
or expand snippets instead. One problem is that we don't want to
remove the semicolon. Another problem came up in a discussion
about [snippets]: let's say we have a snippet "add" that expands to

	add(?, ?)

where ? are placeholders. After snippet expansion the cursor replaces
the first placeholder. If I type "ad<c-n>1" I expect to get "add(1, ?)".
If the InsertCompletionHide hook only runs after processing the "1"
keystroke, this is not possible without evil hacks.

Fix these problems by running InsertCompletionHide when a completion is
accepted _before_ inserting anything else into the buffer.  This should
make it much easier to fully implement [LSP text edits]. I doubt
that anyone besides kak-lsp is using the hook parameter today so this
should be a low-risk fix.

[original motivation]: mawww#2898
[snippets]: kakoune-lsp/kakoune-lsp#616 (comment)
[LSP text edits]: kakoune-lsp/kakoune-lsp#40
krobelus added a commit to krobelus/kakoune that referenced this issue May 29, 2022
… menu

Insert mode completions are accepted by typing any key.  For example,
if there is a completion "somefunction()", then typing

	some<c-n>;

will insert

	somefunction();

and then the InsertCompletionHide hook will fire.  The hook parameter
is a range that contains the entire thing: the actual completion plus
the trailing semicolon that closed the completion menu.

The [original motivation] for the hook parameter was to support
removing text inserted by completion, so we can apply text edits
or expand snippets instead. One problem is that we don't want to
remove the semicolon. Another problem came up in a discussion
about [snippets]: let's say we have a snippet "add" that expands to

	add(?, ?)

where ? are placeholders. After snippet expansion the cursor replaces
the first placeholder. If I type "ad<c-n>1" I expect to get "add(1, ?)".
If the InsertCompletionHide hook only runs after processing the "1"
keystroke, this is not possible without evil hacks.

Fix these problems by running InsertCompletionHide when a completion is
accepted _before_ inserting anything else into the buffer.  This should
make it much easier to fully implement [LSP text edits]. I doubt
that anyone besides kak-lsp is using the hook parameter today so this
should be a low-risk fix.

[original motivation]: mawww#2898
[snippets]: kakoune-lsp/kakoune-lsp#616 (comment)
[LSP text edits]: kakoune-lsp/kakoune-lsp#40
TeddyDD pushed a commit to TeddyDD/kakoune that referenced this issue Aug 19, 2022
… menu

Insert mode completions are accepted by typing any key.  For example,
if there is a completion "somefunction()", then typing

	some<c-n>;

will insert

	somefunction();

and then the InsertCompletionHide hook will fire.  The hook parameter
is a range that contains the entire thing: the actual completion plus
the trailing semicolon that closed the completion menu.

The [original motivation] for the hook parameter was to support
removing text inserted by completion, so we can apply text edits
or expand snippets instead. One problem is that we don't want to
remove the semicolon. Another problem came up in a discussion
about [snippets]: let's say we have a snippet "add" that expands to

	add(?, ?)

where ? are placeholders. After snippet expansion the cursor replaces
the first placeholder. If I type "ad<c-n>1" I expect to get "add(1, ?)".
If the InsertCompletionHide hook only runs after processing the "1"
keystroke, this is not possible without evil hacks.

Fix these problems by running InsertCompletionHide when a completion is
accepted _before_ inserting anything else into the buffer.  This should
make it much easier to fully implement [LSP text edits]. I doubt
that anyone besides kak-lsp is using the hook parameter today so this
should be a low-risk fix.

[original motivation]: mawww#2898
[snippets]: kakoune-lsp/kakoune-lsp#616 (comment)
[LSP text edits]: kakoune-lsp/kakoune-lsp#40
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

2 participants