Vim 的拼写检查怎么开启和校正?
写代码的时候拼错变量名、写文档的时候拼错单词,这种事谁都遇到过。Vim 从 7.0 开始就内置了拼写检查,不需要额外装插件,配几行就能用。但很多人要么不知道这个功能,要么只知道 :set spell 就停了。下面把常用操作和容易踩的坑都过一遍。
开启拼写检查并选择语言
核心就两个选项:
vimset spell set spelllang=en_us
spell 打开拼写检查,spelllang 指定检查哪种语言。Vim 默认只自带英语拼写文件,第一次切换到其他语言时会自动从 vim.org 下载对应的 .spl 文件,放到 ~/.vim/spell/ 目录下。
如果只想对当前缓冲区生效而不影响其他文件,用 setlocal 代替 set:
vimsetlocal spell spelllang=en_us
关闭拼写检查则是 :set nospell。
在拼写错误之间跳转
开启之后,Vim 会用不同颜色标记出问题单词:
- SpellBad(红色)— 不认识的词
- SpellCap(蓝色)— 应该大写但没大写
- SpellRare(黄色)— 罕见拼写
- SpellLocal(绿色)— 不符合当前区域的拼写
跳转命令:
| 命令 | 作用 |
|---|---|
]s | 跳到下一个拼写错误 |
[s | 跳到上一个拼写错误 |
]S | 跳到下一个坏词(只跳 SpellBad,忽略大小写等问题) |
[S | 跳到上一个坏词 |
日常用 ]s 和 [s 就够了,]S 和 [S 在你只关心"这个词不认识"的时候更精准。
用 z= 修正拼写
光标放在拼写错误的单词上,按 z=,Vim 会弹出一个建议列表,编号从 1 开始。输入对应数字回车即可替换。
如果建议列表太长,可以加计数前缀跳过前面的选项,比如 3z= 直接选第三个建议。
在可视模式下先选中一段文本再按 z=,可以对选中部分做批量替换建议。
用 zg 添加到词库、用 zw 标记为错误
zg 把光标下的词标记为"好词",写入 spellfile,以后不再报错。这在遇到专有名词、项目术语、人名时特别有用。
zw 则相反,把光标下的词标记为"坏词"——即使系统词典认为它合法,也会被标红。
如果手滑加错了,撤销命令是 zug(撤销 zg)和 zuw(撤销 zw)。
注意区分大小写:zG 和 zW 是会话级的,只在当前 Vim 进程内生效,退出后丢失。zg 和 zw 则写入 spellfile,持久保存。
自定义词盘:spellfile 配置
Vim 的 spellfile 是一个纯文本文件,每行一个单词。默认路径类似 ~/.vim/spell/en.utf-8.add,命名规则是 {语言}.{编码}.add。
手动指定 spellfile:
vimset spellfile=~/.vim/spell/en.utf-8.add
这个文件可以直接编辑——想批量加词,直接往里面写就行,Vim 会在下次载入时自动编译成 .spl 格式。也可以把它加入版本控制,团队共享一份术语表。
想加载多个词盘,用逗号分隔:
vimset spellfile=~/.vim/spell/en.utf-8.add,~/.vim/spell/project.utf-8.add
zg 会把词加到第一个 spellfile 里。
另外,set complete+=kspell 可以让 Vim 在插入模式补全时也参考拼写词典,输入时按 Ctrl-N / Ctrl-P 即可触发。
多语言拼写:中英文混合场景
spelllang 支持逗号分隔的多语言列表:
vimset spelllang=en_us,zh_cn
这样中英文会同时检查。但有一个现实问题:Vim 对中文的拼写检查能力远不如英文,中文的 .spl 文件并不像英文那样有完整的词库覆盖。实际使用中,zh 的拼写检查价值有限,更多时候还是靠英文检查来抓 typo。
一个更务实的做法是只开英文检查,中文文本不会被误报(Vim 对不在词典语言范围内的文本默认不检查):
vimset spelllang=en_us
如果你的文档以英文为主、夹杂少量中文,这个配置就够了。
编程场景:只在注释和字符串中检查
写代码时,如果全局开 spell,变量名和方法名会大面积标红,很干扰。Vim 的语法系统提供了 @Spell 和 @NoSpell 两个集群(cluster),可以让拼写检查只作用于特定语法区域。
对大多数 filetype 来说,Vim 自带的语法文件已经把注释和字符串归入了 @Spell,其他区域归入 @NoSpell。所以正常情况下,在代码文件里开 set spell,只有注释和字符串会被检查,变量名不会报错。
如果你的某个 filetype 没有做好这个区分,可以在语法文件里手动调整:
vimsyntax match myComment "\/\/.*" contains=@Spell syntax match myIdent "\<\w\+\>" contains=@NoSpell
这样就能精确控制哪些区域参与拼写检查。
spellfile-plugin:自动下载词盘
Vim 自带一个 spellfile-plugin,当 spelllang 设置了一个本地没有对应 .spl 文件的语言时,这个插件会自动从 vim.org 下载。它默认是启用的。
如果因为网络问题下载失败,可以手动从 ftp://ftp.vim.org/pub/vim/runtime/spell/ 下载对应的 .spl 文件,放到 ~/.vim/spell/ 目录下。
禁用自动下载:
vimlet g:loaded_spellfile_plugin = 1
与 coc.nvim 和 nvim-lsp 的配合
Vim 内置的 spell 是基于词典的拼写检查,不依赖 LSP。但如果你还用了 coc.nvim 或 nvim-lspconfig,两者可以并行不冲突。
coc.nvim 有 coc-spell-checker 扩展,底层基于 cspell,可以检查代码中的标识符和注释拼写。它和 Vim 原生 spell 各管各的,不会互相干扰,但也会出现同一段文本两边都报错的情况。如果觉得冗余,可以关掉其中一个。
nvim-lsp 方面,有几个专门的拼写检查 Language Server:
- cspell-lsp — 基于 cspell,支持自定义词典,对代码场景优化好
- typos-lsp — 轻量快速,专注抓源码中的 typo
- ltex-ls — 基于 LanguageTool,除了拼写还检查语法,适合写文档和 Markdown
- harper-ls — 隐私友好的语法检查器,离线运行
配置示例(nvim-lspconfig + cspell):
luavim.lsp.enable("cspell_ls") vim.lsp.config("cspell_ls", { cmd = { "cspell-lsp", "--stdio" }, filetypes = { "markdown", "gitcommit", "text" }, root_markers = { ".git" }, })
实际使用建议:日常写 Markdown 和 commit message 用 Vim 内置 spell 就够了,轻量且零依赖。如果项目需要更严格的拼写检查(比如开源项目要求 CI 里也跑 cspell),再上 LSP 方案。
常用配置汇总
一段比较实用的 .vimrc 配置:
vim" 拼写检查 set spell set spelllang=en_us set spellfile=~/.vim/spell/en.utf-8.add set complete+=kspell " 只在特定文件类型开启 autocmd FileType markdown,gitcommit setlocal spell autocmd FileType python,javascript setlocal nospell " 快捷键 nnoremap <F5> :set spell!<CR> nnoremap <leader>s ]s nnoremap <leader>S [s
Vim 的拼写检查不算复杂,但覆盖面比很多人想象的广——从简单的英文纠错到多语言混合、代码注释定向检查、团队共享词盘,都能做。花五分钟配好,之后每次写文档和 commit message 都能少犯几个低级拼写错误。