按键绑定

Zed 拥有高度可定制的快捷键绑定系统——您可以调整所有设置,使其完全符合您的手指习惯!

预定义键映射

如果您习惯了特定编辑器的默认设置,可以通过设置窗口(cmd-,|ctrl-,)或直接通过您的 settings.json 文件(cmd-alt-,|ctrl-alt-,)更改您的 base_keymap。我们目前支持

  • VS Code (默认)
  • Atom
  • Emacs (Beta)
  • JetBrains
  • Sublime Text
  • TextMate
  • Cursor
  • 无 (禁用所有快捷键绑定)

此设置也可以通过命令面板中的 zed: toggle base keymap selector 操作进行更改。

您还可以启用 vim_modehelix_mode,这会添加模态绑定。有关更多信息,请参阅 Vim 模式Helix 模式的文档。

键映射编辑器

您可以通过 cmd-k cmd-s|ctrl-k ctrl-s 操作或从命令面板运行 zed: open keymap 操作来访问键映射编辑器。您可以使用命令面板左下角的“更改快捷键绑定”或“添加快捷键绑定”按钮轻松地为某个操作添加或更改快捷键绑定。

在那里,您可以看到 Zed 中所有现有操作以及默认设置的关联快捷键绑定。

您也可以直接在那里自定义它们,可以通过将鼠标悬停在特定操作上时出现的铅笔图标,双击操作行,或按 enter 键。

您在键映射编辑器上所做的任何更改也会反映在 keymap.json 文件中。

用户键映射

键映射文件在每个平台上的存储位置如下:

  • macOS/Linux: ~/.config/zed/keymap.json
  • Windows: ~\AppData\Roaming\Zed/keymap.json

您可以通过命令面板中的 zed: open keymap file 操作打开键映射文件。

此文件包含一个带有 "bindings" 对象的 JSON 数组。如果未设置 "context",则绑定始终处于活动状态。如果已设置,则绑定仅在上下文匹配时处于活动状态。

在每个绑定部分中,键序列映射到一个操作。如果检测到冲突,将按下述方式解决。

如果您使用的是非 QWERTY、拉丁字符键盘,您可能需要将 use_key_equivalents 设置为 true。有关更多信息,请参阅非 QWERTY 键盘

例如

[
  {
    "bindings": {
      "ctrl-right": "editor::SelectLargerSyntaxNode",
      "ctrl-left": "editor::SelectSmallerSyntaxNode"
    }
  },
  {
    "context": "ProjectPanel && not_editing",
    "bindings": {
      "o": "project_panel::Open"
    }
  }
]

您可以在默认键映射文件中查看 Zed 在每个平台上的所有默认绑定

如果您想调试自定义键映射问题,可以使用命令面板中的 dev: Open Key Context View。如果您遇到应该有效但无效的问题,请提交一个 issue

快捷键绑定语法

Zed 不仅能够匹配单个按键,还能匹配按顺序输入的一系列按键。"bindings" 映射中的每个键都是一个用空格分隔的按键序列。

每个按键都是一个修饰符序列,后跟一个键。修饰符包括

  • ctrl- Control 键
  • cmd-, win-super- 用于平台修饰符(macOS 上的 Command 键,Windows 上的 Windows 键,以及 Linux 上的 Super 键)。
  • alt- 用于 alt 键(macOS 上的 option 键)
  • shift- Shift 键
  • fn- Function 键
  • secondary- 当 Zed 在 macOS 上运行时等同于 cmd,当在 Windows 和 Linux 上运行时等同于 ctrl

键可以是键盘生成的任何单个 Unicode 码点(例如 a0£ç),或任何命名键(tabf1shiftcmd)。如果您使用的是非拉丁语布局(例如西里尔语),您可以绑定到西里尔字符或按住 cmd 时该键生成的拉丁字符。

几个例子

 "bindings": {
   "cmd-k cmd-s": "zed::OpenKeymap", // matches ⌘-k then ⌘-s
   "space e": "editor::Complete", // type space then e
   "ç": "editor::Complete", // matches ⌥-c
   "shift shift": "file_finder::Toggle", // matches pressing and releasing shift twice
 }

