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

Delaying input for multi-key combinations #3082

Closed
DimmyJing opened this issue Sep 30, 2018 · 3 comments · Fixed by #4735
Closed

Delaying input for multi-key combinations #3082

DimmyJing opened this issue Sep 30, 2018 · 3 comments · Fixed by #4735

Comments

@DimmyJing
Copy link

Is your feature request related to a problem? Please describe.

I'm always frustrated when I type part of a key combination and the line moves along with the first key. For example, I have remapped jk to and the editor would always type out the j, deleting it after I type the k.

Describe the solution you'd like

The solution by NeoVim is to replace the next character with the character you're typing, and inserting the character after it times out. Personally, I find it to be a much cleaner solution.

Describe alternatives you've considered

I have no idea for the possibility for this feature, but just delaying the actual insertion for the key would be enough.

Additional context

What VSCode does
whathappens
What VSCode should do
whatshouldhappen

@shawnaxsom
Copy link
Contributor

Minor note that this sounds similar to what I mentioned (but didn't handle) in #3081. We do have some sort of timeout logic in the app (see: withinTimeout in modeHandler.ts), but it doesn't appear to match standard Vim behavior. I'm not sure whether that deviation in behavior was intentional.

As you mention, standard Vim will usually delay insertion if it knows that there is a potential mapping with additional keys. I'm assuming the expected behavior would be feasible without too much change, but I'd have to investigate further.

@mauricecruz
Copy link

Chiming in here to see if any discovery was made towards this issue. I also remapped my keys similarly. The character insertion ends up in the history buffer which makes undo'ing actions noisy. 😞

@DimmyJing
Copy link
Author

I've looked through the code and I think I found a possible solution to this problem.

Basically the character after the cursor would be overridden by the current key if the isPotentialRemap property of class Remappers is true, and the cursor would be moved back one step. So mappings such as jk to would be |test -> |jest -> |test

Every consecutive character would also override the character right after the cursor and move back the cursor by one step. So, for example, three-letter mappings such as abc to would be |test -> |aest -> |best -> |test

Failed remappings should be like |test -> |jest -> jk|test and |test -> |aest -> |best -> abc|test

To implement this, I think vimState can add a new char field called something like overwrittenChar that holds the character that was overwritten.

Then the first part of the handleRemapping function in remapper.ts could be modified to only replace the letter after the cursor position to overwrittenChar

And there could be another function somewhere called remapFailed that is called whenever the next character sets isPotentialRemap to false or the current key has timeout: the current time - vimState.lastKeyPressedTimestamp is greater than configuration.timeout

What remapFailed does is basically replace the character after the cursor to overwrittenChar, add the letters in vimState.recordedState.commandList before the cursor.

I would have implemented it myself, but the only thing is that remapFailed needs setTimeout to function correctly (to cancel the remap if the time passed is greater than timeout), but I'm not sure how to implement that to modify vimState. It would be great if someone could implement this or point me to the right direction to solve the problem.

@berknam berknam mentioned this issue Jun 16, 2020
10 tasks
J-Fields pushed a commit that referenced this issue Aug 16, 2020
This is a pretty massive change; see pull request #4735 for full details

Most notably:
- Support for operator-pending mode, including remaps and a half-cursor decoration
- Correct handling of ambiguous remaps with timeout
- Correct handling of recursive special case when the RHS starts with the LHS
- Correct handling of multi-key remaps in insert mode
- Failed movements that occur partway through a remap stop & discard the rest of the remap
- Implement `unmap` and `mapclear` in .vimrc

Refs #463, refs #4908
Fixes #1261, fixes #1398, fixes #1579, fixes #1821, fixes #1835
Fixes #1870, fixes #1883, fixes #2041, fixes #2234, fixes #2466
Fixes #2897, fixes #2955, fixes #2975, fixes #3082, fixes #3086
Fixes #3171, fixes #3373, fixes #3413, fixes #3742, fixes #3768
Fixes #3988, fixes #4057, fixes #4118, fixes #4236, fixes #4353
Fixes #4464, fixes #4530, fixes #4532, fixes #4563, fixes #4674
Fixes #4756, fixes #4883, fixes #4928, fixes #4991, fixes #5016
Fixes #5057, fixes #5067, fixes #5084, fixes #5125
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 a pull request may close this issue.

3 participants