《Vim使用技巧 第二版》学习笔记
这是我根据《Vim使用技巧 第二版》整理的,主要用于方便查找
模式
普通模式
x
删除当前字符
u
撤销修改
.
重复动作
a
当前位置插入
A
行末插入(=$a
)
R
由普通模式进入替换模式
r
进入替换模式替换一个字符
gR
进入虚拟替换模式:按屏幕上实际显示的宽度来替换字符,而不是按文件中所保存的字符进行替换(它会把制表符当成一组空格进行处理)
gr
进入虚拟替换模式替换一个字符
o
在下面插入一行并在下一行开头进入插入模式
O
在上面插入一行并在上一行开头进入插入模式
s
删除当前字符并进入插入模式
[count]<Ctrl-a>
把当前光标之上或之后的第一个数字加上 [count](不输入默认为1)
在指令前加上[count]
可以指定指令重复的次数(但是能用重复就不要用次数)
ga
以十进制和十六进制的形式 显示出光标所在字符的字符编码
插入模式
<Ctrl-w>
删除前一个单词
<Ctrl-u>
删除至行首
<Ctrl-o>
进入插入-普通模式:在此模式中,可以执行一个普通模式命令,执行完后,马上又返回到插入模式
<C-r>{register}
粘贴
<C-r><C-p>{register}
按原义插入寄存器内的文本,并修正任何不必要的缩进
<C-r>={算式}
把计算的结果插入
<C-v>{123}
以十进制字符编码插入字符
<C-v>u{1234}
以十六进制字符编码插入字符
<C-v>{nondigit}
按原义插入非数字字符
<C-k>{char1}{char2}
插入以二合字母 {char1}{char2} 表示的字符
可视模式
在可视模式中,要先选中选区,然后再触发修改命令。这种次序颠倒的方式对所有的操作符命令都适用
v
激活面向字符的可视模式
V
激活面向行的可视模式
<C-v>
激活面向列块的可视模式
gv
重选上次的高亮选区
命令行模式
适用于远距离的操作
:[number]
跳转到制定行
:{start},{end}
选择一个范围
@:
重复上一个Ex命令
@@
重复上一个 @:
的命令
<C-d>
显示全部可以补全的命令
<C-r><C-w>
在命令中插入当前光标中的单词
q/
打开查找命令历史的命令行窗口
q:
进入命令行窗口模式,在这个模式下上下选择历史命令的时候,按回车执行;你甚至可以在这个模式里用正常的方式修改历史命令
:!{cmd}
调用外部命令
:shell
启动一个交互的shell会话
:read !{cmd}
在shell 中执行 {cmd} ,并把其标准输出插入光标下方
:[range]write !{cmd}
在 shell 中执行 {cmd} ,以 [range] 作为其标准输入
:[range]!{filter}
使用外部程序 {filter} 过滤指定的 [range]
:source *.vim
执行Ex脚本
:argdo {Ex命令}
对参数列表内的所有缓冲区执行一条Ex命令
关于范围
.
代表当前行的地址
%
代表当前文件中的所有行
/{tag}/
{tag} 所在行
:{address}+n
偏移行
:[range]t{address}
复制 [range] 内容到 {address}
:[range]m{address}
移动 [range] 内容到 {address}
:[range]normal{操作}
对 [range] 行进行普通模式的 {操作}
operator
当一个操作符命令被连续调用两次时,它会作用于当前行。如 dd
删除当前行
c
修改(比删除多一个进入插入模式)
g~
反转大小写
gu
转换为小写
gU
转换为大写
>
增加缩进
<
减少缩进
=
自动缩进
!
使用外部程序过滤{motion}所跨越的行
motion
gg
将光标定位到文件的开头
G
将光标定位到文件的末尾
aw
表示整个单词
ap
表示整个段落
operator + motion 使用例
cw
删除从光标位置到单词结尾间的字符,并进入插入模式
dw
删除从光标起始位置到单词结尾的内容
db
删除从光标起始位置到单词开头的内容,但会原封未动地留下最后一个字符
daw
删除整个单词(delete a word,推荐使用)
关于删除
往前删除不会删除光标本身,往后删除会,光标看最左边就好理解了
关于文件
:ls
列出所有被载入内存中的缓冲区的列表,% 符号指明哪个缓冲区在当前窗口中可见,# 符号则代表轮换文
件。按 <C-^> 可以在当前文件和轮换文件间快速切换
:pwd
打印工作目录(print working directory)
切换缓冲区
命令 | 用途 |
---|---|
:bnext |
切换到列表中的下一个缓冲区 |
:bprev |
切换到列表中的上一个缓冲区 |
:bfirst |
跳到列表的开头 |
:blast |
跳到列表的结尾 |
:bdelete N1 N2 N3 或 :N,M bdelete |
删除缓冲区 |
Glob模式 | 所匹配的文件 |
---|---|
:args *.* |
index.html app.js |
:args **/*.js |
app.js lib/framework.js app/controllers/Mailer.js ...etc |
:args **/*.* |
app.js index.html lib/framework.js lib/theme.css app/controllers/Mailer.js ...etc |
反引号指定文件
:args `cat .chapters`
Vim 会在 shell 中执行反撇号(')括起来的命令,然后把 cat 命令的输出作为 :args 命令的参数。虽然本例是用 cat 命令获取 .chapters 文件的内容,但实际上可以用这种方式执行任意可用的shell命令。
files/.chapters内容
the_vim_way.pml
normal_mode.pml
insert_mode.pml
visual_mode.pml
切分窗口
命令 | 用途 |
---|---|
<C-w>s |
水平切分当前窗口,新窗口仍显示当前缓冲区 |
<C-w>v |
垂直切分当前窗口,新窗口仍显示当前缓冲区 |
:sp[lit] {file} |
水平切分当前窗口,并在新窗口中载入 |
:vsp[lit] {file} |
垂直切分当前窗口,并在新窗口中载入 |
在窗口间切换
命令 | 用途 |
---|---|
<C-w>w |
在窗口间循环切换 |
<C-w>h |
切换到左边的窗口 |
<C-w>j |
切换到下边的窗口 |
<C-w>k |
切换到上边的窗口 |
<C-w>l |
切换到右边的窗口 |
实际上,<C-w><C-w>
完成的功能和 <C-w>w
相同,就是说可以一直按住 <Ctrl>
键,然后输入 ww
(或 wj
,或上表的其他命令)来切换活动窗口。<C-w><C-w>
要比 <C-w>w
更容易按一些,尽管写出来时它显得更繁琐。
(h, j, k, l 和上下左右方向键是等效的)
关闭窗口
Ex命令 | 普通模式命令 | 用途 |
---|---|---|
:clo[se] |
<C-w>c |
关闭活动窗口 |
:on[ly] |
<C-w>o |
只保留活动窗口,关闭其他所有窗口 |
改变窗口大小
也可以拖拽鼠标
命令 | 用途 |
---|---|
<C-w>= |
使所有窗口等宽、等高 |
<C-w>_ |
最大化活动窗口的高度 |
` |
` |
[N]<C-w>_ |
把活动窗口的高度设为[N]行 |
`[N] |
` |
:lcd {path}
设置当前窗口的本地工作目录
:windo lcd {path}
为一个标签页中的所有窗口设置本地工作目录
标签页操作
命令 | 用途 |
---|---|
:tabe[dit] {filename} |
在新标签页中打开 |
<C-w>T |
把当前窗口移到一个新标签页 |
:tabc[lose] |
关闭当前标签页及其中的所有窗口 |
:tabo[nly] |
只保留活动标签页,关闭所有其他标签页 |
在标签页间切换
Ex命令 | 普通模式命令 | 用途 |
---|---|---|
:tabn[ext] {N} |
{N}gt |
切换到编号为 {N} 的标签页 |
:tabn[ext] |
gt |
切换到下一标签页 |
:tabp[previous] |
gT |
切换到上一标签页 |
重排标签页
:tabmove [N]
重新排列标签页。当 [N] 为0时,当前标签页会被移到开头;如果省略了 [N],当前标签页会被移到结尾。如果终端支持鼠标,或是正在使用 GVim,:那么也可以通过鼠标拖曳来进行重排操作。
文件
打开文件
:edit {file}
打开相对于工作目录的文件路径
:edit %:h<Tab>
% 符号代表活动缓冲区的完整文件路径,按 <Tab>
键会将其展开,:h
修饰符会去除文件名,但保留路径中的其他部分
:find {file}
在 path 里查找文件并打开
:set path+={path}
把 {path} 加入查找路径中
特殊的保存文件
把文件保存到不存在目录中
:edit {file}
命令一般用于打开一个已存在的文件,然而如果指定了一个不存在的文件路径,Vim 就会创建一个新的空白缓冲区。
:!mkdir -p %:h
-p
参数使 mkdir
创建任何不存在的中间目录,%:h
为不包含文件名的路径
用超级用户权限保存文件
:w !sudo tee % > /dev/null
快速移动和跳转
行移动
命令 | 光标动作 |
---|---|
j |
向下移动一个实际行 |
gj |
向下移动一个屏幕行 |
k |
向上移动一个实际行 |
gk |
向上移动一个屏幕行 |
0 |
移动到实际行的行首 |
g0 |
移动到屏幕行的行首 |
^ |
移动到实际行的第一个非空白字符 |
g^ |
移动到屏幕行的第一个非空白字符 |
` | 命令 |
---- | ------------------------------ |
j |
向下移动一个实际行 |
gj |
向下移动一个屏幕行 |
k |
向上移动一个实际行 |
gk |
向上移动一个屏幕行 |
0 |
移动到实际行的行首 |
g0 |
移动到屏幕行的行首 |
^ |
移动到实际行的第一个非空白字符 |
g^ |
移动到屏幕行的第一个非空白字符 |
移动到实际行的行尾 | |
`g | 命令 |
---- | ------------------------------ |
j |
向下移动一个实际行 |
gj |
向下移动一个屏幕行 |
k |
向上移动一个实际行 |
gk |
向上移动一个屏幕行 |
0 |
移动到实际行的行首 |
g0 |
移动到屏幕行的行首 |
^ |
移动到实际行的第一个非空白字符 |
g^ |
移动到屏幕行的第一个非空白字符 |
移动到屏幕行的行尾 |
j, k, 0, $ 都用于实际行,加上 g 前缀用于屏幕行
单词移动
命令 | 光标动作 |
---|---|
w |
正向移动到下一单词的开头 |
b |
反向移动到当前单词/上一单词的开头 |
e |
正向移动到当前单词/下一单词的结尾 |
ge |
反向移动到上一单词的结尾 |
先学会用 w 和 b
W, B, E 和 gE 对应”字串“的操作
查找字符
下表为行内操作
命令 | 用途 |
---|---|
f{char} |
正向移动到下一个 {char} 所在之处 |
F{char} |
反向移动到上一个 {char} 所在之处 |
t{char} |
正向移动到下一个 {char} 所在之处的前一个字符上 |
T{char} |
反向移动到上一个 {char} 所在之处的后一个字符上 |
; |
重复上次的字符查找命令 |
, |
反转方向查找上次的字符查找命令 |
/{word}
或者 把光标移到单词上按*
查找单词
n
向下重复上一次查找单词操作
N
向上重复上一次查找单词操作
在可视模式中选择分割符文本对象
选择时光标必须在分割符内
一般以 i 开头的文本对象会选择分隔符内部的文本,而以 a 开头的文本对象会选择包括分隔符在内的整个文本。为了便于记忆,可以把 i 想成“inside”,而把 a 想成“around”或“all”。
文本对象 | 选择区域 | 文本对象 | 选择区域 |
---|---|---|---|
a) 或 ab |
一对圆括号 (parentheses) | i) 或 ib |
圆括号 (parentheses) 内部 |
a} 或 aB |
一对花括号 | i} 或 iB |
花括号 {braces} 内部 |
a] |
一对方括号 [brackets] | i] 方括号 |
[brackets] 内部 |
a> |
一对尖括号 |
i> |
尖括号 |
a' |
一对单引号 'single quotes' | i' |
单引号 'single quotes' 内部 |
a" |
一对双引号 "double quotes" | i" |
双引号 "double quotes" 内部 |
a` |
一对反引号 backticks | i` |
反引号 backticks 内部 |
at |
一对 XML 标签 |
it |
XML标签 |
在普通模式中操作范围文本对象
文本对象 | 选择范围 |
---|---|
iw |
当前单词 |
aw |
当前单词及一个空格 |
iW |
当前字串 |
aW |
当前字串及一个空格 |
is |
当前句子 |
as |
当前句子及一个空格 |
ip |
当前段落 |
ap |
当前段落及一个空行 |
一般来说,d{motion} 命令和 aw、as 和 ap 配合起来使用比较好,而 c{motion} 命令和 iw 及类似的文本对象一起用效果会更好。
做标记
m{a-zA-Z}
用选定的字母标记当前光标所在位置。小写位置标记只在每个缓冲区局部可见,大写位置标记则全局
可见。
`{mark}
把光标移动到设置此位置标记时光标所在之处
'{mark}
跳到位置标记所在行,并把光标置于该行第一个非空白字符上
自动位置标记
位置标记 | 跳转到 |
---|---|
`` |
当前文件中上次跳转动作之前的位置 |
`. |
上次修改的地方 |
`^ |
上次插入的地方 |
`[ |
上次修改或复制的起始位置 |
`] |
上次修改或复制的结束位置 |
`< |
上次高亮选区的起始位置 |
`> |
上次高亮选区的结束位置 |
%
在一组开、闭括号间跳转
在 .vimrc
中加入以下内容可以激活 matchit 插件,它可以使 % 在配对的关键字间跳转:
set nocompatible
filetype plugin on
runtime macros/matchit.vim
遍历跳转列表
:jumps
查看跳转列表
<C-o>
后退
<C-i>
前进
遍历改变列表
:changes
查看改变列表
g;
反向
g,
正向
跳转到文件
把光标放到某个字符串上执行 gf
命令,可以跳转到该文件。
指定扩展名:suffixesadd 选项允许指定一个或多个文件扩展名,当 Vim 用gf 命令搜寻文件名时,会尝试使用这些扩展名,用下面的命令可以设置此选项:
:set suffixesadd+=.h
指定搜寻目录:设置 path(同上 find 的使用)
寄存器
{register}x
剪切字符
{register}d
剪切
{register}y
复制
{register}p
粘贴到光标后
{register}P
粘贴到光标前
{register}gp
粘贴到光标后,光标移动到被粘贴出来的文本结尾
{register}gP
粘贴到光标前,光标移动到被粘贴出来的文本结尾
:reg {register}
查看寄存器内容
register
"0
复制专用寄存器
"a - "z
有名寄存器
_
黑洞寄存器
"+
系统剪贴板
"*
选择专用寄存器
"=
表达式寄存器
只读寄存器
寄存器 | 内容 |
---|---|
"% |
当前文件名 |
"# |
轮换文件名 |
". |
上次插入的文本 |
": |
上次执行的Ex命令 |
"/ |
上次查找的模式 |
交换单词:在可视模式下使用 p 命令时,Vim将用指定的寄存器内容来替换高亮选区中的文本,高亮选区中的内容与寄存器的文本被调包了。
宏
在录制宏的过程中,禁止使用鼠标
q{register}
开始录制(如果 register 是大写,新内容会被追加到对应小写寄存器的后面)
q
停止录制
@{register}
执行宏
@@
重复最近调用过的宏
:normal @{register}
在高亮选区中的每一行上执行这个宏
模式匹配
\c
查找模式忽略大小写
\C
查找模式强制大小写
\v
表示特殊含义
\V
使得其后的模式中只有反斜杠有特殊的意义
模式 | 说明 |
---|---|
#\([0-9a-fA-F]\{6}|[0-9a-fA-F]\{3}\) |
使用 magic 搜索模式时,必须转义 (、)、以及 { 字符,赋予它们特殊的含义 |
`\v#([0-9a-fA-F] | [0-9a-fA-F]{3})` |
`\v#(\x | \x{3})` |
任何圆括号内部的匹配文本都会自动保存到一个临时的仓库,可以用 \1 引用这段被捕获的文本。如果模式中包含不止一组圆括号,则可以用 \1、\2,直到 \9,引用被每对 () 捕获的子匹配。另外,不论模式中是否使用了圆括号,元字符 \0 永远会引用整个匹配。在括号前加上 % 可以不把内容赋值到寄存器中。
<
与 >
两符号将用于匹配单词的边界,它们本身不匹配任何字符,仅表示单词与围绕此单词的空白字符(或标点符号)之间的边界。
例: /\v<(\w+)\_s+\1>
专门用于匹配重复单词
元字符 \zs 标志着一个匹配的起始,元字符 \ze 则用来界定匹配的结束。
例:如果查找 /Practical Vim
,文档中所有出现 “Practical Vim” 的地方都会被高亮起来。一旦将查找模式改为 /Practical \zsVim
,则只有单词 “Vim” 会被高亮,而单词 “Practical” 会被排除于匹配之外,但它仍是模式的一部分。这样一来,只有紧跟着单词 “Practical” 的 “Vim” 才会被高亮,其他前面不是 “Practical” 的 “Vim” 则不会被匹配。这与通过 /Vim
命令进行简单查找的结果有很大不同。
命令 | 用途 |
---|---|
n |
跳至下一处匹配,保持查找方向与偏移不变 |
N |
跳至上一处匹配,保持查找方向与偏移不变 |
/<CR> |
正向跳转至相同模式的下一处匹配 |
?<CR> |
反向跳转至相同模式的上一处匹配 |
gn |
进入面向字符的可视模式,并选中下一处匹配 |
gN |
进入面向字符的可视模式,并选中上一处匹配 |
正向查找时要转义 / 字符,反向查找时要转义 ? 号,每次都要转义符号 \
escape({string}, {chars})
{chars} 参数将指定哪些字符需要用反斜杠转义
在最后添加 /e
可以让光标停留在查找匹配的结尾
统计匹配总数
/{something}
:%s///gn
或者
/{something}
:vimgrep //g %
前者告诉我们总数,后者告诉我们每个所在的位置
substitute
:[range]s[ubstitute]/{pattern}/{string}/[flags]
输入 <C-r>{register}
可以将寄存器的内容插入命令行
标志位
标志位 g 使得 subsititute 命令可在全局范围内执行,即可以修改一行内的所有匹配,而不仅仅是第一处匹配。
标志位 c 让我们有机会可以确认或拒绝每一处修改。
标志位 n 会抑制正常的替换行为,即让 Vim 不执行替换操作,而只是报告本次 substitute 命令匹配的个数。
标志位 e 专门用于屏蔽错误提示。
标志位 & 仅仅用于指示 Vim 重用上一次 substitute 命令所用过的标志位。
特殊字符
符号 | 描述 |
---|---|
\r |
插入一个换行符 |
\t |
插入一个制表符 |
\\ |
插入一个反斜杠 |
\1 |
插入第1个子匹配 |
\2 |
插入第2个子匹配(以此类推,最多到 \9) |
\0 |
插入匹配模式的所有内容 |
& |
插入匹配模式的所有内容 |
~ |
使用上一次调用 :substitute 时的 |
\={Vim script} |
执行 {Vim Script} 表达式;并将返回的结果作为替换 |
手动决定每一次替换——答案的含义
答案 | 用途 |
---|---|
y |
替换此处匹配 |
n |
忽略此处匹配 |
q |
退出替换过程 |
l |
“last” —— 替换此处匹配后退出 |
a |
“all” —— 替换此处与之后所有的匹配 |
<C-e> |
向上滚动屏幕 |
<C-y> |
向下滚动屏幕 |
:cfdo {cmd}
修改所有 quickfix 列表上的文件
global
:[range] global[!] /{pattern}/ [cmd]
在缺省情况下,global 命令的作用范围是整个文件。
{pattern} 域与查找历史相互关联。
global! 将指示 Vim 在没有匹配到指定模式的行上执行 [cmd]