zed-industries / zed

Code at the speed of thought – Zed is a high-performance, multiplayer code editor from the creators of Atom and Tree-sitter.
https://zed.dev
Other
50.31k stars 3.1k forks source link

Cannot ubind/bind `ctrl-'` or `ctrl-t` properly #18796

Open 1925381584 opened 1 month ago

1925381584 commented 1 month ago

Check for existing issues

Describe the bug / provide steps to reproduce it

image Like in the picture, the shortcut key ctrl-alt-down is effective, but ctrl-, can't

Environment

Zed: v0.156.0 (Zed Dev 57ad5778fad8cbdeada7815ca9c58fec63db90d8) OS: Windows 10.0.19045 Memory: 15.7 GiB Architecture: x86_64 GPU: Intel(R) Iris(R) Xe Graphics || Intel Corporation || Intel driver

If applicable, add mockups / screenshots to help explain present your vision of the feature

No response

If applicable, attach your Zed.log file to this issue.

Zed.log


CharlesChen0823 commented 1 month ago

you should paste your binding context here

1925381584 commented 1 month ago

image

notpeter commented 1 month ago

Wrong issue @1925381584 -- that's the screenshot from https://github.com/zed-industries/zed/issues/18798.

As I stated over there, please paste your entire keymap json, I believe you have things over-indented.

1925381584 commented 1 month ago

keymap.json

@notpeter @CharlesChen0823 here is my keymap.json thanks for help

notpeter commented 1 month ago

I can reproduce on MacOS. I think #18798 is a near identical issue so I'm merging that here.

Steps to reproduce:

  1. rebind ctrl-' to toggle the bottom dock (workspace)
  2. rebind ctrl-t to new Assistant (AssistantPanel).

Here is a minimal reproduction keymap. It unbinds all the places that these two keys are bound in the default keymap (for macos and linux/windows just to be comprehensive) and binds them where they want to be.

keymap.json
[
  {
    "context": "Editor",
    "bindings": {
      "ctrl-t": null, // default-macos.json
      "ctrl-'": null // default-linux.json
    }
  },
  {
    "context": "vim_mode == insert",
    "bindings": {
      "ctrl-t": null // vim.json
    }
  },
  {
    "context": "Workspace",
    "bindings": {
      "ctrl-'": "workspace::ToggleBottomDock",
      "ctrl-t": null // default-linux.json
    }
  },
  {
    "context": "AssistantPanel",
    "bindings": {
      "ctrl-t": "assistant::NewContext"
    }
  }
]

If you change either of these keys to something else (e.g. cmd-t or ctrl-alt-t) then everything works as expected. I'm stumped.

CharlesChen0823 commented 1 month ago

I found, if disable keybindings in context Editor, then every keybindings will not work in almostly, because Editor is the first element for dispatch actions.

update: I found the key problem, will try fixed.

ConradIrwin commented 3 weeks ago

I think this is "working as expected", but it does indicate that our current approach is a bit confusing.

Currently key-binding files are read in tree-order (from bottom to top) and so we consider bindings on Editor, then bindings on AssistantPanel, then bindings on Workspace. Within each layer, ordering is used to break ties, so that later bindings override earlier bindings. As the user key file is loaded after the builtin key file, user bindings at a given level take precedence over builtin bindings. That said, builtin bindings at the Editor level still take precedence over user bindings at the Workspace level.

There is no difference in handling between null and any other action. If the null is the highest precedence at the given level, we stop traversing up the tree. This means that if you have null at the Editor level, a binding at the Workspace level (or AssistantPanel) will not be reached.

We could consider changing it, but it works this way because the primary reasons people want to use null bindings are: 1) to disable option-t so that they can type †, or 2) to disable multi key bindings that start with the sequence (as vim does on Linux). Neither of these use-cases would work well if we didn't stop the search.

For now, the easiest way to work around this is to define your actions with no context. When that happens they always match at the lowest level in the tree, and so take precedence over everything:

[{
  // "context": "" omitted
  "bindings": {
      "ctrl-'": "workspace::ToggleBottomDock",
  }
}]

In this specific example, you can also be more specific if you want the binding to work in the Editor inside the assistant panel, but no-where else:

[{
  "context": "AssistantPanel > Editor",
  "bindings": {
      "ctrl-t": "assistant::NewContext"
  }
}]

I do know that one thing that makes this hard right now is that there is no way to discover what contexts are active without reading a lot of code.