首页
/ Zed 内置 Vim 模式实战指南:从模式设计、命令映射到 Zed 原生扩展与配置调优

Zed 内置 Vim 模式实战指南:从模式设计、命令映射到 Zed 原生扩展与配置调优

2026-09-07 12:03:57作者:苗圣禹Peter

Zed 并不是简单地做“键位仿真”,而是把 Vim 的模态操作模型嫁接到自身基于 Tree-sitter、语言服务器与多光标的高性能编辑内核上。这篇指南以 Zed 官方 Vim 模式文档为主线(仓库 docs/src/vim.md),完整覆盖模式的启用/关闭、motion 与 text object 快捷键、: 命令面板、AnyQuotes/AnyBrackets 文本对象、键位上下文定制与全部相关设置项,并结合 crates 源码给出实现层证据。读完你可以在 Zed 中真正配置出一套既保留 Vim 肌肉记忆、又能享用语义导航、多光标、内联 AI 等 Zed 原生能力的日常编辑环境。

Zed vim mode 的设计理念

Vim 模式的目标是“在合理之处复刻 Vim 的 motions 与命令行为,在 Zed 更强的地方使用 Zed 自己的实现”,力求开箱即用、无需配置即可获得熟悉的体验。它并非 Vim 的一比一克隆,而是把 Vim 的模态设计与 Zed 的现代能力融合,并保持高度可配置(可以添加自己的键位或覆盖默认值)。

Zed 官方文档将 vim mode 中复用 Zed 核心功能、从而在行为上产生差异的特性归纳为四类:

  1. Motions(动作):vim mode 使用 Zed 的语义解析按语言微调 motion 行为。例如在 Rust 中,用 % 跳转匹配括号时也能与管道符 | 配对;在 JavaScript 中,w 会把 $ 当作单词字符。
  2. Visual block 选择:vim mode 用 Zed 的多光标来模拟块选择,这让块选择灵活得多。例如块选择后输入的任何内容都会实时同步到每一行,并且你可以随时增删光标。
  3. Macros(宏):vim mode 用 Zed 的录制系统承载 Vim 宏,因此可以录制与回放更复杂的操作,例如自动补全。
  4. Search 与 replace:vim mode 复用 Zed 的搜索系统,因此正则语法与 Vim 略有差异,详见下文 正则差异 一节。

从源码结构看,这套体系在 crates/vim/src/ 中按职责拆分为多个模块:motion.rs(动作)、object.rs(文本对象)、visual.rs(可视模式)、normal.rs / insert.rs / replace.rs(各模式)、surrounds.rs(包围与去包围)、command.rs(Ex 命令解析与 :set 选项)、digraph.rs(二合字 digraph)、rewrap.rsindent.rs,另有 helix.rs 提供 Helix 风格的模式支持,可以顺着这些文件深入阅读各功能的实现细节。

启用与禁用 vim mode

首次启动 Zed 时,欢迎屏上会有一个复选框让你选择是否启用 vim mode。如果错过了这一步,随时可以通过命令面板执行工作区命令 workspace::ToggleVimMode 来开关该模式。

注意:该命令实际切换的是用户设置中的如下属性:

{
  "vim_mode": true
}

对应地,在 assets/settings/default.json 中该值默认为 false。设置项的读取逻辑独立成 crate:crates/vim_mode_setting/src/vim_mode_setting.rs 中定义了 VimModeSettingHelixModeSetting 两个 bool 型设置,其注释说明将其独立拆分,是为了让其他 crate 在不整体依赖 vim crate 的前提下也能开关 Vim/Helix 模式。

Zed 专属功能

Zed 构建在现代基础之上:使用 Tree-sitter 与语言服务器理解正在编辑的文件内容,并原生支持多光标。Vim 模式为此内置了一批 “core Zed” 键位,帮助你最大化利用 Zed 的独有能力。平台间键位略有差异,仓库中存放了 default-linux.jsondefault-macos.jsondefault-windows.json 三份默认键位表,下面各表以文档原文为准。

语言服务器(Language server)

以下命令借助语言服务器完成代码跳转与重构,默认快捷键:

