Contents

vim的学习笔记

本文为《Learn-Vim(the Smart Way)》中文翻译的学习笔记,原文地址

此处附上vim命令速查手册

ch2 缓冲区,窗口和选项卡

缓冲区

Note

set hidden 设置后在切换buffer时不会有未保存文件提示。

source % 加载本文件配置

:bnext,:bprevious 切换至下一个,前一个buffer,可简写为bnbp

Ctrl+i,Ctrl+o 跳转至跳转列表中的新、旧位置

Ctrl+^ 跳转至先前编辑过的buffer

:bdelete n 删除创建的buffer,n可省略,可缩写为bd

窗口

Note

:vsplit file 垂直分割窗口,并打开文件

:split file 水平分割窗口,并打开文件

:new file 创建一个新窗口,并打开文件

Ctrl+W+[HJKL]> 上下左右移动光标至对应的窗口

ctrl+w+[vsco] 垂直分割窗口、水平分割窗口、关闭窗口、关闭除了当前窗口的其它窗口。

选项卡

Note

:tabnew file.txt 在tab中打开一个文件

:tabclose 关闭当前tab

:tabnext 切换至下一个tab

:tabprevious 切换至前一个tab

:tablast 切换至最后一个tab

:tabfirst 切换至第一个tab

ch3 打开和搜索文件

打开和编辑文件

Note
edit file 在vim中打开文件

使用find命令搜索

Note

:find命令根据path选项配置的路径查找文件

set path?查看路径

使用grep在文件中搜索

Note

:vim /pattern/ file 内置grep,两个部分都可以使用通配符,使用quickfix进行处理

:grep 调用外部grep,默认调用终端grep,可以通过变量grepprg修改

quickfix窗口

Note

:copen 打开quickfix窗口

:cclose 关闭quickfix窗口

:cnext 跳到下一个错误

:cprevious 跳到前一个错误

:colder 跳到旧的错误列表

:cnewer 跳到新的错误列表

使用fzf和ripgrep插件

安装

插件地址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语法

Note
  • ^ 表示前缀精确匹配。要搜索一个以"welcome"开头的短语:^welcom

  • $ 表示后缀精确匹配。要搜索一个以"my friends"结尾的短语:friends$

  • ' 表示精确匹配。要搜索短语"welcom my friends":'welcom my friends

  • | 表示"或者"匹配。要搜索"friends"或"foes":friends | foes

  • ! 表示反向匹配。要搜索一个包含"welcome"但不包含"friends"的短语:welcome !friends

查找文件

Note

命令:Files

我自己使用的是插件LeaderF,映射到快捷键<Leader>F

或者使用NERDTree插件,我将其快捷键映射到<Leader>e

附上LeaderF官方仓库NERDTree官方仓库

文件中查找

Note
命令:RG

将grep替换为Rg

Note

将其加入到.vimrc

set grepprg=rg\ --vimgrep\ --smart-case\ --follow

此时再使用:grep命令将使用上述的命令,而不是grep

在多文件中搜索和替换

这部分先鸽了🤣

ch4 Vim语法

Vim语法规则
verb + noun # 动词 + 名词

名词(动作 Motion)

常见动作例子
h 左
j 下
k 上
l 右
w 向前移动到下一个单词的开头
} 跳转到下一个段落
$ 跳转到当前行的末尾

动词(操作符 Operator)

可用:h opreator命令来查看详细的操作符

常用操作符
y yank(复制)
d delete(删除)
c change 删除文本,将删除的文本存到寄存器中,进入插入模式

复制或者删除文本后,可以使用p将其粘贴到光标后,用P将其粘贴到光标前。

动词(操作符 Operator)和名词(动作 motions)的组合

动词+名词的组合
复制当前位置到行尾的所有内容:y$
删除当前位置到下一个单词的开头:dw
修改当前位置到这个段落的结尾:c}

名词可以接受数字作为参数

动词+名词的组合
向左拷贝2个字符:y2h
删除后两个单词:d2w
修改后面两行:c2j

名词续(文本对象 Text Objects)

文本对象可以被 操作符 operations 使用,这里有两类文本对象:

