Skip to content

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

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

Emacs Compatibility Tracking Issue #4856

Closed
morgoth opened this issue Mar 30, 2023 · 37 comments
Closed

Emacs Compatibility Tracking Issue #4856

morgoth opened this issue Mar 30, 2023 · 37 comments
Labels
enhancement [core label] keymap / key binding Feedback for keyboard shortcuts, key mapping, etc

Comments

@morgoth
Copy link

morgoth commented Mar 30, 2023

Rather than a monolithic "implement emacs in Zed" enhancement request (which is inherently unactionable) this issue is a tracking issue for centralizing various Zed bug fixes and enhancements to better supporting emacs-like compatibility and operation in Zed.

Issues:

Merged PRs:

Comments such as "I need emacs mode to switch to Zed!" and the like are unwelcome here.
Please vote with 👍 below on this issue and the linked issues instead.

Editor note (@notpeter): Originally this issue was for an emacs keymap, a beta of which shipped in #19605

@JosephTLyons JosephTLyons transferred this issue from zed-industries/keymaps Jul 19, 2023
@JosephTLyons JosephTLyons added enhancement [core label] keymap / key binding Feedback for keyboard shortcuts, key mapping, etc labels Jul 19, 2023
@ozanmakes
Copy link
Contributor

An offical "Emacs mode" would be really nice. There is a couple of example user configurations over here: https://github.com/zed-industries/community/discussions/1653

At the moment the lack of a "mark" command is the biggest holdup. In Emacs, pressing Ctrl+SPC will toggle selection and let you use movement commands to select text without keeping Shift pressed. Any chance this could be added to Zed?

@JosephTLyons JosephTLyons transferred this issue from zed-industries/community Jan 24, 2024
@lvii

This comment was marked as spam.

@yonkeltron

This comment was marked as off-topic.

@lllleonnnn

This comment was marked as spam.

@opsnull

This comment was marked as off-topic.

@DidacBable

This comment was marked as off-topic.

@samin-UMG

This comment was marked as off-topic.

@djhunter67

This comment was marked as off-topic.

@akaihola

This comment was marked as resolved.

@notpeter notpeter changed the title Emacs keymap Emacs Compatibility Tracking Issue Dec 3, 2024
@notpeter
Copy link
Member

notpeter commented Dec 3, 2024

For those following this issue we've recently shipped two emacs-related improvements:

Please try out the Emacs (beta) keymap by triggering the welcome: toggle bas keymap selector:

image

It's very basic at this point, but give it a whirl, happy to consider PRs with improvements / refinements.

Rather than close this issue I've repurposed it as a tracking issue for additional Emacs-related enhancements and I've edited the issue description above to include links to other issues.

One other update, sadly, due to issues with international keyboards we also opted to revert terminal.option_as_meta to default to false again:

If you need emacs/readline style keybinds in your terminal which use meta / alt you will want to add this to your settings.json:

  "terminal": {
    "option_as_meta": true
  }

@jinschoi

This comment was marked as resolved.

@djhunter67

This comment was marked as off-topic.

@pbgc

This comment was marked as resolved.

@dmvianna

This comment was marked as resolved.

github-merge-queue bot pushed a commit that referenced this issue Jan 3, 2025
Various improvements to the emacs compatibility keybindings.

- See also: #4856

Release Notes:

- Improvements to emacs keybindings:
- Better support for running emacs inside Zed terminal (e.g. `ctrl-x
ctrl-c` will quit emacs in terminal not zed)
  - `alt-^` Join Lines
  - `ctrl-/` Undo
  - `alt-.` GotoDefinition and `alt-,` GoBack
  - `ctrl-x h` SelectAll
  - `alt-<` / `alt->` Goto End/Beginning of Buffer
  - `ctrl-g` as Menu::cancel
@rakete

This comment was marked as off-topic.

@notpeter

This comment was marked as resolved.

@dmvianna

This comment was marked as resolved.

@notpeter

This comment was marked as resolved.

@kzar
Copy link

kzar commented Jan 7, 2025

It might be worth adding "ctrl-o": "editor::Newline" for the editor context?

@notpeter
Copy link
Member

notpeter commented Jan 7, 2025

@kzar Emacs ctrl-o behavior is slightly different that editor::Newline, ctrl-o creates a newline below but does not move the cursor. I would prefer to add support for an optional parameter to the editor::NewlineBelow action so that we could bind "ctrl-o": ["editor::NewlineBelow", {"move_cursor": false}].