Command Default Shortcut
Go to definition g d
Go to declaration g D
Go to type definition g y
Go to implementation g I
Rename (change definition) c d
Go to All references to the current word g A
Find symbol in current file g s
Find symbol in entire project g S
Go to next diagnostic g ]] d
Go to previous diagnostic g [[ d
Show inline error (hover) g h
Open the code actions menu g .

Git

Command Default Shortcut
Go to next git change ] c
Go to previous git change [ c
Expand diff hunk d o
Toggle staged d O
Stage and next (in diff view) d u
Unstage and next (in diff view) d U
Restore change d p

Tree-sitter

Tree-sitter 是 Zed 用来理解代码结构的解析器。Zed 提供了两类基于语法树的能力:改变光标位置的 motions,以及可作为操作目标的 text objects

Command Default Shortcut
Go to next/previous method ] m / [ m
Go to next/previous method end ] M / [ M
Go to next/previous section ] ] / [ [
Go to next/previous section end ] [ / [ ]
Go to next/previous comment ] /, ] * / [ /, [ *
Select a larger syntax node [ x
Select a smaller syntax node ] x
Text Objects Default Shortcut
Around a class, definition, etc. a c
Inside a class, definition, etc. i c
Around a function, method etc. a f
Inside a function, method, etc. i f
A comment g c
An argument, or list item, etc. i a
An argument, or list item, etc. (including trailing comma) a a
Around an HTML-like tag a t
Inside an HTML-like tag i t
The current indent level, and one line before and after a I
The current indent level, and one line before a i
The current indent level i i

需要说明的是各 motion/text object 目标的一致性:[m 系列 motion 的目标定义与 af 的边界一致;[[ 系列的目标与 ac 相同,且在没有类时退而使用函数;gc 用于定位 [ /g c 对应的注释。函数、类、注释的“边界定义”是语言相关的,扩展可通过添加 textobjects.scm 查询文件来补充支持(例如 crates/grammars/src/c/textobjects.scmcrates/grammars/src/go/textobjects.scm 等都是这类查询文件)。而参数与标签的定义运行在 Tree-sitter 层面、按解析树中的特定模式匹配,目前不支持按语言配置。

多光标(Multi cursor)

以下命令用于管理 Zed 中的多个光标:

Command Default Shortcut
Add a cursor selecting the next copy of the current word g l
Add a cursor selecting the previous copy of the current word g L
Add a cursor at the end of every line in the current visual selection g A
Add a cursor at the first character of every line in the current visual selection g I
Add a visual selection for every copy of the current word g a
Skip latest word selection, and add next g >
Skip latest word selection, and add previous g <

面板管理(Pane management)

Command Default Shortcut
Open a project-wide search g /
Open the current search excerpt g <space>
Open the current search excerpt in a split <ctrl-w> <space>
Go to definition in a split <ctrl-w> g d
Go to type definition in a split <ctrl-w> g D

插入模式(In insert mode)

以下命令让你无需退出插入模式即可唤起 Zed 的补全菜单、向 GitHub Copilot 请求建议,或打开内联 AI 助手:

Command Default Shortcut
Open the completion menu ctrl-x ctrl-o
Request GitHub Copilot suggestion (requires GitHub Copilot to be configured) ctrl-x ctrl-c
Open the inline AI assistant (requires a configured assistant) ctrl-x ctrl-a
Open the code actions menu ctrl-x ctrl-l
Hides all suggestions ctrl-x ctrl-z

内置插件功能(Supported plugins)

Zed 的 vim mode 直接内置了 Vim 生态中常由插件提供的功能:

  • ys(yank surround)给文本对象加包围、cs 改包围、ds 删包围;
  • 可视模式下用 gc、普通模式下用 gcc 注释/取消注释选区;
  • 项目面板支持大量仿照 Vim 插件 netrw 的快捷键:用 hjkl 导航、o 打开文件、t 在新标签页打开文件等;
  • 可以自行添加键位在 camelCase 名称内按“子词”导航,见下文可选键位绑定
  • gR 实现 ReplaceWithRegister 式功能;
  • cx 实现 vim-exchange 式功能(注意可视模式默认无绑定,可在可选键位绑定中自行添加);
  • [-]-[+]+[=]= 相对光标进行 indent-wise 式导航;
  • 用 AnyQuotes/AnyBrackets 选中引号/括号文本,并额外提供基于 Neovim mini.ai 插件的 MiniQuotes/MiniBrackets 备选选择策略,详见下节。

这些绑定的默认实现都体现在默认键位表 assets/keymaps/vim.json 中,可作为对照自定义的起点。

Any Bracket 功能:引号与括号文本对象的两种策略

Zed 提供两种选中被引号/括号包围文本的策略。这些文本对象默认不启用,需要在 keymap 中配置后才可用。

支持的字符集

每种文本对象作用于固定字符:

Text Object Characters
AnyQuotes/MiniQuotes 单引号(')、双引号(")、反引号(`
AnyBrackets/MiniBrackets 圆括号(())、方括号([])、花括号({})、尖括号(<>

“Any”与“Mini”两种变体作用于相同字符集,区别在于选择策略。

AnyQuotes / AnyBrackets:传统 Vim 行为

  • 选择优先级:优先找到最内层(最近的)引号或括号;
  • 回退机制:如果找不到则回退到当前行;
  • 基于字符匹配:只关注开/闭字符本身,不考虑语法语义;
  • 贴近原版 Vim:AnyBrackets 与原版 Vim 中 ci<ci( 等命令行为一致,包括一些边界情形(例如把 => 中的 > 视为闭括号)。

MiniQuotes / MiniBrackets:mini.ai 行为

  • 选择优先级:先搜索当前行,再向外扩展;
  • Tree-sitter 集成:使用 Tree-sitter 查询实现更上下文相关的选区;
  • 语法感知匹配:能区分真正的括号与类似字符的其他语境(例如 => 中的 >)。

如何选择

  • 若你偏好传统 Vim 行为、想要“优先最内层分隔符”的稳定字符级选择、需要与原版 Vim 文本对象行为高度一致,选 AnyQuotes/AnyBrackets
  • 若你偏好 mini.ai 插件行为、想要基于 Tree-sitter 的更上下文相关的选择、搜索时优先当前行,选 MiniQuotes/MiniBrackets

配置示例

使用这些文本对象需要向 keymap 添加绑定。下面示例让它们在文本对象操作符(ia)或改包围(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 行为修改引号内内容

对照默认键位表 assets/keymaps/vim.json 可以看到:在 vim_operator 语境下,默认把 q 绑到了 vim::MiniQuotes,而 AnyQuotes、AnyBrackets、MiniBrackets 等均以注释形式保留,说明这正是文档所述“默认不启用、需自行配置”的能力入口,直接编辑你的用户 keymap 覆盖即可。

命令面板(: 命令

Vim 模式允许你用 : 打开 Zed 的命令面板,随后输入任意常规 Zed 命令;同时为流行的 Vim 命令提供别名,保证肌肉记忆可以迁移。例如输入 :w:write 都可以保存文件。

以下表格列出可在命令面板使用的命令,方括号内为可省略的字符。

注意:目前并不完整模拟 Vim 命令行的全部能力,命令暂不支持参数。官方欢迎用户在缺少所需功能时提交 issue 反馈。

文件与窗口管理

因为命令暂不支持参数,保存或新建文件时无法指定文件名。

Command Description
:w[rite][!] Save the current file
:wq[!] Save the file and close the buffer
:q[uit][!] Close the buffer
:wa[ll][!] Save all open files
:wqa[ll][!] Save all open files and close all buffers
:qa[ll][!] Close all buffers
:[e]x[it][!] Close the buffer
:up[date] Save the current file
:cq Quit completely (close all running instances of Zed)
:bd[elete][!] Close the active file in all panes
:vs[plit] Split the pane vertically
:sp[lit] Split the pane horizontally
:new Create a new file in a horizontal split
:vne[w] Create a new file in a vertical split
:tabedit Create a new file in a new tab
:tabnew Create a new file in a new tab
:tabn[ext] Go to the next tab
:tabp[rev] Go to previous tab
:tabc[lose] Close the current tab
:ls Show all buffers

注意! 用于强制执行命令,即不保存更改即执行、或在覆盖文件前不提示。

Ex 命令

这些命令打开 Zed 的各类面板与窗口:

Command Default Shortcut
Open the project panel :E[xplore]
Open the collaboration panel :C[ollab]
Open the chat panel :Ch[at]
Open the AI panel :A[I]
Open the git panel :G[it]
Open the debug panel :D[ebug]
Open the notifications panel :No[tif]
Open the feedback window :fe[edback]
Open the diagnostics window :cl[ist]
Open the terminal :te[rm]
Open the extensions window :Ext[ensions]

诊断导航

Command Description
:cn[ext] or :ln[ext] Go to the next diagnostic
:cp[rev] or :lp[rev] Go to the previous diagnostic
:cc or :ll Open the errors page

Git

Command Description
:dif[fupdate] View the diff under the cursor (d o in normal mode)
:rev[ert] Revert the diff under the cursor (d p in normal mode)

跳转

Command Description
:<number> Jump to a line number
:$ Jump to the end of the file
:/foo and :?foo Jump to next/prev line matching foo

替换

该命令模拟 Vim 的 substitute 命令。它使用正则表达式,而 Zed 的语法与 Vim 略有不同(详见下文正则差异)。Zed 默认只替换当前行搜索模式的首个匹配;要替换全部匹配需追加 g 标志。

Command Description
:[range]s/foo/bar/[g] Replace instances of foo with bar

编辑

Command Description
:j[oin] Join the current line
:d[elete][l][p] Delete the current line
:s[ort] [i] Sort the current selection (with i, case-insensitively)
:y[ank] Yank (copy) the current selection or line

Set

以下命令针对当前 buffer 局部修改编辑器选项:

Command Description
:se[t] [no]wrap Lines longer than the width of the window will wrap and displaying continues on the next line
:se[t] [no]nu[mber] Print the line number in front of each line
:se[t] [no]r[elative]nu[mber] Changes the displayed number to be relative to the cursor
:se[t] [no]i[gnore]c[ase] Controls whether the buffer and project search use case-sensitive matching

从源码看,Ex 命令的解析集中在 crates/vim/src/command.rs:例如 gdefault/nogdefaultcommand.rs 中被解析为 VimOption::GDefault,并在执行时写回全局设置(command.rs);而在 crates/vim/src/normal/search.rs 的替换逻辑中,gdefault 会反转 g 标志的含义,其行为由测试用例 test_replace_gdefaultsearch.rs)对照 Neovim 行为验证:开启 gdefault:s/// 默认替换全部匹配,而加 g 反而只替换首个匹配。

命令助记符(Command mnemonics)

Zed 默认不预置任何命令助记符,但你可以在设置文件的 command_aliases 字段定义指向 Zed 命令的短别名。在命令面板输入该映射中的别名时,会自动解析为对应命令。

配置示例

{
  "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 - 切换选中 diff hunk
  • :crp - 复制当前文件相对路径
  • :cpp - 复制当前文件完整路径
  • :reveal - 在文件管理器中显示当前文件
  • :clank - 取消语言服务器工作

自定义键位绑定

选择正确的 context

Zed 的键位只有在 "context" 属性与编辑器中当前位置匹配时才生效。例如把键位放进 "Editor" context,只在编辑文件时生效;放进 "Workspace" context,则在 Zed 任意位置都生效。示例——编辑文件时保存:

{
  "context": "Editor",
  "bindings": {
    "ctrl-s": "workspace::Save"
  }
}

Context 是嵌套的:编辑文件时你处于 "Editor" context,它位于 "Pane" context 之内,而 "Pane" 又在 "Workspace" context 之内。因此放在 "Workspace" 的键位在编辑文件时同样生效。示例(该绑定是 Zed 内置默认 workspace 保存命令,仅供说明):

// This key binding will work when you're editing a file. It comes built into Zed by default as the workspace: save command.
{
  "context": "Workspace",
  "bindings": {
    "ctrl-s": "workspace::Save"
  }
}

Context 本质是表达式,支持 &&(与)与 ||(或)布尔运算符。例如用 "Editor && vim_mode == normal" 让键位只在编辑文件处于 vim 普通模式时生效。

Vim 模式向 "Editor" context 添加了以下子 context:

Operator Description
VimControl Indicates that vim keybindings should work. Currently an alias for vim_mode == normal || vim_mode == visual || vim_mode == operator, but the definition may change over time
vim_mode == normal Normal mode
vim_mode == visual Visual mode
vim_mode == insert Insert mode
vim_mode == replace Replace mode
vim_mode == waiting Waiting for an arbitrary key (e.g., after typing f or t)
vim_mode == operator Waiting for another binding to trigger (e.g., after typing c or d)
vim_operator Set to none unless vim_mode == operator, in which case it is set to the current operator's default keybinding (e.g., after typing d, vim_operator == d)
helix_mode Set when the current mode is a Helix mode (helix_normal or helix_select), including while an operator is pending and vim_mode reports operator or waiting

注意:Context 每次只在一层上匹配。因此 "Editor && vim_mode == normal" 是可行的,而 "Workspace && vim_mode == normal" 永远不会匹配,因为 vim context 是在 "Editor" 层设置的。

常用 vim context 模板

下面的模板覆盖了常用的 vim context,可直接复制整合进你的用户 keymap:

[
  {
    "context": "VimControl && !menu",
    "bindings": {
      // Put key bindings here if you want them to work in normal & visual mode.
    }
  },
  {
    "context": "vim_mode == normal && !menu",
    "bindings": {
      // "shift-y": ["workspace::SendKeystrokes", "y $"] // Use neovim's yank behavior: yank to end of line.
    }
  },
  {
    "context": "vim_mode == insert",
    "bindings": {
      // "j k": "vim::NormalBefore" // In insert mode, make jk escape to normal mode.
    }
  },
  {
    "context": "EmptyPane || SharedScreen",
    "bindings": {
      // Put key bindings here (in addition to the context above) if you want them to
      // work when no editor exists.
      // "space f": "file_finder::Toggle"
    }
  }
]

注意:如需模拟 Vim 的 map 类命令(nmap 等),可以在正确 context 下使用 workspace::SendKeystrokes 动作实现。

可选键位绑定

跨 dock 导航:默认你只能用 ctrl+whjkl 在编辑器各面板(pane)之间移动,但这些快捷键不适用于终端、项目面板、agent 面板等 dock。若想让同样的快捷键作用于 dock,把下面键位加入用户 keymap:

{
  "context": "Dock",
  "bindings": {
    "ctrl-w h": "workspace::ActivatePaneLeft",
    "ctrl-w l": "workspace::ActivatePaneRight",
    "ctrl-w k": "workspace::ActivatePaneUp",
    "ctrl-w j": "workspace::ActivatePaneDown"
    // ... or other keybindings
  }
}

子词导航(Subword motion):默认不启用,它允许在 camelCasesnake_case 内按单词导航和选择。启用方式:

{
  "context": "VimControl && !menu && vim_mode != operator",
  "bindings": {
    "w": "vim::NextSubwordStart",
    "b": "vim::PreviousSubwordStart",
    "e": "vim::NextSubwordEnd",
    "g e": "vim::PreviousSubwordEnd"
  }
}

注意:dw 等操作不受影响。如果希望操作也使用子词 motion,请把 context 中的 vim_mode != operator 去掉。

对照默认键位表 assets/keymaps/vim.json 可见,这些子词 motion 绑定在默认配置中同样以注释形式存在,静待启用。

可视模式包围:vim mode 在普通模式下用 ys 添加包围,但没有可视模式下的添加包围快捷键。默认 shift-s 是替换选区(删除文本并进入插入模式)。若想在可视模式下用 shift-s 添加包围:

{
  "context": "vim_mode == visual",
  "bindings": {
    "shift-s": "vim::PushAddSurrounds"
  }
}

光标行尾回绕(whichwrap):非模态编辑器通常在越过行尾时光标自动回绕,而 Zed 与 Vim 一致,默认让光标停在各行边界。若希望回绕,覆盖以下键位(等价于 VimScript 的 set whichwrap+=<,>,[,],h,l):

// In VimScript, this would look like this:
// set whichwrap+=<,>,[,],h,l
{
  "context": "VimControl && !menu",
  "bindings": {
    "left": "vim::WrappingLeft",
    "right": "vim::WrappingRight",
    "h": "vim::WrappingLeft",
    "l": "vim::WrappingRight"
  }
}

Sneak 快速跳转:可跳转到文本中任意两字符序列。默认 s 映射为 vim::Substitute,添加以下绑定会覆盖它,请确认符合你的工作流:

{
  "context": "vim_mode == normal || vim_mode == visual",
  "bindings": {
    "s": "vim::PushSneak",
    "shift-s": "vim::PushSneakBackward"
  }
}

Helix 风格跳词标签:在可见的单词开头显示跳转标签。vim 模式默认无绑定,示例使用 g w(与 Helix 默认绑定一致,但会覆盖 vim 默认的 rewrap 绑定):

{
  "context": "vim_mode == normal || vim_mode == visual",
  "bindings": {
    "g w": "vim::HelixJumpToWord"
  }
}

vim-exchange 可视模式绑定:因 shift-x 与可视模式默认的 vim::VisualDeleteLine 冲突,需要时手动绑定:

{
  "context": "vim_mode == visual",
  "bindings": {
    "shift-x": "vim::Exchange"
  }
}

恢复常用文本编辑与 Zed 键位

在 Linux 或 Windows 上使用 vim 模式时,可能会发现它覆盖了你离不开的快捷键:ctrl+v 粘贴、ctrl+f 搜索等。把下面的数据复制进 keymap 即可恢复:

{
  "context": "Editor && !menu",
  "bindings": {
    "ctrl-f": "buffer_search::Deploy",      // vim default: page down
    "ctrl-c": "editor::Copy",               // vim default: return to normal mode
    "ctrl-x": "editor::Cut",                // vim default: decrement
    "ctrl-v": "editor::Paste",              // vim default: visual block mode
    "ctrl-a": "editor::SelectAll",          // vim default: increment
    "ctrl-y": "editor::Undo",               // vim default: line up
    "ctrl-t": "project_symbols::Toggle",    // vim default: go to older tag
    "ctrl-o": "workspace::Open",            // vim default: go back
    "ctrl-s": "workspace::Save",            // vim default: show signature
    "ctrl-b": "workspace::ToggleLeftDock"   // vim default: down
  }
},

修改 vim 模式设置

以下是可改变 vim 模式行为的设置项:

Property Description Default Value
default_mode The default mode to start in. One of "normal", "insert", "replace", "visual", "visual_line", "visual_block", "helix_normal". "normal"
use_system_clipboard Determines how system clipboard is used:
  • "always": use for all operations
  • "never": only use when explicitly specified
  • "on_yank": use for yank operations
"always"
use_multiline_find deprecated
use_smartcase_find If true, f and t motions are case-insensitive when the target letter is lowercase. false
use_regex_search If true, then vim search will use regex mode true
gdefault If true, the :substitute command replaces all matches in a line by default (as if g flag was given). The g flag then toggles this, replacing only the first match. false
toggle_relative_line_numbers If true, line numbers are relative in normal mode and absolute in insert mode, giving you the best of both options. false
custom_digraphs An object that allows you to add custom digraphs. Read below for an example. {}
highlight_on_yank_duration The duration of the highlight animation(in ms). Set to 0 to disable 200

添加一个“僵尸 emoji”二合字的示例——之后输入 ctrl-k f z 即可插入一个僵尸 emoji,可按需添加任意多个:

{
  "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": "🧟‍♀️"
    }
  }
}

从源码看,上述设置项的 schema 定义在 crates/settings_content/src/settings_content.rsVimSettingsContent(含 gdefault 的语义注释、cursor_shapeshow_edit_predictions_in_normal_mode 等),取值类型如 ModeContentnormal/insert,见 settings_content.rs)与 UseSystemClipboardnever/always/on_yank,见 settings_content.rs)。它们最终汇入 crates/vim/src/vim.rs 中标记 RegisterSettingVimSettings 结构体,并在 vim.rsSettings trait 实现里统一 unwrap() 为具体运行时值;assets/settings/default.jsonvim 配置段 给出了与上表一致的默认值。关键行为都有对应源码落点,例如:yank 高亮时长在 crates/vim/src/normal/yank.rs 中读取并决定高亮动画;剪贴板策略在 crates/vim/src/state.rscrates/vim/src/state.rs 中被查询,用于决定是否写系统剪贴板;digraph 在 crates/vim/src/digraph.rs 中先查用户自定义映射再查内置表,其测试用例(digraph.rs)也直接演示了插入自定义 digraph 的写法。

对 vim 模式有用的核心 Zed 设置

以下通用 Zed 设置能帮你进一步打磨 Vim 体验:

Property Description Default Value
cursor_blink If true, the cursor blinks. true
relative_line_numbers If "enabled", line numbers in the left gutter are relative to the cursor. If "wrapped", they also display for wrapped lines. "disabled"
scrollbar Object that controls the scrollbar display. Set to { "show": "never" } to hide the scroll bar. { "show": "auto" }
scroll_beyond_last_line If set to "one_page", allows scrolling up to one page beyond the last line. Set to "off" to prevent this behavior. "one_page"
vertical_scroll_margin The number of lines to keep above or below the cursor when scrolling. Set to 0 to allow the cursor to go up to the edges of the screen vertically. 3
gutter.line_numbers Controls the display of line numbers in the gutter. Set the "line_numbers" property to false to hide line numbers. true
command_aliases Object that defines aliases for commands in the command palette. You can use it to define shortcut names for commands you use often. Read below for examples. {}

综合调整示例:

{
  // Disable cursor blink
  "cursor_blink": false,
  // Use relative line numbers
  "relative_line_numbers": "enabled",
  // Hide the scroll bar
  "scrollbar": { "show": "never" },
  // Prevent the buffer from scrolling beyond the last line
  "scroll_beyond_last_line": "off",
  // Allow the cursor to reach the edges of the screen
  "vertical_scroll_margin": 0,
  "gutter": {
    // Disable line numbers completely
    "line_numbers": false
  },
  "command_aliases": {
    "W": "w",
    "Wq": "wq",
    "Q": "q"
  }
}

command_aliases 是一个把键或键序列映射到 vim 模式命令的对象。上例定义了多个别名:W 对应 wWq 对应 wqQ 对应 q。它与普通 Zed 设置(如 assets/settings/default.json)平级存放,用户在用户设置文件中覆盖即可。

另外,vim 模式还支持各模式独立光标形状(vim.cursor_shape,含 normal/replace/visual/insert,值可为 blockbarunderlinehollow,插入模式还可设 inherit 继承编辑器主光标),以及控制普通模式下是否显示 edit predictions 的 show_edit_predictions_in_normal_mode,这两项同样定义在 settings_content.rsdefault.json 中,属于文档默认配置之外值得了解的高级选项。

正则差异(Regex differences)

Zed 使用与 Vim 不同的正则引擎,因此部分场景需要换用不同的语法。最常见的差异如下:

  • 捕获组:Vim 用 \(\) 表示捕获组,Zed 中为 ()。反过来,Vim 中 () 表示字面括号,Zed 中必须转义为 \(\)
  • 匹配引用:替换时 Vim 用反斜杠加数字表示已匹配的捕获组(如 \1),Zed 用美元符:Vim 中 \0 表示整个匹配,Zed 里是 $0;编号捕获组同理,Vim 的 \1 对应 Zed 的 $1
  • 全局选项:Vim 默认只匹配每行首个出现、在末尾加 /g 找全部;Zed 中正则搜索默认全局
  • 大小写敏感:Vim 用 /i 表示不区分大小写搜索;Zed 中可在模式开头写 (?i),或用快捷键 search::ToggleCaseSensitive 切换大小写敏感。

注意:为帮助过渡,当你编写 Vim 风格替换命令 :%s// 时,命令面板会替你修复括号与替换组。例如 Zed 会把 %s:/\(a\)(b)/\1/ 转换为搜索 "(a)(b)"、替换为 "$1"。

Zed 正则引擎的完整语法以 Rust regex crate 支持为准(对应 Cargo.lock 中所锁定版本的 regex 依赖),其替换语义($1$0 等)也直接体现在 crates/vim/src/normal/search.rs 的 substitute 实现中。

小结

Zed 的 vim 模式是一套“语义化”而非“键位化”的模态编辑实现:%w 等 motion 感知语言结构,visual block 建立于实时多光标之上,宏可以录制补全等复合操作,gc/af 等文本对象由 Tree-sitter 查询驱动,而语言服务器、Git 与内联 AI 也被映射成顺手的 vim 风格快捷键。配合 vim_* 系列 context 表达式、command_aliases、Any/Mini 系列引号括号文本对象与 vim 设置段,几乎每个行为都可按需覆盖。若想深入了解实现,建议从 crates/vim/src 入手,尤其关注 vim.rs(模式状态与设置装配)、normal/search.rs(查找替换)、object.rs(文本对象)与 visual.rs(可视模式),再对照 assets/keymaps/vim.json 理解默认键位的组织方式。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.14 K
2.75 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
857
1.35 K
docsdocs
暂无描述
Markdown
898
5.82 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
531
596
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
921
1.84 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.8 K
1.02 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.36 K
1.46 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.02 K
519
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
548
391