Note
i + object 内部文本对象
a + object 外部文本对象

常见文本对象
w 一个单词
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 移动文件

字符导航

Note
h 左
j 下
k 上
l 右

行号和相对行号

set relativenumber/norelativenumber number/nonumber

移动计数

在使用移动前加上一个数字,可以重复多次移动。

[计数] + 移动

单词导航

Note
w 移动到下一个单词的开头
W 移动到下一个词组的开头
e 移动到下一个单词的结尾
E 移动到下一个词组的结尾
b 移动到前一个单词的开头
B 移动到前一个词组的开头
ge 移动到前一个单词的结尾
gE 移动到前一个词组的结尾

单词和词组都按照非空字符被分割,一个单词指的是一个只包含a-zA-Z0-9字符串,一个词组指的是一个包含除了空字符(包括空格,tab,EOL)以外的字符的字符串。 你可以通过:h word:h WORD了解更多。

当前行导航

Note
0 跳到本行第一个字符
^ 跳到本行第一个非空字符
g_ 跳到本行最后一个非空字符
$ 跳到本行最后一个字符
n| 跳到本行第n列
f 在同一行向后搜索第一个匹配
F 在同一行向前搜索第一个匹配
t 在同一行向后搜索第一个匹配,并停在匹配前
T 在同一行向前搜索第一个匹配,并停在匹配前
; 在同一行重复最近一次搜索
, 在同一行向相反方向重复最近一次搜索

句子和段落导航

Note
( 跳到前一个句子
) 跳到下一个句子
{ 跳转到上一个段落
} 跳转到下一个段落

一个句子的定义是以.!?和跟着的一个换行符或空格,tab结尾的。一个段落总是以一个空行开始和结尾。

你可以通过:h setence:h paragraph了解更多。

匹配导航

Note
% Navigate to another match, usually works for (), [], {}

行号导航

Note
gg 跳转到第一行
G 跳转到最后一行
nG 跳转到第n行
n% 跳到文件的n%

另外,如果你想看文件总行数,可以用CTRL-g查看。

窗格导航

Note
H 跳转到屏幕的顶部
M 跳转到屏幕的中间
L 跳转到屏幕的底部
nH 跳转到距离顶部n行的位置
nL 跳转到距离底部n行的位置

滚动

Note
Ctrl-e 向下滚动一行
Ctrl-d 向下滚动半屏
Ctrl-f 向下滚动一屏
Ctrl-y 向上滚动一行
Ctrl-u 向上滚动半屏
Ctrl-b 向上滚动一屏
zt 将当前行置于屏幕顶部附近
zz 将当前行置于屏幕中央
zb 将当前行置于屏幕底部

搜索导航

Note
/ 向后搜索一个匹配
? 向前搜素一个匹配
n 重复上一次搜索(和上一次方向相同)
N 重复上一次搜索(和上一次方向相反)
* 向后查找光标所在的完整单词
# 向前查找光标所在的完整单词
g* 向后搜索光标所在的单词
g# 向前搜索光标所在的单词

如果你的光标位于一个字符串"one"上,按下*相当于/\<one\>/\<one\>中的\<\>表示整词匹配,使得一个更长的包含"one"的单词不会被匹配上,也就是说它会匹配"one",但不会匹配"onetwo"。 如果你的光标在"one"上并且你想向后搜索完全或部分匹配的单词,例如"one"和"onetwo",你可以用g*替代*

位置标记

你可以通过标记保存当前位置并在之后回到这个位置,就像文本编辑中的书签。 你可以通过mx设置一个标记,其中x可以是a-zA-Z。 有两种办法能回到标记的位置: 用`x精确回到(行和列),或者用'x回到行级位置。使用:marks查看所有标签。

Note
ma 用a标签标记一个位置
`a 精确回到a标签的位置(行和列)
'a 跳转到a标签的行
'' 在当前buffer中跳转回到上一次跳转前的最后一行
`` 在当前buffer中跳转回到上一次跳转前的最后一个位置
`[ 跳转到上一次修改或拷贝的文本的开头
`] 跳转到上一次修改或拷贝的文本的结尾
`< 跳转到最近一次可视模式下选择的部分的开头
`> 跳转到最近一次可视模式下选择的部分的结尾
`0 跳转到退出Vim前编辑的最后一个文件

ch6 输入模式

进入输入模式
i 从光标之前的位置开始输入文本
I 从当前行第一个非空字符之前的位置之前开始输入文本
a 在光标之后的位置追加文本
A 在当前行的末尾追加文本
o 在光标位置下方新起一行并开始输入文本
O 在光标位置的上方新起一行并开始输入文本
s 删除当前光标位置的字符并开始输入文本
S 删除当前行并开始输入文本
gi 从当前缓冲区上次结束输入模式的地方开始输入文本
gI 在当前行的第一列的位置开始输入文本
退出输入模式
退出输入模式进入普通模式
Ctrl-[ 退出输入模式进入普通模式
Ctrl-c 与 Ctrl-[ 和 功能相同, 但是不检查缩写
在输入模式中删除大块文本
Ctrl-h 删除一个字符
Ctrl-w 删除一个单词
Ctrl-u 删除一整行

执行普通模式下的命令

设置居中以及跳转
Ctrl-o zz 居中窗口
Ctrl-o H/M/L 跳转到窗口的顶部/中部/底部
Ctrl-o ‘a 跳转到标志’a处
执行终端命令
Ctrl-o !! curl https://google.com 运行curl命令
Ctrl-o !! pwd 运行pwd命令
快速删除
Ctrl-o dtz 从当前位置开始删除文本,直到遇到字母"z"
Ctrl-o D 从当前位置开始删除文本,直到行末

ch7 点命令

点命令(.)可以用来重放上一个修改操作。详细地可以通过:h .来查看定义。简单来说就是 当你使用普通模式下的命令来更新(添加,修改或者删除)当前缓冲区中的内容时,你就是在执行一个修改操作了。 其中的例外是使用命令行命令进行的修改(以开头的命令),这些命令不算作修改操作。

ch8 寄存器

下面是Vim所拥有的10种寄存器类型:

Note
  1. 匿名寄存器("").
  2. 编号寄存器(“0-9).
  3. 小删除寄存器 (”-).
  4. 命名寄存器 (“a-z).
  5. 只读寄存器 (”:, “., and “%).
  6. Buffer交替文件寄存器 (”#).
  7. 表达式寄存器 ("=).
  8. 选取和拖放寄存器(”* and “+).
  9. 黑洞寄存器 (”_).
  10. 搜索模式寄存器 ("/).
存值在寄存器中的操作
y 复制
c 删除文本并进入输入模式
d 删除文本

其实还有更多的寄存器写入操作,根据经验看来,如果一个操作删除了文本,那么很有可能这个操作将移除的文本存入寄存器中了。

在输入模式中使用寄存器
Ctrl-r x

其中x是寄存器标志。

匿名寄存器("")

想从匿名寄存器中获取文本,可以使用""p。 匿名寄存器默认存储着你最近一次复制,修改或删除的文本。如果再进行另一次复制,修改或删除,Vim会自动替换匿名寄存器中的文本。

默认情况下,p(或者P)是和匿名寄存器相关联的。

编号寄存器("0-9)

复制寄存器 (i"0)

如果你使用yy来复制一整行文本,事实上Vim会将文本存放两个寄存器中:

  1. 匿名寄存器(p)
  2. 复制寄存器("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

基本宏命令
qa 开始记录动作到寄存器 a
q (while recording) 停止记录
调用宏命令
@a Execute macro from register a
@@ Execute the last executed macros

在执行遇到错误的时候,宏命令会自动停止。

命令行执行宏

在正常模式执行@a并不是宏命令调用的唯一方式。你也可以在命令行执行:normal @a:normal会将任何用户添加的参数作为命令去执行。例如添加@a,和在normal mode执行@a的效果是一样的。

:normal命令也支持范围参数。你可以在选择的范围内去执行宏命令。如果你只想在第二行和第三行执行宏命令,你可以执行:2,3 normal @a

Ctrl-v是一个插入模式的操作符,可以逐字地插入一个非数字字符。