Similar to this:

"ctrl-/": ["editor::ToggleComments", { "advance_downwards": false }],

#[derive(PartialEq, Clone, Deserialize, Default)]
pub struct ToggleComments {
#[serde(default)]
pub advance_downwards: bool,
#[serde(default)]
pub ignore_indent: bool,
}

And then add a conditional inside the newline_below to optionally move the cursor.
pub fn newline_below(&mut self, _: &NewlineBelow, cx: &mut ViewContext<Self>) {

@kzar
Copy link

kzar commented Jan 7, 2025

Good point about not moving the cursor, but I don't think that editor::NewlineBelow is right because if you're at the start of a line C-o should move the current line down (or if you're in the middle of a line, it should move the part after your cursor down). Perhaps we could go with your approach to stop the cursor moving, but with editor:Newline?

@kzar

This comment was marked as resolved.

@dmvianna

This comment was marked as resolved.

@dmvianna
Copy link

dmvianna commented Jan 10, 2025

Oh, duh.

"context": "Editor:"

    "ctrl-y": "editor::Paste",
    "alt-w": "editor::Copy",
    "ctrl-w": "editor::Cut",
    "ctrl-?": "editor::Redo",
    "ctrl-shift-n": "editor::SelectDown",
    "ctrl-shift-p": "editor::SelectUp",
    "alt-shift-f": "editor::SelectToNextWordEnd",
    "alt-shift-b": "editor::SelectToPreviousWordStart",
    "ctrl-alt-shift-f": "editor::SelectToEndOfLine",
    "ctrl-alt-shift-b": "editor::SelectToBeginningOfLine"

This below also stops the Assistant from opening at every attempt to run editor::Redo.

"bindings"

  "alt-x": "app_menu::OpenApplicationMenu",
  "ctrl-?": null

And this prevents the cursor movement commands from opening new buffers when reaching beyond the first and last lines of a buffer.

"context": "Workspace:"

  "ctrl-n": null,
  "ctrl-p": null,

@dmvianna

This comment was marked as resolved.

@dmvianna
Copy link

Moving around the workspace panes is different from Emacs, which will just cycle through all available buffers and has no default concept of how they're positioned. Zed seems to organise them spatially, so instead of having just the default Emacs ctrl-x o (which I rebinded to alt-o as per Mastering Emacs in my own configuration), I had to use spatial bindings. I dislike it; I find Emacs's approach better, especially when I can use IBuffer to locate buffers by name using ctrl-x b.

In Emacs, I go to the pane I want the buffer to be and switch to it by name. In Zed (at least for now), I have to locate the pane by looking at the tabs, switching to the pane and then choosing the desired tab. Suboptimal.

Here's my current config:

"context": "Workspace"

  "ctrl-x o": "tab_switcher::Toggle",
  "alt-x b": ["workspace::ActivatePaneInDirection", "Left"],
  "alt-x f": ["workspace::ActivatePaneInDirection", "Right"],
  "alt-x p": ["workspace::ActivatePaneInDirection", "Up"],
  "alt-x n": ["workspace::ActivatePaneInDirection", "Down"]

@dmvianna
Copy link

dmvianna commented Jan 10, 2025

pop-global-mark in Emacs takes you back to the last mark, which in Zed it is the same as xref-go-back.
"context": "Pane"

  "alt-,": "pane::GoBack",  // xref-go-back
  "ctrl-x ctrl-space": "pane::GoBack",  // pop-global-mark
  "ctrl-u ctrl-space": "pane::GoForward"  // set-mark-command with negative prefix

Typing ctrl-x ctrl-space fast enough in Zed is tricky. How can I make Zed less impatient?

github-merge-queue bot pushed a commit that referenced this issue Jan 10, 2025
Originally reported here:
-
#4856 (comment)

macOS default vscode keymap already has this:

https://github.com/zed-industries/zed/blob/8d42456b8a7c547c6760b604c24d902bd2e12b8b/assets/keymaps/default-macos.json#L55
But it's disabled on Linux default vscode keymap as VSCode has this bind
instead:

https://github.com/zed-industries/zed/blob/8d42456b8a7c547c6760b604c24d902bd2e12b8b/assets/keymaps/default-linux.json#L407

Explicitly add it to both emacs keymaps so we can keep them identical
between macos/linux as long as possible.

Release Notes:

- emacs: Add support for `ctrl-t` transposing characters on Linux
@failable

This comment has been minimized.

@notpeter
Copy link
Member

notpeter commented Jan 21, 2025

At the moment the lack of a "mark" command is the biggest holdup. In Emacs, pressing Ctrl+SPC will toggle selection and let you use movement commands to select text without keeping Shift pressed. Any chance this could be added to Zed? -@ozanmakes comment link

Tomorrow (2025-01-21) this will be available Zed Preview 0.171.x (#23297 and #23428):

  • ctrl-space to enter mark/selection mode (editor::SetMark)
  • ctrl-x ctrl-x to swap selection ends (editor::SwapSelectionEnds aka exchange-point-and-mark)

Note multi-cursor is supported for both.

video demo
Screen.Recording.2025-01-21.at.18.17.59.mov

Thanks @ozanmakes for your work on #22904 which inspired me to get this over the line.

@kzar
Copy link

kzar commented Jan 22, 2025

Zed is getting more and more usable for me (as a long-time Emacs user) with these changes, thanks @notpeter!

I've not had the latest upgrade yet, but something I've noticed recently. If I press ctrl-k (editor: kill ring cut) to delete to the end of the line, then ctrl-y (kill ring yank) the text will be pasted back as expected. But if I then select some other text, press ctrl-w (editor: cut), then ctrl-y, the wrong text will be pasted (the text from the original king ring cut). In Emacs, I can paste back the text after using ctrl-w.

@michaelgruner
Copy link

Tomorrow (2025-01-21) this will be available Zed Preview 0.171.x (#23297 and #23428):

Thanks for this! Zed is incredibly fast. This was one of my stoppers to finally switch over.

@maximvl
Copy link

maximvl commented Jan 23, 2025

I'm trying this Emacs keymap, one thing I'm confused about is how it should handle conflicts with default Zed keybinds, eg C-p instead of going to previous line currently opens project file search and C-a selects all instead of going to beginning of a line.

@michaelgruner
Copy link

I'm trying this Emacs keymap, one thing I'm confused about is how it should handle conflicts with default Zed keybinds, eg C-p instead of going to previous line currently opens project file search and C-a selects all instead of going to beginning of a line.

You're probably missing the base_keymap in your settings.json?

"base_keymap": "Emacs"

@maximvl
Copy link

maximvl commented Jan 23, 2025

You're probably missing the base_keymap in your settings.json?

"base_keymap": "Emacs"

I do have that, and I have some Emacs keybinds working, like C-n, C-e, but only those which are not used by Zed default bindings

@michaelgruner
Copy link

I do have that, and I have some Emacs keybinds working, like C-n, C-e, but only those which are not used by Zed default bindings

ctrl-p works just fine for me, as well as all the other navigation keys, yank, paste, save, search, etc... Using the default base_keymap (no custom key binds). The only thing missing for me is setting a mark with ctrl-space.

I'm in Zed 0.170.1 4b2e556bf3ff1c6cf98804cf6c855dd7776a4d1 on Mac. Here's my barebones ~/config/zed/settings.json:

// Zed settings
//
// For information on how to configure Zed, see the Zed
// documentation: https://zed.dev/docs/configuring-zed
//
// To see all of Zed's default settings without changing your
// custom settings, run the `open default settings` command
// from the command palette or from `Zed` application menu.
{
  "assistant": {
    "default_model": {
      "provider": "copilot_chat",
      "model": "gpt-4o"
    },
    "version": "2"
  },
  "vim_mode": false,
  "theme": "Solarized Dark",
  "ui_font_size": 16,
  "buffer_font_size": 16,
  "autosave": {
    "after_delay": {
      "milliseconds": 10000
    }
  },
  "hour_format": "hour24",
  "tab_size": 2,
  "base_keymap": "Emacs",
  "terminal": {
    "option_as_meta": true
  }
}

And my ~/.config/zed/keymap.json is empty.

@failable
Copy link

In Emacs, one can bind the same keyboard shortcut to different commands in different programming language buffers. It would be great if Zed had similar functionality.

For example, using the same shortcut to execute different run commands / tasks in Python and Rust files, e.g. python3 $ZED_FILE and cargo run respectively.

@dmvianna
Copy link

dmvianna commented Jan 24, 2025 via email

@zed-industries zed-industries locked and limited conversation to collaborators Jan 24, 2025
@notpeter notpeter converted this issue into discussion #23629 Jan 24, 2025

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Labels
enhancement [core label] keymap / key binding Feedback for keyboard shortcuts, key mapping, etc
Projects
None yet
Development

No branches or pull requests