Skip to content

Conversation

@0xGlace
Copy link

@0xGlace 0xGlace commented Oct 27, 2025

This PR enables using Vim operators and text objects via keybindings without entering full modal editing mode. When enabled, Vim is activated but doesn't observe keystrokes, change cursor shape and keeps editor input enabled.

This is most useful when one wants to slowly transition into full modal editing, or just needs some of the functionality and doesn't want to keep switching between modes.

With this, Vim actions can be used in any normal keybind:

{
  "context": "Editor",
  "bindings": {
    "cmd-shift-g": "vim::HelixGotoLastModification",
    "cmd-'": [
      "action::Sequence",
      [
        "vim::SwitchToVisualMode",
        ["vim::PushObject", { "around": false }],
        "vim::AnyQuotes"
      ]
    ]
  }
}

Added a description with a few examples to the Vim mode documentation.

Added toggle option for "Always-on Modal Actions" in Keymap settings:

zed-passive-modal-actions

This feature has a few accompanying tests:

  • test_passive_mode_typing_works
    Ensure editor input works in passive mode.
  • test_passive_mode_delete_inside_quotes
    Test a keybind for deleting inside of quotes.
  • test_passive_mode_selection_preserving
    Ensure the selection is preserved after the action has been executed.
  • test_passive_mode_goto_last_modification
    Test HelixGotoLastModification working in passive mode to ensure Vim is getting editor updates.

Original feature idea and motive from Adam Wathan's post.
This implementation is basically the same thing mentioned by [at]ConradIrwin under the same post.

Release Notes:

  • Add always-on modal actions to use vim actions in keybindings

@cla-bot cla-bot bot added the cla-signed The user has signed the Contributor License Agreement label Oct 27, 2025
@ConradIrwin
Copy link
Member

Nice! Thanks for this.

Do we need passive mode, or can we just enable vim mode always without loading the keymap?

There are a few actions that we override (e.g.

workspace.register_action(|workspace, _: &SearchSubmit, window, cx| {
) that we should add a check for whether vim mode is enabled, but otherwise I hope it should be relatively safe.

Some vim actions require an additional argument that is currently required to be passed by a keystroke (like dt<space> to delete until the next space) and so I think we should leave that machinery in place in this mode.

Happy to pair with you on this if you want: https://cal.com/conradirwin/pairing

…he vim mode

setting now toggles whether its keymap is loaded and the behavior of Vim mode.
@0xGlace
Copy link
Author

0xGlace commented Oct 28, 2025

I removed the passive mode and went after the keymap itself, with the last changes, Vim mode is always on and the setting only toggles its keymap and changes some behavior similar to the previous passive mode.

There are a few actions that we override…
For those actions like you've said there's now a simple check, if Vim mode isn't enable, they dispatch the normal action.

Some vim actions require an additional argument that is currently required to be passed by a keystroke (like dt to delete until the next space) and so I think we should leave that machinery in place in this mode.

That's now handled:

https://github.com/0xGlace/zed/blob/858a78b726478bfb96defa2a3c296fdb53a5c640/crates/vim/src/vim.rs#L1307-L1314

I also changed the tests, one of them tests for this exact case.

I think this is much better than the previous approach, that one also had an issue where the mode indicator didn't update properly and I spent most of the time trying to figure out, not having experience with GPUI also made it more tricky but this removes the need for things like that.

Happy to pair with you on this if you want: https://cal.com/conradirwin/pairing

Thank you! and I wish I could but I'm not in a place where I can at the moment

@0xGlace
Copy link
Author

0xGlace commented Oct 28, 2025

I just realized another thing new approach allows for I think is having the conditional keybind context which passive mode didn't allow for

@0xGlace
Copy link
Author

0xGlace commented Oct 30, 2025

I added a keybind context vim_mode_off and add it to the Vim mode docs, though the wording and the name of it might need changing if it doesn't fit.
Should I edit the original PR message to reflect the current implementation?

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