shift- 修饰符只能与字母组合使用以指示大写版本。例如,shift-g 匹配输入 G。尽管在许多键盘上 shift 键用于输入标点符号,例如 (,但该按键不被视为已修改,因此 shift-( 不匹配。

在许多布局上,alt- 修饰符可用于生成不同的键。例如,在 macOS 美国键盘上,组合键 alt-c 会输入 ç。您可以在键映射文件中匹配其中任何一个,但按照惯例,Zed 将此组合键拼写为 alt-c

可以单独匹配按下一个修饰键。例如,shift shift 可以用于实现 JetBrains 的“随处搜索”快捷方式。在这种情况下,绑定在按键释放时而不是在按键按下时发生。

上下文

如果绑定组具有 "context" 键,它将与 Zed 中当前活动的上下文进行匹配。

Zed 的上下文构成一棵树,根是 Workspace。工作区包含窗格和面板,窗格包含编辑器等。查看给定时刻哪些上下文处于活动状态的最简单方法是键上下文视图,您可以通过命令面板中的 dev: open key context view 命令访问该视图。

例如

# in an editor, it might look like this:
Workspace os=macos keyboard_layout=com.apple.keylayout.QWERTY
  Pane
    Editor mode=full extension=md vim_mode=insert

# in the project panel
Workspace os=macos
  Dock
    ProjectPanel not_editing

上下文表达式可以包含以下语法

  • X && Y, X || Y 用于两个条件的与/或
  • !X 用于检查条件是否为假
  • (X) 用于分组
  • X > Y 用于匹配树中的祖先匹配 X 且此层匹配 Y 的情况。

例如

  • "context": "Editor" - 匹配任何编辑器(包括内联输入)
  • "context": "Editor && mode == full" - 匹配用于编辑代码的主编辑器
  • "context": "!Editor && !Terminal" - 匹配除了编辑器或终端聚焦之外的任何位置
  • "context": "os == macos > Editor" - 匹配 macOS 上的任何编辑器。

值得注意的是,属性仅在其定义的节点上可用。这意味着,例如,如果您只想在调试器在 vim 普通模式下停止时启用快捷键绑定,您需要执行 debugger_stopped > vim_mode == normal

注意:在 Zed v0.197.x 之前,! 运算符一次只查看一个节点,> 表示“父级”而不是“祖先”。这意味着 !Editor 会匹配上下文 Workspace > Pane > Editor,因为(令人困惑的是)Pane 匹配 !Editor,并且 os == macos > Editor 不匹配上下文 Workspace > Pane > Editor,因为存在中间的 Pane 节点。

如果您正在使用 Vim 模式,我们有关于 vim 模式如何影响上下文的信息。Helix 模式建立在 Vim 模式之上,并使用相同的上下文。

操作

Zed 的几乎所有功能都作为操作公开。尽管没有明确记录的列表,但您可以通过在命令面板中搜索,查看 macOSWindowsLinux 的默认键映射,或在您的键映射文件中使用 Zed 的自动完成功能来找到它们。

大多数操作不需要任何参数,因此您可以将它们绑定为字符串:"ctrl-a": "language_selector::Toggle"。有些操作需要单个参数,并且必须绑定为数组:"cmd-1": ["workspace::ActivatePane", 0]。有些操作需要多个参数,并绑定为字符串和对象的数组:"ctrl-a": ["pane::DeploySearch", { "replace_enabled": true }]

优先级

当多个快捷键绑定具有相同的击键并且同时处于活动状态时,优先级以两种方式解决

  • 在上下文树中匹配较低节点的绑定获胜。这意味着,如果您有一个上下文为 Editor 的绑定,它将优先于上下文为 Workspace 的绑定。没有上下文的绑定在树中最低级别匹配。
  • 如果在树的同一级别有多个匹配的绑定,则后定义的绑定优先。由于用户快捷键绑定在系统快捷键绑定之后加载,这允许用户绑定优先于内置快捷键绑定。

另一种冲突是当您有两个绑定时,其中一个绑定是另一个绑定的前缀。例如,如果您有 "ctrl-w":"editor::DeleteToNextWordEnd""ctrl-w left":"editor::DeleteToEndOfLine"

当这种情况发生,并且两个绑定在当前上下文都处于活动状态时,Zed 会在您输入 ctrl-w 后等待 1 秒,以查看您是否要输入 left。如果您不输入任何内容,或者输入不同的键,则会触发 DeleteToNextWordEnd。如果您输入 left,则会触发 DeleteToEndOfLine

非 QWERTY 键盘

Zed 对非 QWERTY 键盘的支持仍在进行中。

如果您的键盘可以输入完整的 ASCII 范围(DVORAK、COLEMAK 等),那么快捷键应该按预期工作。

否则,请继续阅读...

macOS

在西里尔语、希伯来语、亚美尼亚语和其他大部分非 ASCII 键盘上,当按住 cmd 时,macOS 会自动将按键映射到 ASCII 范围。Zed 更进一步,它始终可以根据 ASCII 布局或实际布局匹配按键,无论修饰符和 use_key_equivalents 设置如何。例如,在泰语中,按下 ctrl-ๆ 将匹配与 ctrl-qctrl-ๆ 关联的绑定。

在支持扩展拉丁字母(法语 AZERTY、德语 QWERTZ 等)的键盘上,通常无法在不使用 option 的情况下输入整个 ASCII 范围。这引入了一个歧义:option-2 会生成 @。为了确保这些键盘上仍然可以输入所有内置键盘快捷键,我们移动了快捷键绑定。例如,QWERTY 键盘上绑定到 @ 的快捷键在西班牙语布局上会移动到 "。此映射基于 macOS 系统默认设置,可以通过从命令面板运行 dev: open key context view 来查看。

如果您在个人键映射中定义快捷键,可以通过在键映射中将 use_key_equivalents 设置为 true 来选择使用键等效映射

[
  {
    "use_key_equivalents": true,
    "bindings": {
      "ctrl->": "editor::Indent" // parsed as ctrl-: when a German QWERTZ keyboard is active
    }
  }
]

Linux

自 v0.196.0 起,在 Linux 上,如果您键入的键不产生 ASCII 字符,那么我们使用 QWERTY 布局等效键作为键盘快捷键。这意味着许多快捷键可以在许多布局上键入。

我们尚未移动快捷键以确保所有内置快捷键都可以在每种布局上键入,因此,如果有些 ASCII 字符无法键入,并且您的键盘布局在与所需键入的字符相同的键上具有不同的 ASCII 字符,您可能需要添加自定义快捷键绑定才能使其工作。我们确实打算在某个时候解决此问题,并且非常感谢您的帮助!

提示和技巧

禁用绑定

如果您希望给定绑定在给定上下文中不执行任何操作,则可以将 null 用作操作。这在您不小心触发表单且想禁用它时,或者您想键入该序列会键入的字符时,或者您想禁用以该键开头的多键绑定时非常有用。

[
  {
    "context": "Workspace",
    "bindings": {
      "cmd-r": null // cmd-r will do nothing when the Workspace context is active
    }
  }
]

null 绑定遵循与普通操作相同的优先级规则,因此它也会禁用树中更上方匹配的所有绑定。如果您希望树中更上方的绑定优先于较低的绑定,则需要在所需的上下文中将其重新绑定到所需的操作。

这对于防止 Zed 在您指定的操作是条件且会传播时回退到默认快捷键绑定很有用。例如,buffer_search::DeployReplace 仅在搜索栏不可见时触发。如果搜索栏可见,它将传播并触发为该快捷键绑定设置的默认操作,例如打开右侧停靠栏。为了防止这种情况发生

[
  {
    "context": "Workspace",
    "bindings": {
      "cmd-r": null // cmd-r will do nothing when the search bar is in view
    }
  },
  {
    "context": "Workspace",
    "bindings": {
      "cmd-r": "buffer_search::DeployReplace" // cmd-r will deploy replace when the search bar is not in view
    }
  }
]

重新映射键

一个常见的请求是能够将单个击键映射到序列。您可以使用 workspace::SendKeystrokes 操作来完成此操作。

[
  {
    "bindings": {
      // Move down four times
      "alt-down": ["workspace::SendKeystrokes", "down down down down"],
      // Expand the selection (editor::SelectLargerSyntaxNode);
      // copy to the clipboard; and then undo the selection expansion.
      "cmd-alt-c": [
        "workspace::SendKeystrokes",
        "ctrl-shift-right ctrl-shift-right ctrl-shift-right cmd-c ctrl-shift-left ctrl-shift-left ctrl-shift-left"
      ]
    }
  },
  {
    "context": "Editor && vim_mode == insert",
    "bindings": {
      "j k": ["workspace::SendKeystrokes", "escape"]
    }
  }
]

这有一些限制,特别是

  • 在所有快捷键绑定都已分派之后,才会发生任何异步操作。例如,这意味着虽然您可以使用绑定打开文件(如 cmd-alt-r 示例所示),但您不能发送后续击键并希望它们被新视图解释。
  • 其他异步操作的例子包括:打开命令面板、与语言服务器通信、更改缓冲区语言、任何需要网络连接的操作。
  • 一次模拟的按键数量限制为 100 个。

SendKeystrokes 的参数是空格分隔的击键列表(使用与上述相同的语法)。由于击键的解析方式,任何未被识别为击键的段都将原样发送到当前聚焦的输入字段。

如果 SendKeystrokes 的参数包含用于触发它的绑定,它将使用该绑定的下一个最高优先级定义。这允许您扩展快捷键绑定的默认行为。

将按键转发到终端

如果您使用的是 Linux 或 Windows,您可能会发现自己希望将按键组合转发到内置终端,而不是由 Zed 处理。

例如,在 Linux 上,ctrl-n 会在 Zed 中创建一个新标签页。如果您希望在内置终端聚焦时将 ctrl-n 发送到内置终端,请将以下内容添加到您的键映射中

{
  "context": "Terminal",
  "bindings": {
    "ctrl-n": ["terminal::SendKeystroke", "ctrl-n"]
  }
}

任务快捷键绑定

您还可以将键绑定到启动在 tasks.json 中定义的 Zed 任务。有关更多信息,请参阅任务文档