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

vim: Allow left/right (h/l) motions to change lines + up/down (k/j) to move the cursor to the start/end #25663

Closed
wants to merge 1 commit into from

Conversation

asqarslanov
Copy link

@asqarslanov asqarslanov commented Feb 26, 2025

Closes #25510.

This pull request adds two config options:

  • "vim.boundary_movements.left_right" ("off" | "on")
  • "vim.boundary_movements.up_down" ("off" | "on")

They allow to toggle “wrapping” of the left/right and up/down motions in Vim mode (details in the discussion).

Potentially, this feature may be exapnded to only allow wrappings for the arrow/letter keys. That’s the reason why I chose to use strings ("off", "on") instead of booleans.

The changes are not breaking, so users aren’t required to modify their configuration files.

This is my first real open-source PR, so the implementation may not be the cleanest, but it works. I’ll be glad to hear feedback on how to improve code quality.

Also, I’m not a native English speaker, so the naming of the config options (and variables in the code) may not be accurate, I’m open to suggestions.

Copy link

cla-bot bot commented Feb 26, 2025

We require contributors to sign our Contributor License Agreement, and we don't have @asqarslanov on file. You can sign our CLA at https://zed.dev/cla. Once you've signed, post a comment here that says '@cla-bot check'.

@asqarslanov
Copy link
Author

@cla-bot check

@cla-bot cla-bot bot added the cla-signed The user has signed the Contributor License Agreement label Feb 26, 2025
Copy link

cla-bot bot commented Feb 26, 2025

The cla-bot has been summoned, and re-checked this pull request!

@maxdeviant maxdeviant changed the title Vim: allow left/right (h/l) motions to change lines + up/down (k/j) to move the cursor to the start/end vim: Allow left/right (h/l) motions to change lines + up/down (k/j) to move the cursor to the start/end Feb 26, 2025
@asqarslanov
Copy link
Author

asqarslanov commented Feb 26, 2025

I discovered a small bug in the implementation.

When the parameter wrap is passed as true to the function vim::motion::up_down_buffer_rows (simple up/down movements with j/k), the exepected behavior is that the cursor will either go the start of the line (if at the top line) or to the end (if at the bottom line). It does work like this when times is passed as 1 (or -1). However, if the cursor initially was at some other line except the top or the bottom and times is greater than 1 (or less than -1), the wrapping does not happen.

While not a huge problem, this makes the implementation incomplete. I’ll try to tackle down this problem, but, I guess, I will also need some help since the up_down_buffer_rows function seems very complex to me.

@ConradIrwin
Copy link
Member

@asqarslanov Thanks for this!

For h and l, I think the right fix is to instruct users to rebind these keys to the same action as space (vim::Space) and backspace (vim::Backspace) which already behave how you want. This lets us avoid adding more configuration options and code.

For j and k, I'm not sure we want to do this. As you point out, vim doesn't have this ability; and I'm not aware of any commonly used vim plugins that provide it either. Are you using a vim implementation that supports this, and if so, why do you enable this behavior?

@asqarslanov
Copy link
Author

@ConradIrwin

Thank you for the reply!

Setting h and l to vim::Backspace and vim::Space is pretty clever, I didn’t actually think of it (even though I effectively copied the implementations 😜). To me, having explicit config options feels a bit nicer and more intuitive, but I see how this can seem redundant.

As for j and k, I’m not aware of any modal editors that can do that. Though, why can’t Zed be the first to implement it? :)

Having been a Vim user for more than two years, I still find myself pressing these keys at the top/bottom line to move the cursor—it’s simply the first thing that comes to my mind—and it’s just annoying when the editor doesn’t do the thing. For example, I may try to go to the beginning of a file by first pressing gg and then, instead of changing my right hand’s position, I would just be able to press k. A small quality-of-life improvement.

@ConradIrwin
Copy link
Member

Makes sense.

I think it'd be better to teach your fingers shift-g to go to end of file; it's not quite as ergonomic as k, but it is what everyone else does :D.

Want to send a PR to the docs page for the wrapping behavior of h/l ?

@asqarslanov
Copy link
Author

asqarslanov commented Feb 26, 2025

Unfortunate that the PR was aborted, but I understand this is done to not make the editor a mixture of everyone’s whims. I hope, the plugin system will be powerful enough to implement this as an extension.

About the docs, yes, I think, I could do that. To make things more intuitive, what do you think about renaming (aliasing) the Backspace and Space actions to vim::WrappingLeft and vim::WrappingRight? Isn’t it too late for this now?

@ConradIrwin
Copy link
Member

Sounds fine to me (you can use the action_with_deprecated_alias functionality

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cla-signed The user has signed the Contributor License Agreement
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants