vim的学习笔记
本文为《Learn-Vim(the Smart Way)》中文翻译的学习笔记,原文地址。
此处附上vim命令速查手册
ch2 缓冲区,窗口和选项卡
缓冲区
set hidden
设置后在切换buffer时不会有未保存文件提示。
source %
加载本文件配置
:bnext
,:bprevious
切换至下一个,前一个buffer,可简写为bn
,bp
Ctrl+i
,Ctrl+o
跳转至跳转列表中的新、旧位置
Ctrl+^
跳转至先前编辑过的buffer
:bdelete n
删除创建的buffer,n可省略,可缩写为bd
窗口
:vsplit file
垂直分割窗口,并打开文件
:split file
水平分割窗口,并打开文件
:new file
创建一个新窗口,并打开文件
Ctrl+W+[HJKL]>
上下左右移动光标至对应的窗口
ctrl+w+[vsco]
垂直分割窗口、水平分割窗口、关闭窗口、关闭除了当前窗口的其它窗口。
选项卡
:tabnew file.txt
在tab中打开一个文件
:tabclose
关闭当前tab
:tabnext
切换至下一个tab
:tabprevious
切换至前一个tab
:tablast
切换至最后一个tab
:tabfirst
切换至第一个tab
ch3 打开和搜索文件
打开和编辑文件
edit file
在vim中打开文件使用find命令搜索
:find
命令根据path选项配置的路径查找文件
set path?
查看路径
使用grep在文件中搜索
:vim /pattern/ file
内置grep,两个部分都可以使用通配符,使用quickfix进行处理
:grep
调用外部grep,默认调用终端grep,可以通过变量grepprg修改
quickfix窗口
:copen
打开quickfix窗口
:cclose
关闭quickfix窗口
:cnext
跳到下一个错误
:cprevious
跳到前一个错误
:colder
跳到旧的错误列表
:cnewer
跳到新的错误列表
使用fzf和ripgrep插件
安装
往.zshrc
中添加下列代码(若是其它shell,请修改相应的.*rc
文件)
if type rg &> /dev/null; then
export FZF_DEFAULT_COMMAND='rg --files'
export FZF_DEFAULT_OPTS='-m'
fi
FZF_DEFAULT_OPTS
中的-m
允许我们按下<TAB>
和<S-TAB>
进行多重选择
安装好之后还需要在.vimrc
中安装fzf插件
Plug 'junegunn/fzf.vim'
Plug 'junegunn/fzf', { 'do': { -> fzf#install() } }
fzf语法
-
^
表示前缀精确匹配。要搜索一个以"welcome"开头的短语:^welcom
。 -
$
表示后缀精确匹配。要搜索一个以"my friends"结尾的短语:friends$
。 -
'
表示精确匹配。要搜索短语"welcom my friends":'welcom my friends
。 -
|
表示"或者"匹配。要搜索"friends"或"foes":friends | foes
。 -
!
表示反向匹配。要搜索一个包含"welcome"但不包含"friends"的短语:welcome !friends
。
查找文件
命令:Files
我自己使用的是插件LeaderF,映射到快捷键<Leader>F
。
或者使用NERDTree插件,我将其快捷键映射到<Leader>e
。
文件中查找
:RG
将grep替换为Rg
将其加入到.vimrc
中
set grepprg=rg\ --vimgrep\ --smart-case\ --follow
此时再使用:grep
命令将使用上述的命令,而不是grep
在多文件中搜索和替换
这部分先鸽了🤣
ch4 Vim语法
名词(动作 Motion)
j 下
k 上
l 右
w 向前移动到下一个单词的开头
} 跳转到下一个段落
$ 跳转到当前行的末尾
动词(操作符 Operator)
可用:h opreator
命令来查看详细的操作符
d delete(删除)
c change 删除文本,将删除的文本存到寄存器中,进入插入模式
复制或者删除文本后,可以使用p
将其粘贴到光标后,用P
将其粘贴到光标前。
动词(操作符 Operator)和名词(动作 motions)的组合
y$
删除当前位置到下一个单词的开头:
dw
修改当前位置到这个段落的结尾:
c}
名词可以接受数字作为参数
y2h
删除后两个单词:
d2w
修改后面两行:
c2j
名词续(文本对象 Text Objects)
文本对象可以被 操作符 operations 使用,这里有两类文本对象:
a + object 外部文本对象
p 一个段落
s 一个句子
( 或 ) 一对()
{ 或 } 一对{}
[ 或 ] 一对[]
< 或 > 一对<>
t XML标签
" 一对""
' 一对''
` 一对``
了解更多可以使用:h text-objects
。
综合性和语法
Vim有一个 过滤操作符!
可以用外部程序过滤我们的文本。
例如将一下文本格式化
Id|Name|Cuteness
01|Puppy|Very
02|Kitten|Ok
03|Bunny|Ok
使用命令!}column -t -s "|"
后效果如下:
Id Name Cuteness
01 Puppy Very
02 Kitten Ok
03 Bunny Ok
插件vim-textobj-user允许你创建自己的文本对象,同时包含有一系列定义好的文本对象。
ch5 移动文件
字符导航
j 下
k 上
l 右
行号和相对行号
set relativenumber/norelativenumber number/nonumber
移动计数
在使用移动前加上一个数字,可以重复多次移动。
[计数] + 移动
单词导航
W 移动到下一个词组的开头
e 移动到下一个单词的结尾
E 移动到下一个词组的结尾
b 移动到前一个单词的开头
B 移动到前一个词组的开头
ge 移动到前一个单词的结尾
gE 移动到前一个词组的结尾
单词和词组都按照非空字符被分割,一个单词指的是一个只包含a-zA-Z0-9
字符串,一个词组指的是一个包含除了空字符(包括空格,tab,EOL)以外的字符的字符串。 你可以通过:h word
和:h WORD
了解更多。
当前行导航
^ 跳到本行第一个非空字符
g_ 跳到本行最后一个非空字符
$ 跳到本行最后一个字符
n| 跳到本行第n列
f 在同一行向后搜索第一个匹配
F 在同一行向前搜索第一个匹配
t 在同一行向后搜索第一个匹配,并停在匹配前
T 在同一行向前搜索第一个匹配,并停在匹配前
; 在同一行重复最近一次搜索
, 在同一行向相反方向重复最近一次搜索
句子和段落导航
) 跳到下一个句子
{ 跳转到上一个段落
} 跳转到下一个段落
一个句子的定义是以.!?和跟着的一个换行符或空格,tab结尾的。一个段落总是以一个空行开始和结尾。
你可以通过:h setence
和:h paragraph
了解更多。
匹配导航
% Navigate to another match, usually works for (), [], {}
行号导航
G 跳转到最后一行
nG 跳转到第n行
n% 跳到文件的n%
另外,如果你想看文件总行数,可以用CTRL-g
查看。
窗格导航
M 跳转到屏幕的中间
L 跳转到屏幕的底部
nH 跳转到距离顶部n行的位置
nL 跳转到距离底部n行的位置
滚动
Ctrl-d 向下滚动半屏
Ctrl-f 向下滚动一屏
Ctrl-y 向上滚动一行
Ctrl-u 向上滚动半屏
Ctrl-b 向上滚动一屏
zt 将当前行置于屏幕顶部附近
zz 将当前行置于屏幕中央
zb 将当前行置于屏幕底部
搜索导航
? 向前搜素一个匹配
n 重复上一次搜索(和上一次方向相同)
N 重复上一次搜索(和上一次方向相反)
* 向后查找光标所在的完整单词
# 向前查找光标所在的完整单词
g* 向后搜索光标所在的单词
g# 向前搜索光标所在的单词
如果你的光标位于一个字符串"one"上,按下*相当于/\<one\>
。 /\<one\>
中的\<
和\>
表示整词匹配,使得一个更长的包含"one"的单词不会被匹配上,也就是说它会匹配"one",但不会匹配"onetwo"。 如果你的光标在"one"上并且你想向后搜索完全或部分匹配的单词,例如"one"和"onetwo",你可以用g*
替代*
。
位置标记
你可以通过标记保存当前位置并在之后回到这个位置,就像文本编辑中的书签。 你可以通过mx
设置一个标记,其中x可以是a-zA-Z。 有两种办法能回到标记的位置: 用`x精确回到(行和列),或者用'x
回到行级位置。使用:marks
查看所有标签。
`a 精确回到a标签的位置(行和列)
'a 跳转到a标签的行
'' 在当前buffer中跳转回到上一次跳转前的最后一行
`` 在当前buffer中跳转回到上一次跳转前的最后一个位置
`[ 跳转到上一次修改或拷贝的文本的开头
`] 跳转到上一次修改或拷贝的文本的结尾
`< 跳转到最近一次可视模式下选择的部分的开头
`> 跳转到最近一次可视模式下选择的部分的结尾
`0 跳转到退出Vim前编辑的最后一个文件
ch6 输入模式
I 从当前行第一个非空字符之前的位置之前开始输入文本
a 在光标之后的位置追加文本
A 在当前行的末尾追加文本
o 在光标位置下方新起一行并开始输入文本
O 在光标位置的上方新起一行并开始输入文本
s 删除当前光标位置的字符并开始输入文本
S 删除当前行并开始输入文本
gi 从当前缓冲区上次结束输入模式的地方开始输入文本
gI 在当前行的第一列的位置开始输入文本
Ctrl-[ 退出输入模式进入普通模式
Ctrl-c 与 Ctrl-[ 和 功能相同, 但是不检查缩写
Ctrl-w 删除一个单词
Ctrl-u 删除一整行
执行普通模式下的命令
Ctrl-o H/M/L 跳转到窗口的顶部/中部/底部
Ctrl-o ‘a 跳转到标志’a处
Ctrl-o !! pwd 运行pwd命令
Ctrl-o D 从当前位置开始删除文本,直到行末
ch7 点命令
点命令(.
)可以用来重放上一个修改操作。详细地可以通过:h .
来查看定义。简单来说就是 当你使用普通模式下的命令来更新(添加,修改或者删除)当前缓冲区中的内容时,你就是在执行一个修改操作了。 其中的例外是使用命令行命令进行的修改(以:
开头的命令),这些命令不算作修改操作。
ch8 寄存器
下面是Vim所拥有的10种寄存器类型:
- 匿名寄存器("").
- 编号寄存器(“0-9).
- 小删除寄存器 (”-).
- 命名寄存器 (“a-z).
- 只读寄存器 (”:, “., and “%).
- Buffer交替文件寄存器 (”#).
- 表达式寄存器 ("=).
- 选取和拖放寄存器(”* and “+).
- 黑洞寄存器 (”_).
- 搜索模式寄存器 ("/).
c 删除文本并进入输入模式
d 删除文本
其实还有更多的寄存器写入操作,根据经验看来,如果一个操作删除了文本,那么很有可能这个操作将移除的文本存入寄存器中了。
其中x是寄存器标志。
匿名寄存器(""
)
想从匿名寄存器中获取文本,可以使用""p
。 匿名寄存器默认存储着你最近一次复制,修改或删除的文本。如果再进行另一次复制,修改或删除,Vim会自动替换匿名寄存器中的文本。
默认情况下,p
(或者P
)是和匿名寄存器相关联的。
编号寄存器("0-9
)
复制寄存器 (i"0
)
如果你使用yy
来复制一整行文本,事实上Vim会将文本存放两个寄存器中:
- 匿名寄存器(
p
) - 复制寄存器(
"0
)
在你又复制其他不同的文本后,Vim会自动替换匿名寄存器和复制寄存器(0
)中的内容。 复制寄存器的内容会自动放入剪切板中。
编号寄存器(“1-9)
当你修改或者删除至少一整行的文本时,这部分文本会按时间顺序被存储在1-9号编号寄存器中。(编号越小时间距离越近)
小删除寄存器("-
)
不足一行的修改或者删除都不会被存储在0-9号编号寄存器中,而是会被存储在小删除寄存器 ("-
)中。
命名寄存器("a-z
)
a-z命名寄存器可以存储复制的,修改的和被删除的文本。你需要显式地告诉Vim你要使用命名寄存器,你拥有完整的控制权。
为了复制一个单词到寄存器"a"中,你可以使用命令"ayiw
:
"a
告诉Vim下一个动作(删除/修改/复制)会被存储在寄存器"a"中yiw
复制这个单词
有时你可能会想要往已有内容的命名寄存器中继续添加内容,这种情况下,你可以追加文本而不是全部重来。你可以使用大写版本的命名寄存器来进行文本的追加。
只读寄存器(":
,".
,"%
)
- . 存储上一个输入的文本
- 存储上一次执行的命令
% 存储当前文件的文件名
Buffer交替文件寄存器("#
)
在Vim中,#通常代表交替文件。交替文件指的是你上一个打开的文件,想要插入交替文件的名字的话,可以使用命令"#p
。
表达式寄存器("=
)
你可以使用以下命令计算数学表达式1+1的值:
"=1+1<Enter>p
Ctrl-r =1+1 (输入模式)
"=@a (a为某个寄存器,里面保存着表达式)
Ctrl-r =@a (输入模式)
选取和拖放寄存器("*
,"+
)
需要配合vim-gui(gvim)使用,并且支持clipboard
特性,此处跳过。
黑洞寄存器("_
)
有些时候你并不希望把什么东西都往寄存器里存,你可以使用黑洞寄存器("_
)。
它是和/dev/null
类似的寄存器。
搜索模式寄存器("/
)
为了粘贴你的上一个搜索询问(/
或?
),你可以使用搜索模式寄存器("/
)。使用命令"/p
就能粘贴上一个搜索的条目。
查看所有寄存器
你可以使用:register
命令来查看你的所有寄存器。如果你只想查看"a”,“1"和”-“寄存器的内容的话则可以使用命令:register a 1 -
。
有一个Vim的插件叫做vim-peekaboo
,可以让你查看到寄存器的内容,在普通模式下输入"
或@
即可,或者在输入模式中输入Ctrl-r
。
执行寄存器
命名寄存器不只可以用来存放文本,你还可以借助@
来执行宏命令。
清除寄存器
你可以通过记录一个空的宏命令来快速地清除任何命名寄存器。
还有一种清除寄存器的方法就是使用表达式:let @a = ''
来将寄存器"a 的值设为空的字符串。
获取寄存器的内容
你可以使用:put
命令来粘贴任何寄存器的内容。此命令会心起一行打印内容。
ch9
q (while recording) 停止记录
@@ Execute the last executed macros
在执行遇到错误的时候,宏命令会自动停止。
命令行执行宏
在正常模式执行@a
并不是宏命令调用的唯一方式。你也可以在命令行执行:normal @a
。:normal
会将任何用户添加的参数作为命令去执行。例如添加@a
,和在normal mode
执行@a
的效果是一样的。
:normal
命令也支持范围参数。你可以在选择的范围内去执行宏命令。如果你只想在第二行和第三行执行宏命令,你可以执行:2,3 normal @a
。
Ctrl-v
是一个插入模式的操作符,可以逐字地插入一个非数字字符。