-
-
Notifications
You must be signed in to change notification settings - Fork 896
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
fix: use a transient map to avoid overlay keymaps issues #4676
base: master
Are you sure you want to change the base?
Conversation
This PR hopefully fixes the issue reported here . The error reported by @farazshaikh seems to be the same one I was seeing, so if they could provide some clarification or maybe test these changes, it'd be great. |
It also fixes the issue reported in this other comment by @thecsw. The client now obeys |
10501d9
to
826cb5d
Compare
@kiennq FYI |
clients/lsp-copilot.el
Outdated
@@ -204,7 +219,7 @@ automatically, browse to %s." user-code verification-uri)) | |||
:download-server-fn (lambda (_client callback error-callback _update?) | |||
(lsp-package-ensure 'copilot-ls callback error-callback)) | |||
:notification-handlers (lsp-ht | |||
("$/progress" (lambda (&rest args) (lsp-message "$/progress with %S" args))) | |||
("$/progress" #'lsp-copilot--progress-callback) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This has a default handler in lsp--default-notification-handlers
already, we might not need this here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The lsp-progress-function is called in this copilot-specific handler.
I added it because of panel completions (see here ).
Whether we decide that panel completions should be part of lsp-mode or of some other package, we need some copilot-specific handling of the progress notification.
I'd rather not advise the global progress handler to be able to collect panel completions, so I believe a copilot-specific function is a better strategy.
If lsp-mode already has a way of tapping into progress notifications for extra handling that is specific to some client , let me know!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've opened a draft MR with the panel changes so you can better understand why panel completions require copilot-ls handling $/progress
notifications.
Instead of using transient map and cleaning up of it. Would using |
I'll try that and come back to you. I did not like how this fix makes state management a bit messy, so I'd be happy with a simpler solution ;) (Though I'm not sure what would happen in the case where the smartparens overlay is visible (binding |
Hey @kiennq I've tried:
The results were not great. The issue is keymap priority. I tried to force the minor-mode keymap to be the first one in the I did not find much documentation on how to handle these conflicting bindings from different minor-mode maps, except texts pointing to I've pushed here the changes needed to use overriding local map directly (ignore the changes in lsp-copilot.el and the ones regarding inhibition) . See if it looks better this way -- if so, I'll cherry pick the necessary changes and update this MR. |
FWIW evil uses |
Thanks @fnussbaum! That explains a lot! So IMHO using I'll cherry pick the changes and update the PR |
…y keymap Despite having higher priority, the inline completion overlay keymap may not be active when other overlays around point also define a keymap. This can be observed with smartparens -- upon inserting a pair, smartparens creates an overlay to track the inserted pair. This overlay has a keymap binging only `C-g`. Nonetheless, if the user triggers inline completions inside a recently inserted pair such as the example below (cursor at `|') value = [ | ] then the inline completion shown at `|' would now have its keymap active. In that case, pressing `C-g' once would call the smartparens function that removes the current overlay, and afterwards the inline completion overlay would be active. This results in weird behaviours -- e.g. pressing `C-g' once does not cancel the suggestion, but twice does; Pressing `C-<return>' results in a "C-<return> is undefined" message, etc. This change updates the inline completion mechanism to use `overriding-terminal-local-map`. This ensures that the inline completion keymap is active when the overlay is shown (see https://www.gnu.org/software/emacs/manual/html_node/elisp/Searching-Keymaps.html). Since the inline completion keymap binds `[t]' to a "hide and execute whatever command was bound before", we end up with the expected behaviour of the overlay keymap.
6b205e9
to
69803ce
Compare
@kiennq that should do it. We're now just replacing the overlay keymap by a overriding-terminal-local-map associated with the overlay and keys message. This has been working just fine here for me ;) (On a side note, that's similar to what |
When some other overlay is active at point with a keymap property, even when
its priority is lower than the inline completion overlay's, this foreign keymap
may take precedence over our inline completion keymap.
This happens, for example, when the inline completion is shown inside a pair
inserted by smartparens. For example, when the user types
[
, smartparens will insert the closing]
pair and leave the cursor inside the pair --[|]
. The user then presses<return>
.The result is the buffer with the following state (cursor at
|
:When Smartparens inserts the closing pair, it creates an overlay from
[
to up]
. This overlay has akeymap property mapping
C-g
to a function that removes the overlay.When an inline completion is shown (either on idle or by user request), the
keymap from smartparens overlay is active despite the inline completion
overlay's higher priority.
As a result, pressing
C-<return>
will likely display a message complainingthe key is not bound.
If the user presses
C-g
once, then they gain access to the inline completionkeymap.
This caused a weird bug in which a user gets a suggestion, but can't accept
it. Pressing C-g only once would not cancel the completion, but pressing it
again would indeed hide the completion overlay. Explicitly asking for a
suggestion at the same point would then display the completion overlay and the
keymap would work as expected, since the first
C-g
removed the smartparensoverlay.
This commit fixes the issue using
overriding-terminal-local-map
. This ensures that the inline completionkeymap is active when the overlay is shown (see
https://www.gnu.org/software/emacs/manual/html_node/elisp/Searching-Keymaps.html).
Since the inline completion keymap binds
[t]
to a "hide and execute whatevercommand was bound before", we end up with the expected behavior of the
overlay keymap.