虽说已经用了很久的vi,可是对于vi不同功能的熟练程度是不同的,这意味着有时会忘掉某些操作而需要查阅相关信息。此时若是手边没有参考书,就非常令人抓狂,只好去网上进行搜索。既然如此,那就花点时间整理下吧,查阅起来应该方便不少。我个人习惯是把vi和vim混在一起统称为vi的,因此尽管标题是“Vi 备忘录”,但其实也包含了vim的功能。
Vi 的简介
Vi 的基本模式
使用 vi 时主要有四种模式:一般模式、插入模式、命令行模式、可视化模式。一般模式 下可以快速浏览文本,插入模式 下可以自由编辑文本,命令行模式 下可以进行搜索、保存等特殊操作,可视化模式 下可以进行块操作。
Vi 的特性
未完待续
Vi 命令快速查询
这里根据各命令的功能进行归类总结。值得注意的是,许多命令都可以在前面加上数字n,来完成n次操作;也可以进行 操作+移动 的组合,来进行快速操作,如 d$ 。
移动光标
| 操作 | 功能 |
|---|---|
| (n)h 或 (n)← 或 (n)[Backspace] 或 (n)[Ctrl]h | 向左移动一(n)个字符 |
| (n)j 或 (n)↓ 或 (n)[Ctrl]n 或 (n)[Ctrl]j | 向下移动一(n)行 |
| (n)k 或 (n)↑ 或 (n)[Ctrl]p | 向上移动一(n)行 |
| (n)l 或 (n)→ 或 (n)[space] | 向右移动一(n)个字符 |
| (n)[Ctrl]f 或 (n)[Page Down] | 向下移动一(n)页 |
| (n)[Ctrl]b 或 (n)[Page Up] | 向上移动一(n)页 |
| (n)[Ctrl]d | 向下移动半页(n行) |
| (n)[Ctrl]u | 向上移动半页(n行) |
| (n)[Ctrl]e | 向下滚动一(n)行 |
| (n)[Ctrl]y | 向上滚动一(n)行 |
| 0 或 [Home] | 移动至当前行行首 |
| (n)$ 或 (n)[End] | 移动至当前行(向下第n行)行尾 |
| ^ 或 _ | 移动至当前行的非空格行首 |
| (n)+ 或 (n)[Enter] 或 (n)[Ctrl]m | 移动至下一(n)行的非空格行首 |
| (n)- | 移动至上一(n)行的非空格行首 |
| (n)zt 或 (n)z[Enter] | 将当前(第n)行滚动至屏幕顶部 |
| (n)zz 或 (n)z. | 将当前(第n)行滚动至屏幕中间 |
| (n)zb 或 (n)z- | 将当前(第n)行滚动至屏幕底部 |
| [Ctrl]o | 移动至较早的位置 |
| (n)| | 移动至当前行第一(n)列 |
| ( | 移动至上一个句子的开头 |
| ) | 移动至下一个句子的开头 |
| { | 移动至上一个段落 |
| } | 移动至下一个段落 |
| [[ | |
| ]] | |
| (n)H | 移动至屏幕第一(n)行的非空格行首 |
| M | 移动至屏幕中间行的非空格行首 |
| (n)L | 移动至屏幕倒数第一(n)行的非空格行首 |
| (n)w | 移动至下一(n)个单词词首 |
| (n)e | 移动至下一(n)个单词词尾 |
| (n)b | 移动至上一(n)个单词词首 |
| (n)ge | 移动至上一(n)个单词词尾 |
| (n)W | 移动至下一(n)个单词词首,跳过标点符号 |
| (n)E | 移动至下一(n)个单词词尾,跳过标点符号 |
| (n)B | 移动至上一(n)个单词词首,跳过标点符号 |
| (n)gE | 移动至上一(n)个单词词尾,跳过标点符号 |
| G | 移动至最后一行 |
| nG | 移动至第n行 |
| gg | 移动至第一行 |
| f[char] | 移动至当前行下一个字符char |
| F[char] | 移动至当前行上一个字符char |
| t[char] | 移动至当前行下一个字符char的前一个字符 |
| T[char] | 移动至当前行上一个字符char的后一个字符 |
| ; | 执行上一次的[fFtT] |
| , | ;的反向,;为[fFtT]则,为[FfTt] |
| % | 移动至与当前括号匹配的括号,包括()、[]、{}、<>等 |
| n% | 移动至文件n%处 |
删除
使用 d 进行删除时,可以通过 (n1)d(n2)[CursorMove] 的形式将 d 与光标移动 [CursorMove] 进行组合,对当前位置至目标位置间的字符进行删除,并且利用n1、n2来进行多次操作。
列举部分有关 d 的操作,未列举的可参考 光标移动 部分的内容。
| 操作 | 功能 |
|---|---|
| (n)dd 或 d(n)d | 向下删除一(n)行(从当前行开始计算) |
| dG | 删除当前行至最后一行 |
| dnG | 删除当前行至第n行 |
| dgg | 删除当前行至第1行 |
| d0 | 删除当前光标至行首 |
| d$ 或 D | 删除当前光标至行尾 |
| (n)dw 或 d(n)w | 从当前光标开始向后删除至下一(n)个单词词首前 |
| (n)de 或 d(n)e | 从当前光标开始向后删除至下一(n)个单词词尾后 |
| (n)db 或 d(n)b | 从当前光标开始向前删除至上一(n)个单词词首前 |
| (n)dge 或 d(n)ge | 从当前字符后开始向前删除至上一(n)个单词词尾前 |
| (n1)d(n2)[w/e/b/ge] | 同上,但处理n1×n2个单词 |
| daw | 从单词开头开始向后删除至下一个单词词首前(不确定) |
| diw | |
| das | |
| dis | |
| df[char] | 删除至当前行下一个字符char |
| dF[char] | 删除至当前行上一个字符char |
| dt[char] | 删除至当前行下一个字符char的前一个字符 |
| dT[char] | 删除至当前行上一个字符char的后一个字符 |
| (n)d/string 或 d(n)/string | 向下搜索字符串string,并从当前光标开始向后删除至下一个string前 |
| (n)d?string 或 d(n)?string | 向上搜索字符串string,并从当前光标开始向前删除至下一个string前 |
| [Del] | 向后删除一个字符 |
| (n)x | 向后删除一(n)个字符 |
| (n)X | 向前删除一(n)个字符 |
复制
使用 y 进行删除时,可以通过 (n1)y(n2)[CursorMove] 的形式将 y 与光标移动 [CursorMove] 进行组合,对当前位置至目标位置间的字符进行删除,并且利用n1、n2来进行多次操作。
列举部分有关 y 的操作,未列举的可参考 光标移动 部分和 删除 部分的内容。
| 操作 | 功能 |
|---|---|
| (n)yy 或 (n)Y | 向下复制一(n)行(从当前行开始计算) |
| yG | 复制当前行至最后一行 |
| ynG | 复制当前行至第n行 |
| ygg | 复制当前行至第1行 |
| y0 | 复制当前光标至行首 |
| y$ | 复制当前光标至行尾 |
| (n)yw 或 y(n)w | 从当前光标开始向后复制至下一(n)个单词词首前 |
| (n)ye 或 y(n)e | 从当前光标开始向后复制至下一(n)个单词词尾后 |
| (n)yb 或 y(n)b | 从当前光标开始向前复制至上一(n)个单词词首前 |
| (n)yge 或 y(n)ge | 从当前字符后开始向前复制至上一(n)个单词词尾前 |
| yaw | |
| y/string | |
| y?string |
修改
| 操作 | 功能 |
|---|---|
| (n)J | 删除换行符,连接下一(n)行与当前行 |
| (n)p | 将已复制或删除的内容粘贴一(n)份至下一行或当前字符后 |
| (n)P | 将已复制或删除的内容粘贴一(n)份至上一行或当前字符前 |
| (n)u | 撤销一(n)次操作 |
| U | 恢复上一次修改行的所有修改 |
| (n)[Ctrl]r | 恢复一(n)次撤销 |
| . | 重复上一个操作 |
| (n)>> 或 >(n)> | 将当前行(向下n行)向右移动shiftwidth的距离 |
| (n)<< 或 <(n)< | 将当前行(向下n行)向左移动shiftwidth的距离 |
| (n)~ | 更改一(n)个字母的大小写,并向后移动一(n)个字符 |
| (n)[Ctrl]a | 使当前数字加一(n) |
插入
| 操作 | 功能 |
|---|---|
| (n)i | 从当前光标插入(重复n次) |
| (n)I | 从行首插入(重复n次) |
| (n)a | 从当前光标下一个字符后插入(重复n次) |
| (n)A | 从行尾插入(重复n次) |
| (n)o | 从下一行插入新行(重复n次) |
| (n)O | 从上一行插入新行(重复n次) |
| (n)r | 单次替换一(n)个字符 |
| R | 多次替换字符 |
| (n)cc 或 c(n)c 或 (n)S | 向下删除一(n)行,并从新行插入(从当前行开始计算) |
| (n)cw 或 c(n)w | 从当前光标开始向后删除至下一个单词词尾,并从当前光标插入 |
| (n)ce 或 c(n)e | 同上 |
| (n)cb 或 c(n)b | |
| caw | 从单词开头开始向后删除至下一个单词词首,并从当前光标插入(不确定) |
| c0 | 删除当前光标至行首,并从当前光标插入 |
| c$ 或 C | 删除当前光标至行尾,并从当前光标插入 |
| c/string | |
| c?string | |
| (n)s | 删除一(n)个字符,并从当前光标插入 |
块选取
进入块选取后可以使用移动光标的快捷键来快速选取
| 操作 | 功能 |
|---|---|
| v | 按字符进行块选取 |
| V | 按行进行块选取 |
| [Ctrl]v | 按矩形进行块选取 |
| y | 块选取后复制反白区域 |
| d | 块选取后删除反白区域 |
| c | 按矩形进行块选取后,替换反白区域 |
| ~ | 更改泛白区域的字母大小写 |
标记
可以对特定位置进行标记,以达到快速访问与跳转的目的。
| 操作 | 功能 |
|---|---|
| m[mark] | 将当前行设置标记[mark],[mark]取为[a-z] |
| y’[mark] | 复制标记为[mark]的行至当前行之间的内容 |
| d’[mark] | 删除标记为[mark]的行至当前行之间的内容 |
| ‘[mark] | 移动至标记[mark]所在行的非空格行首 |
| ‘’ 或 ‘` | 移动至上一行的非空格行首 |
| `[mark] | 移动至标记[mark]所在行的具体位置 |
| `` 或 `‘ | 移动至上一行的具体位置 |
| ‘. | |
| `. | |
| :marks | 查看所有标记 |
宏与寄存器
将一系列操作以宏的形式保存至寄存器中,以达到快速执行重复操作的目的。
| 操作 | 功能 |
|---|---|
| q[register]和q | 将一系列操作设置为宏存至寄存器[register],[register]取为[a-z] |
| “[register]yy | 复制当前行至[register]中 |
| “[register]dd | 删除当前行至[register]中 |
| “[register]p | 复制[register]内容至下一行 |
| (n)@[register] | 执行一(n)次寄存器[register]内的宏 |
| @@ | 执行上一次执行的宏(只执行一次,不论上一次执行了多少次) |
标签
未完待续
插入模式
| 操作 | 功能 |
|---|---|
| [Ctrl]n | 输入提示与自动补全(向下) |
| [Ctrl]p | 输入提示与自动补全(向上) |
| [Ctrl]e | 逐个字符复制下一行 |
| [Ctrl]y | 逐个字符复制上一行 |
| [Ctrl]o | 临时切换至一般模式 |
| [Esc] 或 [Ctrl][ | 插入模式切换至一般模式 |
| [Backspace] 或 [Ctrl]h | 插入模式中向左删除一个字符 |
文件操作
| 操作 | 功能 |
|---|---|
| :w | 保存文件 |
| :w >> [file] | 以追加的形式保存文件至[file] |
| :w! | 强制保存文件 |
| :q | 退出文件(要求修改已保存) |
| :q! | 退出但不保存 |
| :wq | 保存后退出 |
| :w [file] | 另存为[file] |
| ZZ | 若文件无改动则不保存退出,若文件被改动则保存后退出 |
| :r [file] | 在下一行插入[file]的内容 |
| :n r [file] | 在第n行的下一行插入[file]的内容 |
| :e! | 返回至上次保存后的状态,相当于重新打开 |
搜索
| 操作 | 功能 |
|---|---|
| (n)/string | 向下搜索字符串string的第一(n)个匹配项 |
| (n)?string | 向上搜索字符串string的第一(n)个匹配项 |
| /string\c | |
| /\ |
|
| n | 移动至下一个搜索的匹配项 |
| N | 移动至上一个搜索的匹配项 |
| gd | 搜索当前单词,并停留在当前匹配项 |
| (n)* | 搜索当前单词,并移动到下一(n)个匹配项 |
| (n)# | 搜索当前单词,并移动到上一(n)个匹配项 |
| (n)g* | 搜索当前字符串,并移动到下一(n)个匹配项 |
| (n)g# | 搜索当前字符串,并移动到上一(n)个匹配项 |
调整
| 操作 | 功能 |
|---|---|
| :% [action] | 对所有行进行操作[action] |
| :n1,n2 [action] | 对第n1行至n2行之间执行操作[action],’1,$’同’%’ |
| :n [action] | 对第n行执行操作[action] |
| :n1,n2 y | 复制第n1至n2行之间内容 |
| :n1,n2 d | 删除第n1至n2行之间内容 |
| :n1,n2 m n3 | 将第n1至n2行移动到第n3行之后 |
| :n1,n2 co n3 | 将第n1至n2行复制到第n3行之后 |
| :n1,n2 w [file] | 将第n1至n2行另存为[file] |
| :n1,n2 w ![command] | 将第n1至n2行作为标准输入来执行[command] |
| :n1,n2 s/str1/str2/ | 在第n1至n2行之间搜索第一个str1并替换成str2 |
| :n1,n2 s/str1/str2/g | 在第n1至n2行之间搜索str1并替换成str2 |
| :n1,n2 s/str1/str2/gc | 在第n1至n2行之间搜索str1并替换成str2,替换前需确认 |
| :n1,n2 >> | 将第n1行至n2行之间向右移动一个[tab] |
| :n1,n2 << | 将第n1行至n2行之间向左移动一个[tab] |
| :g/str/d | |
| :s 或 :& | 执行上一步的s/str1/str2/g命令 |
| :ce | 使本行内容居中 |
| :ri | 使本行内容靠右 |
| :le | 使本行内容靠左 |
| :@: | 执行上一次的命令行模式的命令 |
外部命令
| 操作 | 功能 |
|---|---|
| :![command] | 暂时离开vi并执行命令[command] |
| :!! | 执行上一次的外部命令 |
| :.![command] | |
| :sh | 暂时离开vi执行多条命令 |
| [Ctrl]d | 执行:sh后由此操作回到vi |
| :r ![command] | 执行外部命令并将其标准输出插入至下一行 |
多文件编辑
| 操作 | 功能 |
|---|---|
| :vi [file] 或 :e [file] | 在vi中打开另一个文件[file] |
| :n | 切换至下一个文件 |
| :N | 切换至上一个文件 |
| :b [file] | 直接跳到[file]文件对其进行编辑 |
| :next | |
| :previous | |
| :wnext | |
| :args | |
| :args [file1] [file2] … | |
| :last | |
| :first | |
| [Ctrl]^ | 返回至上一个编辑的文件 |
| :file | 列出当前文件的信息 |
| :files 或 :ls | 列出所有打开的文件 |
多窗口编辑
| 操作 | 功能 |
|---|---|
| :split 或 [Ctrl]ws | 打开新窗口显示当前文件(水平排列) |
| :split [file] | 打开新窗口显示file(水平排列) |
| :vsplit 或 [Ctrl]wv | 打开新窗口显示当前文件(垂直排列) |
| :vsplit [file] | 打开新窗口显示file(垂直排列) |
| :q 或 [Ctrl]wq | 关闭当前窗口 |
| [Ctrl]wo | 关闭当前窗口以外的其他所有窗口 |
| [Ctrl]wh 或 [Ctrl]w← | 移动至左一个窗口 |
| [Ctrl]wj 或 [Ctrl]w↓ | 移动至下一个窗口 |
| [Ctrl]wk 或 [Ctrl]w↑ | 移动至上一个窗口 |
| [Ctrl]wl 或 [Ctrl]w→ | 移动至右一个窗口 |
| [Ctrl]w+ 或 [Ctrl]w- | 增加或减小视窗的高度 |
个性化设置
使用 :set 来进行个性化的设置,通常是对两种类型的变量进行设置:取值型和布尔型。
- 取值型 —— :set var=num
- 布尔型 —— :set (no)var
另外,还有一些设置或是查看信息的命令,它们可能不使用 :set 作为开头。
布尔型变量
| 操作 | 功能 |
|---|---|
| :set number | 显示行号,number可缩写为nu |
| :set hlsearch | 设置搜索高亮 |
| :set autoindent | 设置自动缩进,autoindent可缩写为ai |
| :set autowrite | 设置自动保存 |
| :set cindent | 设置C语言的自动缩进,缩进量由shiftwidth控制 |
| :set ignorecase | 不区分大小写,ignorecase可缩写为ic |
| :set backup | 设置自动备份,backup可缩写为bk |
| :set mesg | |
| :set warn | |
| :set ruler | 显示右下状态栏,ruler可缩写为ru |
| :set showmode | 显示左下模式信息,showmode可缩写为smd |
| :set wrapscan | 设置搜索达顶部或底部时能回到底部或顶部,wrapscan可缩写为ws |
取值型变量
| 操作 | 功能 |
|---|---|
| :set shiftwidth=n | 设置偏移量为n个空格,shiftwidth可缩写为sw |
| :set window=n | ,window可缩写为wi |
| :set wrapmargin=n | ,wrapmargin可缩写为wm |
| :set tabstop=n | 设置一个[tab]为n个空格,tabstop可缩写为ts |
| :set backspace=[012] | 设置backspace是[2]否[01]能够删除任意字符 |
| :set background=dark | 设置颜色色调为深色,background可缩写为bg |
| :set background=light | 设置颜色色调为浅色,background可缩写为bg |
| :set filetype=[filetype] | 设置文件类型,如[filetype]取fortran |
其他设置及查看信息
| 操作 | 功能 |
|---|---|
| :set | 显示与系统默认值不同的设置参数 |
| :set all | 显示当前所有的环境参数设置值 |
| :syntax on 或 :syntax enable | 开启语法高亮 |
| :syntax off 或 :syntax clear | 取消语法高亮 |
| :nohlsearch | 单次取消高亮 |
| :colorscheme [type] | |
| :hide edit [file] | |
| :abbreviate str1 str2 | 将str1设置为str2的缩写,abbreviate可缩写为ab |
| :unabbreviate str | 删除已设置的缩写str,unabbreviate可缩写为una |
| :abbreviate | 查看所有已设置的缩写 |
| :map key1 key2 | 将关键字序列key1映射到另一个关键字序列key2 |
| :unmap key | 删除已设置的映射key |
| :map | |
| :registers ([register]) | 查看所有([register])寄存器,registers可缩写为reg |
| [Ctrl]g | 显示当前文件名和状态 |
| [Ctrl]l | 清除并重画屏幕 |
| Q | 进入Ex模式,之后输visual则返回Normal模式 |
| :help | 打开帮助 |
| :help [operation] | |
| :version | 查看vi的相关设置信息,可缩写为ve |
| [Esc][Esc] 或 [Ctrl][[Ctrl][ | 命令行模式切换至一般模式 |
| [Backspace] 或 [Ctrl]h | 命令行模式中向左删除一个字符 |
设置文件
vi 启动时,会自行寻找设置文件来初始化设置。按照以下顺序,vi 将读取找到的第一个文件。
\$HOME/.vimrc
\$HOME/_vimrc
\$HOME/.exrc
\$HOME/_exrc
如果使用 vi 的GUI版本,则需要读取 gvimrc 文件。使用 :version 命令可以查看读取了哪些文件。
如果想要在打开 vi 后自行读取设置文件,可以使用 :source 命令。
如果想要把已修改的设置保存为文件,可以使用 :mkvimrc 和 :mkexrc 命令。
如果想在不同的目录读取不同的设置文件,需要在当前目录放置一个 .vimrc 文件,同时在 vi 里设置 :set exrc。
| 操作 | 功能 |
|---|---|
| :mkvimrc [file] | 将已设置的内容保存成文件[file],可缩写为mkv |
| :version | 可查看读取的设置文件,可缩写为ve |
| :source [file] | 读取包含设置信息的文件,可缩写为so |
| :mkexrc [file] | 将已设置的内容保存成文件[file],可缩写为mk |
| :scriptnames | 查看加载的脚本,可缩写为scr |
| :set exrc | 设置为读取当前目录的设置文件,exrc可缩写为ex |