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

Add emacs keybindings for mark emulation #22904

Open
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

ozanmakes
Copy link
Contributor

@ozanmakes ozanmakes commented Jan 9, 2025

These keybindings extend the already selected text. This allows closer emacs emulation where subsequent movement commands extend / shrink the current selection instead of dismissing it.

This is a follow up on

Release Notes:

  • Added emacs movement keybindings that extend/shrink the current selection

@cla-bot cla-bot bot added the cla-signed The user has signed the Contributor License Agreement label Jan 9, 2025
These keybindings extend the already selected text. This allows closer
emacs emulation where subsequent movement commands extend / shrink the
current selection instead of dismissing it.
@ozanmakes ozanmakes force-pushed the emacs-mark-movement branch from e8e46f1 to 4e6c580 Compare January 10, 2025 10:42
@ozanmakes
Copy link
Contributor Author

I've updated this PR to

  • Add set-mark-command emulation (ctrl-space + movement)
  • Apply the same changes to macos/emacs.json

@ozanmakes ozanmakes mentioned this pull request Jan 10, 2025
1 task
@notpeter notpeter self-assigned this Jan 10, 2025
@notpeter
Copy link
Member

I love this. Particularly the elegance of "mark mode" being activate whenever there is a selection. It's obviously not perfect (you have to rapidly press a navigation key after ctrl-space) but it's a lot of functionality for very little code.

I've added ctrl-space + native navigation keys (left,right,home,end,pageup,pagedown,alt-left,alt-right) to further match the behavior of emacs.

Currently ctrl-space in macos/linux is bound to editor::ShowCompletions which will now be slightly delayed. I wonder if there's an emacs equivalent we should consider binding to that in the future to support manually triggering the completions menu without delay.

@notpeter
Copy link
Member

I've tried to test this in various Editor context other than regular buffers (command palette, assistant panel, project panel) and it works pretty well.

  • Renaming a file in the project panel is awkward (selects the entire filename by default, so it's difficult to deselect without cancelling the rename). Pressing right does not deselect and place you at the end of the filename.
  • Similar issue when spawning the buffer search / project search since it selects your query string by default.

In a buffer I think these behaviors are fine but I think in the single line editors (search, modals, etC) I think this behavior is a little too jank to ship.

How would you feel about changing the keybind contexts to:

    "context": "Editor && (mode == full) && selection",
    "context": "Editor && (mode == full) && !selection",

Would it be an acceptable compromise to add support for emacs style "mark mode" but only in Full Editor buffers, not in line editors?

I also noticed a difference between this an emacs behavior:
In a buffer, hold shift and press right a few times to mark some text and release shift.

  • In emacs, adding to the selection requires holding shift again; pressing right without shift cancels the selection.
  • In Zed, pressing right without shift expands the selection.

Alternatively we could conceivably split the arrow/home/end binds I added to only be used in mode == full while the supporting the emacs style navigations everywhere.

Thoughts?

@ozanmakes
Copy link
Contributor Author

I love this. Particularly the elegance of "mark mode" being activate whenever there is a selection. It's obviously not perfect (you have to rapidly press a navigation key after ctrl-space) but it's a lot of functionality for very little code.

Thank you!

I've added ctrl-space + native navigation keys (left,right,home,end,pageup,pagedown,alt-left,alt-right) to further match the behavior of emacs.

This is great, thanks for adding these.

Currently ctrl-space in macos/linux is bound to editor::ShowCompletions which will now be slightly delayed. I wonder if there's an emacs equivalent we should consider binding to that in the future to support manually triggering the completions menu without delay.

Alt-/ would be a natural keybinding for this as it is used in Emacs for various text completion mechanisms (by default dabbrev-expand).

In Zed, pressing right without shift expands the selection.

You're right, in Emacs selecting text with Shift + arrow keys does not set the mark. But I can't think of a way to replicate this behavior. For users who use Emacs keymap but prefer selecting text with classic Shift + arrow keys this could be a regression and a bit annoying.

Would it be an acceptable compromise to add support for emacs style "mark mode" but only in Full Editor buffers, not in line editors?

I think this is a good compromise. These keybindings are most valuable in file and assistant buffers, and we can omit line editors to keep this PR simple and not introduce counter-intuitive edge cases. I will update the context in this PR accordingly.

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