Vim 使用指南
在服务器上改配置文件、在终端里写 Git 提交信息,经常会进入 Vim。Vim 的操作方式和普通编辑器不同:大部分时间不是在“打字”,而是在用按键组合“操作文本”。这篇从模式讲起,整理最常用的移动、编辑、搜索替换和多窗口操作,再介绍寄存器和宏,最后给出一份基础配置。
vim file.txt # 打开文件,不存在则新建vim +25 file.txt # 打开并跳到第 25 行vim -O a.txt b.txt # 左右分屏打开两个文件vimtutor # Vim 自带的交互式教程,约半小时,强烈推荐退出相关命令(在普通模式下输入):
| 命令 | 作用 |
|---|---|
:w |
保存 |
:q |
退出(有未保存修改时会拒绝) |
:wq 或 :x |
保存并退出(:x 只在有修改时写入) |
:q! |
放弃修改强制退出 |
:wa / :qa |
保存全部 / 退出全部 |
:w !sudo tee % |
忘了用 sudo 打开只读文件时,借助 tee 以 root 身份写入 |
| 模式 | 进入方式 | 用途 |
|---|---|---|
| 普通模式(Normal) | 启动后默认;在其他模式按 Esc 返回 |
移动光标、删除、复制、粘贴等操作 |
| 插入模式(Insert) | i、a、o 等 |
输入文本 |
| 可视模式(Visual) | v、V、Ctrl-v |
选中文本后再操作 |
| 命令行模式(Command-line) | :、/、? |
执行命令、搜索 |
进入插入模式的几种方式:
| 按键 | 位置 |
|---|---|
i / a |
光标前 / 光标后插入 |
I / A |
行首(第一个非空字符) / 行尾插入 |
o / O |
在下方 / 上方新开一行插入 |
可视模式:v 按字符选择,V 按行选择,Ctrl-v 按列(矩形块)选择。选中后可以用 d 删除、y 复制、> 缩进等。块选择模式下按 I 输入文字再按 Esc,可以同时在多行前插入相同内容,常用于批量加注释。
普通模式下:
| 按键 | 移动到 |
|---|---|
h j k l |
左、下、上、右 |
w / b / e |
下一个单词开头 / 上一个单词开头 / 单词结尾 |
W / B / E |
同上,但以空白分隔“单词”(跳过标点) |
0 / ^ / $ |
行首 / 行首第一个非空字符 / 行尾 |
gg / G |
文件开头 / 文件结尾 |
25G 或 :25 |
第 25 行 |
Ctrl-d / Ctrl-u |
向下 / 向上翻半页 |
Ctrl-f / Ctrl-b |
向下 / 向上翻一页 |
% |
跳到匹配的括号 |
f{字符} / t{字符} |
在当前行向右跳到某字符上 / 该字符前;; 重复,, 反向重复 |
* / # |
向下 / 向上搜索光标下的单词 |
Ctrl-o / Ctrl-i |
跳回上一个位置 / 跳到下一个位置 |
大多数移动命令前可以加数字表示重复次数,如 5j 向下移动 5 行,3w 向后移动 3 个单词。
操作符 + 动作
Section titled “操作符 + 动作”Vim 编辑命令的核心语法是 操作符 + 动作(或文本对象):
| 操作符 | 作用 |
|---|---|
d |
删除(删除的内容会进入寄存器,相当于剪切) |
c |
修改:删除后进入插入模式 |
y |
复制(yank) |
> / < |
增加 / 减少缩进 |
= |
自动缩进 |
gu / gU |
转小写 / 转大写 |
把操作符和前面的移动组合起来:
dw 删除到下一个单词开头d$ 删除到行尾(等同于 D)dgg 删除到文件开头c3w 修改接下来 3 个单词yG 复制到文件结尾>j 当前行和下一行增加缩进操作符连按两次表示作用于整行:dd 删除一行,yy 复制一行,cc 修改一行,>> 缩进一行。前面加数字,如 3dd 删除 3 行。
文本对象让你不必把光标移到开头就能操作一整块内容,格式是 i(inner,不含边界)或 a(around,含边界)加对象类型:
| 命令 | 作用 |
|---|---|
diw / daw |
删除当前单词 / 删除单词及其后的空格 |
ci" |
修改双引号内的内容 |
da( 或 dab |
删除包括括号在内的整个括号块 |
yi{ |
复制花括号内的内容 |
cit |
修改 HTML 标签内的内容 |
dip |
删除当前段落 |
比如光标在 fetch("/api/user") 的引号内任意位置,输入 ci" 就能直接改写 URL。
其他常用编辑命令
Section titled “其他常用编辑命令”| 按键 | 作用 |
|---|---|
x |
删除光标下的字符 |
r{字符} |
把光标下的字符替换为指定字符 |
p / P |
在光标后 / 前粘贴 |
u |
撤销 |
Ctrl-r |
重做 |
. |
重复上一次修改操作 |
J |
把下一行合并到当前行 |
~ |
切换光标下字符的大小写 |
. 是 Vim 中最有用的命令之一:比如用 ciw 改了一个单词,移动到另一个单词上按 . 就能做同样的修改。
/pattern 向下搜索?pattern 向上搜索n / N 跳到下一个 / 上一个匹配搜索默认区分大小写,在模式后加 \c 可以忽略大小写,如 /error\c。
替换命令的格式是 :[范围]s/查找/替换/[标志]:
:s/foo/bar/ 当前行第一个 foo 替换为 bar:s/foo/bar/g 当前行所有 foo:%s/foo/bar/g 整个文件:%s/foo/bar/gc 整个文件,每处替换前确认(y 替换,n 跳过,a 全部,q 退出):10,20s/foo/bar/g 第 10 到 20 行:'<,'>s/foo/bar/g 可视模式选中的范围(选中后按 : 会自动填入 '<,'>):%s/\s\+$//e 删除所有行尾空白,e 表示没有匹配时不报错查找内容中包含 / 时,可以换用其他分隔符,比如 :%s#/old/path#/new/path#g。
:g 命令对匹配的行执行命令:
:g/console.log/d 删除所有包含 console.log 的行:v/TODO/d 删除所有不包含 TODO 的行多文件与窗口
Section titled “多文件与窗口”Vim 中每个打开的文件都是一个缓冲区(buffer):
:e path/to/file 打开文件:ls 列出缓冲区:bn / :bp 下一个 / 上一个缓冲区:b 2 切换到 2 号缓冲区:bd 关闭当前缓冲区:sp file 水平分屏打开(上下排列):vs file 垂直分屏打开(左右排列)Ctrl-w h/j/k/l 移动到左 / 下 / 上 / 右侧的窗口Ctrl-w w 在窗口之间循环切换Ctrl-w = 所有窗口等宽等高Ctrl-w q 关闭当前窗口:only 只保留当前窗口:tabnew file 在新标签页打开gt / gT 下一个 / 上一个标签页:tabclose 关闭标签页寄存器与宏入门
Section titled “寄存器与宏入门”复制和删除的内容存放在寄存器中,用 " 加寄存器名指定:
| 寄存器 | 说明 |
|---|---|
"" |
默认寄存器,最近一次删除或复制的内容 |
"0 |
最近一次复制(yank)的内容,不会被删除操作覆盖 |
"a 到 "z |
命名寄存器,供自己使用 |
"+ |
系统剪贴板(需要 Vim 编译时支持 clipboard) |
"_ |
黑洞寄存器,写入的内容直接丢弃 |
"ayy 把当前行复制到寄存器 a"ap 粘贴寄存器 a 的内容"+y 复制到系统剪贴板"_dd 删除一行但不影响默认寄存器"0p 粘贴最近一次复制的内容(即使之后又删除过东西):reg 查看所有寄存器的内容一个常见困扰:复制了一段文字,接着删除了别的内容想替换,结果粘贴出来的是刚删掉的内容。这时用 "0p 就能粘贴之前复制的内容。
插入模式下按 Ctrl-r 再按寄存器名,可以插入寄存器的内容。
宏就是把一串按键录制到寄存器中,然后重复播放,适合处理大量格式相同的行:
qa 开始录制到寄存器 a... 执行一系列操作q 停止录制@a 播放一次@@ 重复上一次播放的宏10@a 播放 10 次示例:把下面几行改成 JS 对象属性格式。
nameageemail把光标放在第一行,依次输入:qa(开始录制)、I(行首插入)、输入 、Esc、A(行尾插入)、输入 : '',、Esc、j(移到下一行)、q(结束录制)。然后 2@a 处理剩下两行,结果:
name: '', age: '', email: '',录制宏时尽量使用相对移动(w、f、0、$),让宏在不同长度的行上都能正确执行。
常用 .vimrc 配置
Section titled “常用 .vimrc 配置”用户配置文件是 ~/.vimrc(Neovim 使用 ~/.config/nvim/init.vim 或 init.lua)。系统级配置的位置因发行版而异,比如 Debian/Ubuntu 是 /etc/vim/vimrc,一般不建议修改系统级配置,写在自己的 ~/.vimrc 中即可。
" 基础set nocompatible " 不兼容旧版 vi 的行为syntax on " 语法高亮filetype plugin indent on " 按文件类型加载插件和缩进规则set encoding=utf-8
" 界面set number " 显示行号set relativenumber " 显示相对行号,方便 5j 这类跳转set cursorline " 高亮当前行set showcmd " 右下角显示正在输入的命令set scrolloff=5 " 光标上下保留 5 行
" 缩进set expandtab " Tab 转为空格set tabstop=2 " Tab 显示宽度set shiftwidth=2 " 自动缩进宽度set autoindent
" 搜索set hlsearch " 高亮搜索结果set incsearch " 边输入边搜索set ignorecase " 搜索忽略大小写set smartcase " 搜索词含大写字母时区分大小写
" 其他set backspace=indent,eol,start " 允许退格删除缩进、换行set clipboard=unnamedplus " 默认使用系统剪贴板(需 clipboard 支持)set mouse=a " 启用鼠标set undofile " 持久化撤销历史
" 快捷键:空格作为 leader 键let mapleader = " "nnoremap <leader>w :w<CR>nnoremap <leader>h :nohlsearch<CR>nnoremap 定义普通模式下的非递归映射,比 nmap 更安全,推荐总是使用 noremap 系列。修改配置后可以在 Vim 中执行 :source ~/.vimrc 立即生效。
需要插件时,可以使用 Vim 8 起自带的 package 机制,或 vim-plug 等插件管理器。如果想把 Vim 当成日常主力编辑器,可以考虑 Neovim,或在 VS Code 中安装 Vim 插件,在熟悉的环境里使用 Vim 的按键方式。
- 普通模式用来操作,插入模式用来输入,可视模式用来选择,命令行模式用来执行命令;不确定在哪个模式就按
Esc。 - 编辑命令遵循“操作符 + 动作/文本对象”,如
dw、ci"、yip;操作符连按两次作用于整行。 .重复上一次修改,u撤销,Ctrl-r重做。- 替换用
:%s/查找/替换/gc,:g对匹配行批量执行命令。 - 分屏用
:sp、:vs和Ctrl-w系列;"0p粘贴最近复制的内容,qa ... q录制宏,@a播放。 - 个人配置写在
~/.vimrc,映射优先使用noremap系列。