{T}

开篇词:我们为什么要学 Vim?

Vim 是一款功能强大、高度可定制的文本编辑器,以高效、轻量和跨平台著称。它基于 Unix 系统的 vi 编辑器开发,但扩展了更多现代功能,成为程序员和文字工作者的首选工具之一。Vim 的核心理念是“用键盘完成一切”,虽然上手需要时间,但一旦掌握,会成为提升生产力的利器。建议从基础命令开始,逐步探索插件和配置,最终形成自己的工作流

  • 开发者:编写代码、配置文件、日志分析
  • 系统管理员:快速编辑服务器配置文件
  • 作家:通过插件支持 Markdown、LaTeX 等格式

核心特点

  1. 模式化操作

    Vim 通过不同模式区分操作:

    • 普通模式(Normal):默认模式,用于导航、复制、粘贴、删除等
    • 插入模式(Insert):输入文本(按 i 进入)
    • 可视模式(Visual):选择文本块(按 v 进入)
    • 命令模式(Command):执行命令(如保存 :w、退出 :q
    • 其他模式:如替换模式(R)、Ex 模式(Q)等
  2. 高效文本操作

    • 快捷键丰富:例如 dd 删除一行,yy 复制一行,p 粘贴,/ 搜索,:s/old/new/g 替换
    • 宏录制:通过 q 录制宏,重复复杂操作
    • 多窗口/分屏:支持垂直/水平分屏(:vsplit:hsplit),方便对比或编辑多个文件
  3. 轻量级与可扩展性

    • 无需图形界面:纯终端运行,资源占用低,适合远程服务器
    • 插件生态:通过插件(如 Vim-plug、Pathogen)扩展功能,支持语法高亮、自动补全、LSP 等
  4. 跨平台支持

    • 支持 Linux、macOS、Windows(GVim 或 WSL),配置文件可同步

基本操作示例

  • 导航hjkl 移动光标(左下右上),gg 跳到文件开头,G 跳到结尾
  • 编辑i 插入文本,x 删除字符,u 撤销,Ctrl+r 重做
  • 搜索替换/keyword 搜索,:1,10s/foo/bar/g 替换第1-10行的 foobar
  • 保存退出:w 保存,:q! 强制退出不保存,:wq 保存并退出

进阶功能

  1. 语法高亮与缩进
    • 自动识别文件类型并应用语法高亮(如 Python、C++)。
    • 智能缩进(= 命令对齐代码块)。
  2. 文件管理
    • 内置文件浏览器(:Explore),或集成插件(如 NERDTree)。
  3. 版本控制集成
    • 通过插件(如 fugitive.vim)直接操作 Git。
  4. 终端集成
    • 在 Vim 中打开终端(:terminal),适合调试或运行命令。

学习资源

  • 官方文档:help 命令内置详细帮助
  • 教程:
    • Vim Adventures(游戏化学习)
    • Vimcasts(视频教程)
  • 书籍:《Practical Vim》《Modern Vim》

优缺点

  • 优点:
    • 极致高效(熟练后操作速度远超鼠标)
    • 轻量级,适合远程开发
    • 高度可定制(.vimrc 配置文件)
  • 缺点:
    • 学习曲线陡峭,初期可能不适应模式切换
    • 图形界面功能较弱(需依赖插件或 GVim)

安装

Linux 安装

在 Red Hat Linux 和 CentOS Linux 上,默认安装的 Vim 可能是一个最小功能的版本。虽然这个版本启动速度很快,但它缺少了很多对开发有用的功能,如语法加亮、Python 集成和图形界面。一般情况下,应至少安装更全功能版本的 Vim;如果能使用 X Window 的话,则应安装图形界面版本

可以通过下面的命令来查看已经安装的 Vim 版本:

bash
# 查看已经安装的 Vim 版本
yum list installed | grep vim
 
# 输出如下
vim-common.x86_64                      2:8.2.2637-21.el9           @appstream       
vim-enhanced.x86_64                    2:8.2.2637-21.el9           @appstream       
vim-filesystem.noarch                  2:8.2.2637-21.el9           @baseos          
vim-minimal.x86_64                     2:8.2.2637-21.el9           @baseos 

如果输出只有下面这样的内容的话,就说明安装的 Vim 版本只有基本功能:

vim-minimal.x86_64 2:8.0.1763-13.el8 @System

DANGER

建议使用 sudo yum install vim-X11 来安装图形界面的 Vim,或至少使用 sudo yum install vim-enhanced 来安装增强版本的 Vim

图形界面 Vim 的功能更丰富,并且即使你只在终端里使用 Vim,含图形界面支持的 Vim 会带剪贴板支持,跟整个图形环境的交互也就比较容易。但只是远程通过 SSH 使用 Vim 的话,那确实图形界面支持就没有意义了

macOS 安装

在 macOS 中一般已经内置 vim,并提供了除图形界面外的较完整功能集。如果希望使用图形界面,则需要自行安装 MacVim

  • 使用 Homebrew。推荐使用这种方式,后面升级也会比较容易
  • 使用 MacVim 的独立安装包

使用 Homebrew 安装:

bash
brew install macvim
 
# 升级的命令
brew upgrade macvim
 
# 卸载
brew uninstall macvim
 
mvim --version
 
# 使用
mvim  /Users/XXX/Desktop/123.txt
 
# 启动 MacVim
mvim

Windows 安装

Windows 上默认是没有 Vim 的,可以从 Vim 的网站下载 Windows 下的安装包:https://www.vim.org/download.php#pc

安装界面会有一个选择组件的步骤,如下图所示:

<img src="https://zhangzhengyang.oss-cn-beijing.aliyuncs.com/images/202505211839129.png" alt="image-20250521183927377" style="zoom:50%;" />

在界面中有几项可以关注一下:

  • 安装批处理文件:对于用 Vim 的开发者来说,通常命令行是刚需,所以一般需要勾上这项。
  • 创建图标:通常不选
  • 创建默认配置文件:去掉这项——马上会创建配置文件
  • 安装多语言支持:不选

然后点 下一步,不需要修改安装目标文件夹,完成安装即可。使用 gvim 命令打开图形界面,保存使用的 ZZ

基本概念

Vim 键盘位

图中的 表示,单个字母不是完整的命令,必须再有进一步的输入。比如单个 g 没有意义,而 gg 表示跳转到文件开头。一个键最多有三排内容:最底下是直接按键的结果,中间是按下 Shift 的结果(变大写),上面偏右的小字是按下 Ctrl 的结果。还用了一些特殊符号来表示操作的位置,如果你已经了解了这些命令的功能,你也自然就明白它们的意义了

76910d1a16ed737c42078dd1255124a1

这张图里没有写出 Vim 的命令行命令,此时应该已经掌握了以下这些:

命令描述
:q!退出 Vim(不保存)
:wq存盘并退出 Vim
:s执行替换
:!执行外部命令
:edit编辑文件(可缩写为 :e
:w写文件(保存)
:r读文件
:help查看帮助
Ctrl-D命令行补全(向下补全)
Tab命令行补全

Vim 四种模式

进入 Vim 后默认状态下键入的字符并不会插入到所编辑的文件之中,Vim 有以下四种主要模式:

  • 正常(normal)模式(也称为普通模式),默认的编辑模式。在任何其他模式中,通过键盘上的 Esc 键回到正常模式
  • 插入(insert)模式,输入文本时使用;比如在正常模式下键入 i(insert)或 a(append)即可进入插入模式
  • 可视(visual)模式,用于选定文本块;用键 v(小写)来按字符选定,Vim 里也提供其他不同的选定方法,包括按行和按列块
  • 命令行(command-line)模式,用于执行较长、较复杂的命令;在正常模式下键入冒号 : 即可进入该模式;使用斜杠(/)和问号(?)开始搜索也算作命令行模式。命令行模式下的命令要输入回车键(Enter)才算完成

Vim 里的大部分操作会在正常模式下完成。如果你做编辑工作时有超过几秒的停顿,就应当考虑按下 Esc 键,回到正常模式

Vim 键描述体例

使用 Vim 里的标准键描述方式来讲解。根据 Vim 的一般习惯,使用尖括号来描述特殊的输入序列。下面我会提供一个列表,给出常用键的表示方式及在动图中的显示方式。这部分内容不需要记住,你用的时候作为参考就行

  • <Esc> 表示 Esc 键;显示为“⎋”
  • <CR> 表示回车键;显示为“↩”
  • <Space> 表示空格键;显示为“␣”
  • <Tab> 表示 Tab 键;显示为“⇥”
  • <BS> 表示退格键;显示为“⌫”
  • <Del> 表示删除键;显示为“⌦”
  • <lt> 表示 < 键;显示为“<”
  • <Up> 表示光标上移键;显示为“⇡”
  • <Down> 表示光标下移键;显示为“⇣”
  • <Left> 表示光标左移键;显示为“⇠”
  • <Right> 表示光标右移键;显示为“⇢”
  • <PageUp> 表示 Page Up 键;显示为“⇞”
  • <PageDown> 表示 Page Down 键;显示为“⇟”
  • <Home> 表示 Home 键;显示为“↖”
  • <End> 表示 End 键;显示为“↘”
  • <F1> - <F12> 表示功能键 1 到 12;显示为“F1”到“F12”
  • <S-…> Shift 组合键;显示为“⇧”(较少使用,因为我们需要写 ! 而不是 <S-1>;和特殊键组合时仍然有用)
  • <C-…> Control 组合键;显示为“⌃”
  • <M-…> Alt 组合键;显示为“⌥”(对于大部分用户,它的原始键名 Meta 应该只具有历史意义)
  • <D-…> Command 组合键;显示为“⌘”(Mac 键盘)

现在回到前面的模式部分,提到的 Esc、Enter、v、V 和 Ctrl-V,按现在的描述惯例,以后就会写成 <Esc><CR>vV<C-V>。这也是以后在 Vim 里对键进行重映射的写法

INFO

这里我要强调一下,对“ <”的特殊解释仅在描述输入时生效。在描述命令行和代码时,我们写“ <CR>”仍表示四个字符,而非回车键。特别是,如果我们描述的命令行首是“:”,表示这是一个输入 : 开始的 Vim 命令行模式命令(以回车键结束);如果行首是“/”或“?”,表示这是一个输入 /? 开始的搜索命令(以回车键结束);如果行首是“ $”,表示这是一个在 shell 命令行上输入的命令(以回车键结束),“ $”(和后面的空格)不是命令的一部分,通常后续行也不是命令的一部分,除非行尾有“\”或“^”字符,或行首有“ $”字符

也就是说,下面的命令是在 Vim 里输入“ :set ft?<CR>”(用来显示当前编辑文件的文件类型):

bash
# 在 vim 命令行输入 :set ft?,显示当前编辑文件的文件类型
:set ft?

在终端输入 which vim(用来检查 vim 命令的位置):

text
$ which vim
/usr/local/bin/vim

Vim 选项和配置

在配置文件中加入下面的代码。根据 Unix 下的惯例,Vim 的配置文件放在用户的主目录下,文件名通常是 .vimrc;而它在 Windows 下名字是 _vimrc

bash
set enc=utf-8
set nocompatible
source $VIMRUNTIME/vimrc_example.vim

上面三行代码完成了下列功能:

  • 设置编辑文件的内码是 UTF-8
  • 设置 Vim 不需要和 vi 兼容(仅为万一起见,目前大部分情况下这是默认的情况)
  • 导入 Vim 的示例配置(这会打开一些有用的选项,如语法加亮、搜索加亮、命令历史、记住上次的文件位置,等等)

如果 ~/.vimrc 不存在,可以通过以下命令创建并编辑:

bash
touch ~/.vimrc  # 创建文件
vim ~/.vimrc    # 用 Vim 编辑

备份和撤销文件

不产生备份文件,但保留跨会话撤销编辑的能力;因为有了撤销文件,备份其实也就没有必要了。同时,把撤销文件放在用户个人的特定目录下,既保证了安全,又免去了其他目录下出现不必要文件的麻烦

要达到这个目的在 Linux/macOS 下会这么写:

bash
set enc=utf-8
source $VIMRUNTIME/vimrc_example.vim
 
 
set nobackup       " 禁用传统备份文件(.bak)
set nowritebackup  " 写入文件时不创建临时备份
set noswapfile     " 禁用交换文件(.swp)
 
if has('persistent_undo')
  set undofile
  set undodir=~/.vim/undodir
  if !isdirectory(&undodir)
    call mkdir(&undodir, 'p', 0700)
  endif
endif

Windows 下这么写:

bash
set enc=utf-8
source $VIMRUNTIME/vimrc_example.vim
 
set fileencodings=ucs-bom,utf-8,gb18030,latin1
set nobackup
 
if has('persistent_undo')
  set undofile
  set undodir=~/.vim/undodir
  if !isdirectory(&undodir)
    call mkdir(&undodir, 'p', 0700)
  endif
endif

验证 set nobackup

这条配置的作用是禁用 Vim 的备份文件(.swp.bak 文件)

验证方法:打开 Vim 并编辑一个文件:

bash
vim test.txt
  1. 在 Vim 中输入一些内容并保存(:w)。

  2. 检查当前目录是否生成 .swp.bak

    bash
    ls -a  # 查看隐藏文件
    • 如果配置生效:不会看到 .swp.bak 文件
    • 如果看到备份文件:说明配置未生效,检查 ~/.vimrc 是否被正确加载(见下文排查方法)

验证 undodir 和自动创建目录

这条配置的作用是:

  • 设置撤销文件(undo history)的存储目录为 ~/.vim/undodir
  • 如果目录不存在,则自动创建它(权限为 0700

检查目录是否存在

bash
ls -ld ~/.vim/undodir
  • 如果目录存在,说明 mkdir 命令生效
  • 如果目录不存在,可能是 Vim 没有正确加载配置
  1. 测试撤销功能
    • 在 Vim 中编辑文件并保存后 :w,尝试撤销操作(:uu
    • 如果撤销功能正常,说明 undodir 配置生效(即使目录为空,Vim 也会按需创建撤销文件)

鼠标支持

根据运行环境动态启用鼠标支持

bash
if has('mouse')  " 检查 Vim 是否支持鼠标功能
  if has('gui_running') || (&term =~ 'xterm' && !has('mac'))  " 条件判断
    set mouse=a  " 启用所有鼠标操作(a=所有模式)
  else
    set mouse=nvi  " 仅允许在普通模式(n)、可视模式(v)、插入模式(i)中使用鼠标
  endif
endif

Vim 中运行输出应为 mouse=amouse=nvi

python
:set mouse?

Vim 目录结构

Vim 的运行支持文件在不同的平台上有着相似的目录结构。以 Vim 9.1 为例,它们的标准安装位置分别在:

  • 大部分 Unix 下面:/usr/share/vim/vim91
  • macOS Homebrew 下:/usr/local/opt/macvim/MacVim.app/Contents/Resources/vim/runtime
  • Windows 下:C:\\Program Files (x86)\\Vim\\vim91

在安装目录下面有很多子目录,如 autoloadcolorsdocpackpluginsyntax 等等。这些子目录下面就是分类放置的 Vim 支持文件。最常用的子目录应该是下面这几个:

  • syntaxVim 的语法加亮文件
  • docVim 的帮助文件
  • colorsVim 的配色方案
  • pluginVim 的“插件”,即用来增强 Vim 功能的工具

在图形界面的 Vim 里,可以通过“语法 > 在菜单中显示文件类型”来展示 Vim 的所有文件类型,然后可以选择某一类型来对当前文件进行设置。这里的菜单项,跟 syntax 目录下的文件就基本是一一对应

单文件操作

图形界面

使用图形界面,可以在操作系统的资源管理器里进入到合适的目录,然后逐个使用 Vim 来打开文件。可以直接把文件拖拽到 Vim 里、使用 “文件 > 打开” 菜单当然也是一种选择。

使用这几种编辑方式的话,可以把需要粘贴的内容放到操作系统的剪贴板里,然后在图形界面的 Vim 里用以下方法之一粘贴进去:

  • 正常模式 Vim 命令 "+P(意义我们后面再解释)
  • 快捷键 <D-V>(提醒:这是我们对 ⌘V 的标记方式;仅适用于 macOS)或 <S-Insert>(PC 键盘)
  • 鼠标右键加“粘贴”(Paste)
  • 菜单“编辑 > 粘贴”(Edit > Paste)

注意,如果你通常使用 Ctrl-V 键粘贴的话,这个快捷键在 Vim 里并不适用。即使你使用的是图形界面的 Vim 也是如此,因为这个键在 Vim 里有其他用途。顺便说一句,这个键在 Unix 终端上也一样是不能用作粘贴的。

终端 Vim

如果直接把图形界面下的基本步骤,翻译成终端 Vim(非图形界面)的用法的话,应该是这样子的:

  1. 在终端里进入到目标目录下
  2. 使用 vim 文件名 来逐一打开需要编辑的文件
  3. 如果光标不在开头的话,用鼠标或 gg 命令跳转到开头
  4. 使用命令 i 进入插入模式
  5. 使用终端窗口的粘贴命令或快捷键(如 <S-Insert>)来粘贴内容
  6. <Esc> 回到正常模式并用保存退出

已经存在交换文件!

对每个文件单独使用一个 Vim 会话来编辑,很容易出现冲突的情况,迟早会遇到“已经存在交换文件!”(Swap file “…” already exists!)的错误提示。出现这个提示,有两种可能的原因:

  1. 你上次编辑这个文件时,发生了意外崩溃
  2. 你已经在使用另外一个 Vim 会话编辑这个文件

原因不同,处理的策略自然也不相同。当进程 ID(process ID)后面没有 “STILL RUNNING” 这样的字样时,那就是情况 1;否则,就是情况 2

  1. 若无"STILL RUNNING" → 文件因崩溃未正常关闭
    • r 恢复编辑 → 保存后 → 再次打开需手动删除交换文件 d
    • 或直接 d 跳过
  2. 若有"STILL RUNNING" → 文件已被其他Vim会话打开
    • 通常用 q/a 放弃当前编辑(少数情况用 o 只读查看)
    • 强制编辑(e)需谨慎(仅确认无冲突时使用)