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

Key sequence terminating character is not considered to start a new one #6878

Open
KnorrFG opened this issue Apr 25, 2023 · 8 comments · May be fixed by #6960
Open

Key sequence terminating character is not considered to start a new one #6878

KnorrFG opened this issue Apr 25, 2023 · 8 comments · May be fixed by #6960
Labels
A-helix-term Area: Helix term improvements C-bug Category: This is a bug E-easy Call for participation: Experience needed to fix: Easy / not much E-good-first-issue Call for participation: Issues suitable for new contributors E-has-instructions Call for participation: Has instructions for fixing the issue and opening a PR

Comments

@KnorrFG
Copy link

KnorrFG commented Apr 25, 2023

Hey,
first of all, let me thank you for Helix. I love it. <3

To the point: I have this in my config:

[keys.insert]
j = { k = "normal_mode"}

and typically this works. However, when I type the sequence jjk in insert mode, it will input jjk, instead of inputting j, and then exiting insert mode. This seems to happen because a character that terminates a possible key-sequence is not considered to be able to start a new one.

This is quite annoying if you try to exit insert mode after typing a j as last character, like e.g. in obj. It's very minor, and you might not even consider it a bug, but I thought I'll bring it up.

@kirawi

This comment was marked as resolved.

@pascalkuthe
Copy link
Member

This issue is specific to insert mode the description is kind of a bit missleading. The problem is that in insert mode inserting text usually causes it to be inserted (this is not considered a keybinding but rather just the definition of insert mode).

To solve this issue we would need to add a special handling for the last pending key in

for ev in pending {
and call self.keymap.get again for the last key (similar to
if let KeymapResult::Matched(command) =
) and only insert the char if KeymapResult::NotFound is returned

@pascalkuthe pascalkuthe added E-easy Call for participation: Experience needed to fix: Easy / not much E-good-first-issue Call for participation: Issues suitable for new contributors E-has-instructions Call for participation: Has instructions for fixing the issue and opening a PR C-bug Category: This is a bug labels Apr 25, 2023
@pascalkuthe
Copy link
Member

pascalkuthe commented Apr 26, 2023

this is already existing functionality in helix and a simple bugfix for that.

Actually I think this bug doesn't just occur in insert mode but also in normal mode and visual mode. The general issue is that with KeymapResult::Cancelled we still need to try if any key is bound to the pressed key.

@kirawi kirawi added the A-helix-term Area: Helix term improvements label Apr 28, 2023
@sscheele
Copy link
Contributor

sscheele commented May 2, 2023

@pascalkuthe I think your proposed fix doesn't behave as I'd expect. If we do as you suggest, then the test case of typing "jjk" in insert mode would insert "jj" and exit to normal mode. If I had set up my config file as KnorrFG did, I would expect that only "j" would be inserted. However, I can't think of a solution that doesn't set up a weird thing where no typable prefix of an insert-mode keybinding can be inserted until the binding fails to match.

@pascalkuthe
Copy link
Member

It's hard to know without looking at your code but the idea was that basically the last canceled chars get reprocessed to check for keybindings and to not insert the char for it in that case. So basically for the for loop I linked you would need to do let last = pendigg.pop()

@sscheele
Copy link
Contributor

sscheele commented May 3, 2023

Ah, I misunderstood your suggestion, I've implemented a fix based on your comment here: master...sscheele:helix:ins-bindings. However, I think a better approach might be to modify the trie code to add a CancelledPending result or something so that this edge case doesn't have to be handled explicitly every time we use the trie.

Edit: CancelledPending would indicate that the processed event cancels a previously pending sequence but also starts a new pending sequence. Maybe not the best name, it was just the first thing I came up with.

@pascalkuthe
Copy link
Member

pascalkuthe commented May 3, 2023

This is a general issue and also a problem in normal mode so you are right that this is a bit to specific. I was sort of getting at that with

Actually I think this bug doesn't just occur in insert mode but also in normal mode and visual mode. The general issue is that with KeymapResult::Cancelled we still need to try if any key is bound to the pressed key.

You can probably handle this generically in handle_keymap_event. It's a bit hard to see trough but that function actually only ever returns Some(KeymapResult::NotFound) Some(KeyMapResult::Canceled(..)) and None.

At the end of the function, you can special case KeympaResult::Cancelled(..) do the same logic you just implemented (but instead of inserting text in the NotFound case you should just push the key event back to the list if the function returned Some(..)). This should handle all cases.

@kmicklas
Copy link
Contributor

Should we close this as duplicate of #2612 (which has more discussion)? Although this one gives a different model of the underlying problem, the high level symptom is the same.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-helix-term Area: Helix term improvements C-bug Category: This is a bug E-easy Call for participation: Experience needed to fix: Easy / not much E-good-first-issue Call for participation: Issues suitable for new contributors E-has-instructions Call for participation: Has instructions for fixing the issue and opening a PR
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants