第51章 Zed 编辑器 Vim 模式详解
Zed 内置了 Vim 模拟层。本页面介绍如何启用和禁用 vim 模式、键位绑定、Zed 特有的功能以及配置选项。
Zed vim 模式的设计理念
vim 模式在合理之处复刻了 Vim 的移动(motions)和命令行为,而在 Zed 方案更优之处则采用 Zed 专属功能。目标是提供开箱即用的熟悉体验,无需额外配置。
这包括对语义导航、多光标的支持,以及其他通常由插件提供的功能,例如包围文本(surrounding text)。
因此,Zed 的 vim 模式并非与 Vim 一比一复刻,而是将 Vim 的模态设计与 Zed 的现代特性相结合,带来更流畅的体验。该模式支持配置,你可以添加自定义键位绑定或覆盖默认设置。
核心差异
vim 模式中有四类功能使用了 Zed 的核心能力,导致部分行为存在差异:
- 移动(Motions):vim 模式利用 Zed 的语义解析,针对不同语言调整移动行为。例如,在 Rust 中,使用
%跳到匹配括号时支持管道符|;在 JavaScript 中,w将$视为单词字符。 - 视觉块选择(Visual block selections):vim 模式借助 Zed 的多光标功能模拟视觉块选择,使块选择更加灵活。例如,在块选择后插入的文本会实时更新到每一行,且可随时增删光标。
- 宏(Macros):vim 模式使用 Zed 的录制系统来处理 vim 宏。因此,可以捕获并回放更复杂的操作,比如自动补全。
- 查找与替换(Search and replace):vim 模式使用 Zed 的搜索系统,因此正则表达式语法与 Vim 略有不同。查看正则表达式差异部分了解详情。
注意:Zed vim 模式的基础功能已能覆盖许多使用场景,且我们正持续优化。如果发现工作流中缺失的功能,请在 GitHub 上提交 issue。
启用与禁用 vim 模式
首次打开 Zed 时,欢迎页面上会有一个复选框,允许你启用 vim 模式。
如果你之前错过了这个:随时都可以打开命令面板,使用 workspace 命令 {#action workspace::ToggleVimMode} 来开启或关闭 vim mode。
注意:这个命令会切换用户设置中的以下属性:
{ "vim_mode": true }
Zed 特有功能
Zed 构建在现代技术基础之上,利用 Tree-sitter 和 language server 理解你正在编辑的文件内容,并且原生支持多光标。
Vim mode 提供了一些 Zed 核心快捷键,帮你充分发挥 Zed 的特色功能。
Language server
以下命令借助 language server 帮你导航和重构代码。
| 命令 | 默认快捷键 |
|---|---|
| 跳转到定义 | g d |
| 跳转到声明 | g D |
| 跳转到类型定义 | g y |
| 跳转到实现 | g I |
| 重命名(修改定义) | c d |
| 跳转到当前单词的所有引用 | g A |
| 在当前文件中查找符号 | g s |
| 在整个项目中查找符号 | g S |
| 跳转到下一个诊断 | g ] 或 ] d |
| 跳转到上一个诊断 | g [ 或 [ d |
| 显示行内错误(悬停提示) | g h |
| 打开 code actions 菜单 | g . |
Git
| 命令 | 默认快捷键 |
|---|---|
| 跳转到下一个 git 变更 | ] c |
| 跳转到上一个 git 变更 | [ c |
| 展开 diff hunk | d o |
| 切换暂存状态 | d O |
| 暂存并跳到下一处(diff 视图中) | d u |
| 取消暂存并跳到下一处(diff 视图中) | d U |
| 还原变更 | d p |
Tree-sitter
Tree-sitter 是 Zed 用来解析代码结构的底层引擎。Zed 提供了一系列移动命令来改变光标位置,并支持将文本对象作为操作的目标。
| 命令 | 默认快捷键 |
|---|---|
| 跳转至下一个/上一个方法 | ] m / [ m |
| 跳转至下一个/上一个方法末尾 | ] M / [ M |
| 跳转至下一个/上一个代码块 | ] ] / [ [ |
| 跳转至下一个/上一个代码块末尾 | ] [ / [ ] |
| 跳转至下一个/上一个注释 | ] /、] * / [ /、[ * |
| 选中更大的语法节点 | [ x |
| 选中更小的语法节点 | ] x |
| 文本对象 | 默认快捷键 |
|---|---|
| 包含类、定义等在内的范围 | a c |
| 类、定义等内部内容 | i c |
| 包含函数、方法等在内的范围 | a f |
| 函数、方法等内部内容 | i f |
| 注释 | g c |
| 参数或列表项等 | i a |
| 参数或列表项等(含尾随逗号) | a a |
| 包含 HTML 风格标签在内的范围 | a t |
| HTML 风格标签内部内容 | i t |
| 当前缩进级别及前后各一行 | a I |
| 当前缩进级别及前一行 | a i |
| 当前缩进级别 | i i |
注意:[m 系列移动命令的目标边界定义与 af 一致。[[ 的目标与 ac 的定义相同,但若代码中不存在类,则会退回使用函数作为目标。同样地,g c 用于定位 [ /。
函数、类和注释的定义因语言而异。扩展可以通过添加 textobjects.scm 文件来获得支持。参数和标签的定义则运行在 Tree-sitter 层面,它会在解析树中查找特定模式,目前尚不支持按语言进行配置。
多光标
这些命令帮助你管理 Zed 中的多个光标。
| 命令 | 默认快捷键 |
|---|---|
| 选中当前单词的下一处,并添加一个光标 | g l |
| 选中当前单词的上一处,并添加一个光标 | g L |
| 在视觉选区内每行的行尾添加光标 | g A |
| 在视觉选区内每行的首字符处添加光标 | g I |
| 选中当前单词的所有出现位置(视觉选择) | g a |
| 跳过最新选中的单词,选中下一个 | g > |
| 跳过最新选中的单词,选中上一个 | g < |
窗格管理
这些命令用于打开新窗格或跳转到指定窗格。
| 命令 | 默认快捷键 |
|---|---|
| 打开全项目搜索 | g / |
| 打开当前搜索片段 | g <space> |
| 在分屏中打开当前搜索片段 | <ctrl-w> <space> |
| 在分屏中跳转到定义 | <ctrl-w> g d |
| 在分屏中跳转到类型定义 | <ctrl-w> g D |
插入模式
以下命令可帮助你在不退出插入模式的情况下调出 Zed 的补全菜单、请求 GitHub Copilot 建议或打开内联 AI 助手。
| 命令 | 默认快捷键 |
|---|---|
| 打开补全菜单 | ctrl-x ctrl-o |
| 请求 GitHub Copilot 建议(需预先配置 GitHub Copilot) | ctrl-x ctrl-c |
| 打开内联 AI 助手(需预先配置助手) | ctrl-x ctrl-a |
| 打开代码操作菜单 | ctrl-x ctrl-l |
| 隐藏所有建议 | ctrl-x ctrl-z |
支持的插件功能
Zed 的 vim 模式内置了 Vim 生态中常用插件提供的功能:
- 可以用
ys(yank surround)为文本对象添加包围符,用cs更换包围符,用ds删除包围符。 - 可以在可视模式下用
gc、在普通模式下用gcc切换注释。 - 项目面板支持许多仿照 Vim 插件
netrw的快捷键:用hjkl导航,用o打开文件,用t在新标签页打开文件,等等。 - 可以在 keymap 中添加按键绑定,以便在"camelCase"命名中移动。具体做法见下文可选按键绑定一节。
- 可以用
gR实现 ReplaceWithRegister 的功能。 - 可以用
cx实现 vim-exchange 的功能。注意它在可视模式下没有默认绑定,但你可以在 keymap 中自行添加(参见可选按键绑定一节)。 - 可以用 indent wise 插件的
[-、]-、[+、]+、[=、]=在相对于光标的缩进层级间移动。 - 可以用 AnyQuotes 选择引号内文本,用 AnyBrackets 选择括号内文本。Zed 还提供 MiniQuotes 和 MiniBrackets,其选择行为基于 Neovim 插件 mini.ai。详见下文引号与括号文本对象一节。
- 可以为 AnyQuotes、AnyBrackets、MiniQuotes、MiniBrackets 配置不同的选择策略来选取引号和括号内的文本。详见下文Any Bracket 功能一节。
Any Bracket 功能
Zed 提供了两种不同的策略来选取被引号或方括号包围的文本。这些文本对象默认未启用,必须在你的键位映射配置中进行设置后方可使用。
包含的字符
每种文本对象类型适用于特定的字符:
| 文本对象 | 字符 |
|---|---|
| AnyQuotes/MiniQuotes | 单引号(')、双引号(")、反引号(`) |
| AnyBrackets/MiniBrackets | 圆括号(())、方括号([])、花括号({})、尖括号(<>) |
“Any”和“Mini”两种变体适用于相同的字符集,但选取策略有所不同。
AnyQuotes 和 AnyBrackets(传统 Vim 行为)
这些文本对象实现了传统 Vim 的行为:
- 选取优先级:优先查找最内层(最近)的引号或括号
- 回退机制:若未找到,则回退到当前行
- 基于字符的匹配:仅关注开闭字符,不考虑语法结构
- 与原版 Vim 的一致性:AnyBrackets 的行为与原版 Vim 中如
ci<、ci(等命令一致,包括可能的边界情况(例如将=>中的>视为闭合分隔符)
MiniQuotes 和 MiniBrackets(mini.ai 行为)
这些文本对象实现了 mini.ai Neovim 插件的行为:
- 选取优先级:先搜索当前行,再向外扩展
- Tree-sitter 集成:使用 Tree-sitter 查询以实现更具上下文感知的选取
- 语法感知匹配:能够区分实际括号与其他上下文中的相似字符(例如
=>中的>)
选择何种方法
-
如果你符合以下情况,建议使用 AnyQuotes/AnyBrackets:
- 偏好传统 Vim 行为
- 希望保持基于字符的选取一致性,并优先处理最内层分隔符
- 需要行为与原版 Vim 文本对象紧密匹配
-
如果你符合以下情况,请使用 MiniQuotes/MiniBrackets:
- 更倾向于 mini.ai 插件的行为
- 希望使用 Tree-sitter 实现更具上下文感知的选择
- 搜索时更倾向于当前行优先
配置示例
要使用这些文本对象,需要在键位映射中添加绑定。以下是一个配置示例,使得在使用文本对象操作符(i 和 a)或更改环绕(cs)时,这些对象可用:
{
"context": "vim_operator == a || vim_operator == i || vim_operator == cs",
"bindings": {
// Traditional Vim behavior
"q": "vim::AnyQuotes",
"b": "vim::AnyBrackets",
// mini.ai plugin behavior
"Q": "vim::MiniQuotes",
"B": "vim::MiniBrackets"
}
}
使用此配置后,你可以使用如下命令:
cib- 使用 AnyBrackets 行为更改括号内部ciB- 使用 MiniBrackets 行为更改括号内部ciq- 使用 AnyQuotes 行为更改引号内部ciQ- 使用 MiniQuotes 行为更改引号内部
命令面板
Vim 模式允许你使用 : 打开 Zed 的命令面板。然后你可以输入内容来访问任何常规 Zed 命令。此外,vim 模式为流行的 Vim 命令添加了别名,以确保你的肌肉记忆能转移到 Zed。例如,你可以输入 :w 或 :write 来保存文件。
下方,你可以找到表格,列出了在命令面板中可使用的命令。我们用方括号表示可选字符,意味着你可以省略它们。
注意:我们尚未模拟 Vim 命令行的完整功能。特别是,命令目前不支持参数。如果你在命令面板中发现缺失的功能,请在 GitHub 上提交问题。
文件和窗口管理
此表格展示了用于管理窗口、标签页和窗格的命令。由于命令目前不支持参数,在保存或创建新文件时,无法指定文件名。
| 命令 | 说明 |
|---|---|
:w[rite][!] |
保存当前文件 |
:wq[!] |
保存文件并关闭缓冲区 |
:q[uit][!] |
关闭缓冲区 |
:wa[ll][!] |
保存所有打开的文件 |
:wqa[ll][!] |
保存所有打开的文件并关闭所有缓冲区 |
:qa[ll][!] |
关闭所有缓冲区 |
:[e]x[it][!] |
关闭缓冲区 |
:up[date] |
保存当前文件 |
:cq |
完全退出(关闭所有正在运行的 Zed 实例) |
:bd[elete][!] |
关闭所有面板中的当前活动文件 |
:vs[plit] |
垂直拆分面板 |
:sp[lit] |
水平拆分面板 |
:new |
在水平拆分中新建文件 |
:vne[w] |
在垂直拆分中新建文件 |
:tabedit |
在新标签页中新建文件 |
:tabnew |
在新标签页中新建文件 |
:tabn[ext] |
切换到下一个标签页 |
:tabp[rev] |
切换到上一个标签页 |
:tabc[lose] |
关闭当前标签页 |
:ls |
显示所有缓冲区 |
注意:
!字符用于强制执行命令,不保存更改或在覆盖文件前不做提示。
Ex 命令
以下 ex 命令用于打开 Zed 的各个面板和窗口。
| 命令 | 默认快捷键 |
|---|---|
| 打开项目面板 | :E[xplore] |
| 打开协作面板 | :C[ollab] |
| 打开聊天面板 | :Ch[at] |
| 打开 AI 面板 | :A[I] |
| 打开 git 面板 | :G[it] |
| 打开调试面板 | :D[ebug] |
| 打开通知面板 | :No[tif] |
| 打开反馈窗口 | :fe[edback] |
| 打开诊断窗口 | :cl[ist] |
| 打开终端 | :te[rm] |
| 打开扩展窗口 | :Ext[ensions] |
导航诊断
以下命令用于导航诊断信息。
| 命令 | 描述 |
|---|---|
:cn[ext] 或 :ln[ext] |
跳转到下一个诊断 |
:cp[rev] 或 :lp[rev] |
跳转到上一个诊断 |
:cc 或 :ll |
打开错误页面 |
Git
以下命令用于与版本控制系统 git 交互。
| 命令 | 描述 |
|---|---|
:dif[fupdate] |
查看光标下的 diff(在普通模式下为 d o) |
:rev[ert] |
恢复光标下的 diff(在普通模式下为 d p) |
跳转
以下命令用于跳转到文件中的特定位置。
| 命令 | 描述 |
|---|---|
:<number> |
跳转到指定行号 |
:$ |
跳转到文件末尾 |
:/foo 和 :?foo |
跳转到下一个/上一个匹配 foo 的行 |
替换
此命令用于替换文本。它模拟了 vim 中的 substitute 命令。该命令使用正则表达式,且 Zed 的语法与 vim 略有不同。你可以在下方的 正则表达式差异章节 中了解 Zed 语法的更多细节。Zed 默认只替换当前行中搜索模式的首个匹配项。要替换所有匹配项,请添加 g 标志。
| 命令 | 描述 |
|---|---|
:[range]s/foo/bar/[g] |
将 foo 的实例替换为 bar |
编辑
以下命令协助你编辑文本。
| 命令 | 描述 |
|---|---|
:j[oin] |
合并当前行 |
:d[elete][l][p] |
删除当前行 |
:s[ort] [i] |
对当前选区进行排序(添加 i 参数时不区分大小写) |
:y[ank] |
摘录(复制)当前选区或整行 |
Set
这些命令用于局部修改当前缓冲区中的编辑器选项。
| 命令 | 描述 |
|---|---|
:se[t] [no]wrap |
当行长度超过窗口宽度时,文字自动换行并延续到下一行显示 |
:se[t] [no]nu[mber] |
在每行前显示行号 |
:se[t] [no]r[elative]nu[mber] |
将显示的数字改为相对于光标的相对数值 |
:se[t] [no]i[gnore]c[ase] |
控制缓冲区和项目搜索是否使用区分大小写的匹配 |
命令助记符
Zed 默认不提供任何命令助记符,但你可以通过在配置文件中设置 command_aliases 来为 Zed 命令定义简短别名。当你在命令面板中输入此映射中的别名时,它会被解析为对应的命令。
配置示例
要配置命令助记符,请在配置文件中添加 command_aliases 键。以下是一个包含有用助记符的配置示例:
{
"command_aliases": {
"zlog": "zed::OpenLog",
"newf": "workspace::NewFile",
"diffs": "editor::ToggleSelectedDiffHunks",
"crp": "workspace::CopyRelativePath",
"cpp": "workspace::CopyPath",
"reveal": "editor::RevealInFileManager",
"clank": "editor::CancelLanguageServerWork"
}
}
通过此配置,你可以使用如下命令:
:zlog- 打开 Zed 日志:newf- 创建新文件:diffs- 切换选中的差异代码块:crp- 复制当前文件的相对路径:cpp- 复制当前文件的完整路径:reveal- 在文件管理器中显示当前文件:clank- 取消语言服务器正在执行的任务
自定义按键绑定
选择正确的 context
Zed 的按键绑定只有在 "context" 属性与编辑器当前所处的位置匹配时才会生效。例如,把按键绑定添加到 "Editor" context,那么它们只会在编辑文件时起作用;如果添加到 "Workspace" context,则在 Zed 的任何地方都有效。下面是一个在编辑文件时执行保存的按键绑定示例:
{
"context": "Editor",
"bindings": {
"ctrl-s": "workspace::Save"
}
}
context 是嵌套的:当你编辑文件时,所处的 context 是 "Editor",它位于 "Pane" 之内,而 "Pane" 又位于 "Workspace" 之内。这就是为什么添加到 "Workspace" context 的按键绑定在编辑文件时也能生效。请看示例:
// 这个按键绑定在编辑文件时生效。Zed 默认已内置了它,对应 workspace: save 命令。
{
"context": "Workspace",
"bindings": {
"ctrl-s": "workspace::Save"
}
}
context 是表达式,支持 &&(与)和 ||(或)等布尔运算符。例如,可以使用 "Editor && vim_mode == normal" 这个 context,创建只在编辑文件且处于 vim normal 模式时才生效的按键绑定。
Vim mode 在 "Editor" context 的基础上增加了几个 context:
| 运算符 | 说明 |
|---|---|
| VimControl | 表示 vim 按键绑定应生效。目前是 vim_mode == normal || vim_mode == visual || vim_mode == operator 的别名,但定义将来可能会变化 |
| vim_mode == normal | Normal 模式 |
| vim_mode == visual | Visual 模式 |
| vim_mode == insert | Insert 模式 |
| vim_mode == replace | Replace 模式 |
| vim_mode == waiting | 正在等待任意按键(例如,在输入 f 或 t 之后) |
| vim_mode == operator | 正在等待下一个绑定触发(例如,在输入 c 或 d 之后) |
| vim_operator | 除非 vim_mode == operator,否则设置为 none;若处于该模式,则设为当前操作符的默认按键(例如,输入 d 后,vim_operator == d) |
| helix_mode | 当当前模式为 Helix 模式(helix_normal 或 helix_select)时设置,包括操作符待处理且 vim_mode 报告为 operator 或 waiting 的情况 |
注意:上下文一次只匹配一层。因此可以使用表达式
"Editor && vim_mode == normal",但"Workspace && vim_mode == normal"永远不会匹配,因为我们在"Editor"层级设置 Vim 上下文。
Vim 模式按键绑定的常用上下文
下面是一个包含常用 Vim 模式上下文的模板,帮助你自定义 Vim 模式按键绑定。你可以复制并将其整合到你的用户键位映射中。
[
{
"context": "VimControl && !menu",
"bindings": {
// 如果你想让按键绑定在 normal 和 visual 模式下生效,请在此处添加。
}
},
{
"context": "vim_mode == normal && !menu",
"bindings": {
// "shift-y": ["workspace::SendKeystrokes", "y $"] // 使用 Neovim 的 yank 行为:复制到行尾。
}
},
{
"context": "vim_mode == insert",
"bindings": {
// "j k": "vim::NormalBefore" // 在插入模式下,按 jk 退出到普通模式。
}
},
{
"context": "EmptyPane || SharedScreen",
"bindings": {
// 如果想让按键绑定在没有编辑器存在时也能工作,请在此处(以及上述上下文的基础上)添加。
// "space f": "file_finder::Toggle"
}
}
]
提示:如果你想模拟 Vim 的
map命令(如nmap等),可以在正确的上下文中使用workspace::SendKeystrokes动作。
可选的按键绑定
默认情况下,你可以使用快捷键在编辑器中打开的不同文件之间导航:先按 ctrl+w,再按 h、j、k、l 分别向左、下、上、右移动。
但同样的快捷键无法用于在所有的编辑器停靠面板(终端、项目面板、Agent 面板等)之间切换。如果你希望使用相同的快捷键来导航这些面板,可以将以下按键绑定添加到你的用户按键映射中。
{
"context": "Dock",
"bindings": {
"ctrl-w h": "workspace::ActivatePaneLeft",
"ctrl-w l": "workspace::ActivatePaneRight",
"ctrl-w k": "workspace::ActivatePaneUp",
"ctrl-w j": "workspace::ActivatePaneDown"
// ... 或其他按键绑定
}
}
子词移动(Subword motion)功能允许你在 camelCase 或 snake_case 中导航和选中的是单个单词,默认未启用。若要启用,请将以下绑定添加到你的按键映射中。
{
"context": "VimControl && !menu && vim_mode != operator",
"bindings": {
"w": "vim::NextSubwordStart",
"b": "vim::PreviousSubwordStart",
"e": "vim::NextSubwordEnd",
"g e": "vim::PreviousSubwordEnd"
}
}
提示:像
dw这样的操作不受影响。如果希望这些操作也使用子词移动,请从context中移除vim_mode != operator。
Vim 模式提供了在普通模式下环绕选区的快捷键(ys),但没有提供在可视模式下添加环绕的快捷键。默认情况下,shift-s 会替换选区(擦除文本并进入插入模式)。若要使用 shift-s 在可视模式下添加环绕,可将以下对象添加到你的按键映射中。
{
"context": "vim_mode == visual",
"bindings": {
"shift-s": "vim::PushAddSurrounds"
}
}
在非模态编辑器中,光标移动到行尾时通常会换到下一行。但 Zed 默认的行为和 Vim 完全一致:光标会停在行边界。如果你希望光标在行间换行移动,可以覆盖以下键绑定:
// 在 VimScript 中等价于:
// set whichwrap+=<,>,[,],h,l
{
"context": "VimControl && !menu",
"bindings": {
"left": "vim::WrappingLeft",
"right": "vim::WrappingRight",
"h": "vim::WrappingLeft",
"l": "vim::WrappingRight"
}
}
Sneak motion 功能可以快速跳转到文本中任意两个字符的位置。要启用它,只需在 keymap 中添加以下键绑定。默认情况下 s 键映射为 vim::Substitute,添加这些绑定会覆盖该行为,请确认这符合你的使用习惯。
{
"context": "vim_mode == normal || vim_mode == visual",
"bindings": {
"s": "vim::PushSneak",
"shift-s": "vim::PushSneakBackward"
}
}
Helix 风格的 jump-to-word 操作会在可见的单词开头显示跳转标签。该功能在 Vim 模式中没有默认绑定,需要在 keymap 中添加键绑定才能启用。下面的示例使用 g w,这与 Helix 的默认绑定一致,但会覆盖 Vim 模式默认的重新换行绑定。
{
"context": "vim_mode == normal || vim_mode == visual",
"bindings": {
"g w": "vim::HelixJumpToWord"
}
}
vim-exchange 功能在 visual 模式下没有默认绑定,因为 shift-x 会与 visual 模式默认的 shift-x 绑定(vim::VisualDeleteLine)冲突。如果要设置 vim-exchange 的默认绑定,可以在 keymap 中添加以下键绑定:
{ "context": "vim_mode == visual", "bindings": { "shift-x": "vim::Exchange" } }
恢复常用文本编辑和 Zed 快捷键
如果你是在 Linux 或 Windows 上使用 Vim 模式,可能会发现它覆盖了那些你离不开的快捷键,比如 ctrl+v 粘贴、ctrl+f 搜索等。你可以通过将以下数据复制到自己的键位映射配置中来恢复这些快捷键:
{ "context": "Editor && !menu", "bindings": { "ctrl-f": "buffer_search::Deploy", // Vim 默认:翻页向下 "ctrl-c": "editor::Copy", // Vim 默认:返回普通模式 "ctrl-x": "editor::Cut", // Vim 默认:减少 "ctrl-v": "editor::Paste", // Vim 默认:可视化块模式 "ctrl-a": "editor::SelectAll", // Vim 默认:增加 "ctrl-y": "editor::Undo", // Vim 默认:向上移动一行 "ctrl-t": "project_symbols::Toggle", // Vim 默认:跳转到较旧的标签 "ctrl-o": "workspace::Open", // Vim 默认:后退 "ctrl-s": "workspace::Save", // Vim 默认:显示签名 "ctrl-b": "workspace::ToggleLeftDock" // Vim 默认:向下移动 } }
修改 Vim 模式设置
你可以修改以下设置来调整 Vim 模式的行为:
| 属性 | 描述 | 默认值 |
|---|---|---|
| default_mode | 启动时的默认模式。可选值包括 "normal"、"insert"、"replace"、"visual"、"visual_line"、"visual_block"、"helix_normal"。 | "normal" |
| use_system_clipboard | 决定如何使用系统剪贴板:
|
"always" |
| use_multiline_find | 已弃用 | |
| use_smartcase_find | 如果设为 true,且目标字母为小写时,f 和 t 移动指令将忽略大小写。 |
false |
| use_regex_search | 如果设为 true,Vim 搜索将使用正则表达式模式 |
true |
| gdefault | 如果设为 true,:substitute 命令默认替换行内的所有匹配项(相当于添加了 g 标志)。此时 g 标志用于切换此行为,即仅替换第一个匹配项。 |
false |
| toggle_relative_line_numbers | 如果设为 true,普通模式下显示相对行号,插入模式下显示绝对行号,兼顾两者优点。 |
false |
| custom_digraphs | 一个对象,允许你添加自定义 digraphs(双字组合)。示例见下文。 | {} |
| highlight_on_yank_duration | 高亮动画的持续时间(毫秒)。设为 0 可禁用 |
200 |
这是一个添加 zombie emoji(僵尸表情)digraph 的示例。配置后,输入 ctrl-k f z 即可插入僵尸表情。你可以添加任意数量的 digraphs。
{
"vim": {
"custom_digraphs": {
"fz": "🧟♀️"
}
}
}
以下是修改这些设置后的示例:
{
"vim": {
"default_mode": "insert",
"use_system_clipboard": "never",
"use_smartcase_find": true,
"use_regex_search": true,
"gdefault": true,
"toggle_relative_line_numbers": true,
"highlight_on_yank_duration": 50,
"custom_digraphs": {
"fz": "🧟♀️"
}
}
}
Vim 模式下有用的 Zed 核心设置
以下是一些通用 Zed 设置,有助于微调你的 Vim 体验:
| 属性 | 描述 | 默认值 |
|---|---|---|
| cursor_blink | 如果设为 true,光标会闪烁。 |
true |
| relative_line_numbers | 如果设为 "enabled",左侧边栏的行号相对于光标位置显示。如果设为 "wrapped",换行行也会显示行号。 |
"disabled" |
| scrollbar | 控制滚动条显示的对象。设置为 { "show": "never" } 可隐藏滚动条。 |
{ "show": "auto" } |
| scroll_beyond_last_line | 设为 "one_page" 时,允许滚动超出最后一行最多一页。设为 "off" 可禁用此行为。 |
"one_page" |
| vertical_scroll_margin | 滚动时光标上下保留的行数。设为 0 可让光标垂直方向一直移动到屏幕边缘。 |
3 |
| gutter.line_numbers | 控制行号槽中行号的显示。将 "line_numbers" 属性设为 false 可隐藏行号。 |
true |
| command_aliases | 为命令面板中的命令定义别名的对象。可以用来给常用命令设置快捷名称,示例如下。 | {} |
以下是修改这些设置后的示例:
{
// 禁用光标闪烁
"cursor_blink": false,
// 使用相对行号
"relative_line_numbers": "enabled",
// 隐藏滚动条
"scrollbar": { "show": "never" },
// 禁止缓冲区滚动超出最后一行
"scroll_beyond_last_line": "off",
// 允许光标到达屏幕边缘
"vertical_scroll_margin": 0,
"gutter": {
// 完全禁用行号
"line_numbers": false
},
"command_aliases": {
"W": "w",
"Wq": "wq",
"Q": "q"
}
}
command_aliases 是一个对象,用于把按键或按键序列映射到 vim mode 命令。上面的例子定义了多个别名:W 映射到 w、Wq 映射到 wq、Q 映射到 q。
正则表达式差异
Zed 使用的正则表达式引擎与 Vim 不同,因此在某些情况下需要使用不同的语法。以下是常见的差异:
- 捕获组:Vim 使用
\(和\)表示捕获组,而在 Zed 中是(和)。反过来,在 Vim 中,(和)表示字面括号,但在 Zed 中必须转义为\(和\)。 - 匹配引用:替换时,Vim 使用反斜杠后跟数字来表示已匹配的捕获组,例如
\1。Zed 则使用美元符号。也就是说,在 Vim 中用\0表示整个匹配时,在 Zed 中语法是$0。编号捕获组同理:Vim 中的\1在 Zed 中是$1。 - 全局选项:默认情况下,Vim 的正则搜索只匹配每行中的首次出现,你需要在查询末尾添加
/g以查找所有匹配。而在 Zed 中,正则搜索默认就是全局的。 - 大小写敏感性:Vim 使用
/i表示忽略大小写的搜索。在 Zed 中,你可以在模式开头写(?i),或者通过快捷键 {#kb search::ToggleCaseSensitive} 切换大小写敏感性。
提示:为了方便过渡,当你编写 Vim 风格的替换命令
:%s//时,命令面板会自动修正括号并替换组。例如,Zed 会将%s:/\(a\)(b)/\1/转换为搜索 "(a)(b)" 并替换为 "$1"。
关于 Zed 正则引擎支持的完整语法,请参阅 regex 文档。