Vim - oceanbei333/leetcode GitHub Wiki

[TOC]

什么是 Vim?

Vim是从vi发展出来的一个文本编辑器。

对于大多数用户来说,Vim有着一个比较陡峭的学习曲线。这意味着开始学习的时候可能会进展缓慢,但是一旦掌握一些基本操作之后,能大幅度提高编辑效率。

模式

  • 普通模式(Normal mode)

在普通模式中,用的编辑器命令,比如移动光标,删除文本等等。这也是Vim启动后的默认模式。这正好和许多新用户期待的操作方式相反(大多数编辑器默认模式为插入模式)。

  • 插入模式(Insert mode)

在这个模式中,大多数按键都会向文本缓冲中插入文本。大多数新用户希望文本编辑器编辑过程中一直保持这个模式。

  • 可视模式(Visual mode)

这个模式与普通模式比较相似。但是移动命令会扩大高亮的文本区域。高亮区域可以是字符、行或者是一块文本。

当执行一个非移动命令时,命令会被执行到这块高亮的区域上。

  • 选择模式(Select mode)

这个模式和无模式编辑器的行为比较相似(Windows标准文本控件的方式)。这个模式中,可以用鼠标或者光标键高亮选择文本

  • 命令行模式(Command line mode)

在命令行模式中可以输入会被解释成可执行的文本。例如执行命令(:键),搜索(/?键)或者过滤命令(!键)。在命令执行之后,Vim返回到命令行模式之前的模式,通常是普通模式。

  • Ex模式(Ex mode)

这和命令行模式比较相似,可以一次执行多条命令

普通模式

动作

按键 说明
h
l 右(小写L)
j
k
w 移动到下一个单词
e 移动到当前/下一单词的结尾
b 移动到上一个单词
ge 反向移动到上一单词的结尾

动作可以用数字搭配使用,n动作

4j

撤销

u键会触发撤销命令,它会撤销最新的修改。

一次修改可以是改变文档内文本的任意操作,其中包括在普通模式、可视模式以及命令行模式中所触发的命令,

而且一次修改也包括了在插入模式中输入(或删除)的文本,

因此我们也可以说,i{insert some text} 是一次修改。

重做

重复

. 善用重复

操作符

操作符是对某个区域文本执行的操作。比如,dcgU> 都是操作符。这些操作符既可以在普通模式下使用,也可以在可视模式下使用。

截屏2021-01-07 上午10.55.36

操作符+动作=操作

dj 删除当前行以及上面一行

dl 删除左边一个字符

也可以配合数字使用

3dj或者d3j

文本对象

操作符也可以和文本对象搭配使用

截屏2021-01-07 上午11.21.40 截屏2021-01-07 上午11.19.55

操作符+文本对象

文本对象操作一般用 ia 加上对象标识符操作,其中 i 表示在对象内(英文 inner)操作,a 表示对整个对象(英文 around)操作,这时开头和结尾的空格都会被考虑进来。举个例子,diw 可以删除当前单词,ci( 可以改变括号中的内容。

文本对象同样可以与数字搭配使用。比如,像 ((( ))) 这样的文本,假如光标位于最内层的括号上或最内层的括号内,那么 d2a( 将会删除从最内层开始的两对括号,以及他们之间的所有内容。其实,d2a( 这个操作等同于 2da(

Vim的语法只有一条额外规则,即当一个操作符命令被连续调用两次时,它会作用于当前行。所以 dd 删除当前行,而 >> 缩进当前行

删除文本

命令 说明
x 删除游标所在的字符
X 删除游标所在前一个字符
Delete x
dd 删除整行
dw 删除一个单词(不适用中文)
d$D 删除至行尾
d^ 删除至行首
dG 删除到文档结尾处
d1G 删至文档首部

插入模式

命令 说明
i 在当前光标处进行编辑
I 在行首插入
A 在行末插入
a 在光标后插入编辑
o 在当前行后插入一个新行
O 在当前行前插入一个新行
cw 替换从光标所在位置后到一个单词结尾的字符

退出插入模式 esc

命令行模式

打开文件

:e 文件名

保存文档

从普通模式输入:进入命令行模式,

输入w回车,保存文档。

输入:w 文件名可以将文档另存为其他文件名或存到其它路径下

退出vim

命令 说明
:q! 强制退出,不保存
:q 退出
:wq! 强制保存并退出
:x 保存并退出
:wq 保存并退出

运行Shell命令

在Vim的命令行模式中,给命令加一个叹号前缀(参见:h:!)就可以调用外部程序。

Ex 命令

初时,先有 ed,ed 为 ex 之父,ex 为 vi 之父,而vi为 Vim 之父。

Vim为几乎所有功能都提供了相应的Ex命令

有时使用 Ex 命令,能比用普通模式命令更快地完成同样的工作。

举个例子,普通模式命令一般操作当前字符或当前行,

而 Ex 命令却可以在任意位置执行,这意味着我们无需移动光标就可以使用 Ex 命令做出修改。

但使 Ex 命令脱颖而出的最让人赞叹的功能,是它们拥有能够在多行上同时执行的能力。

![截屏2021-01-07 上午10.08.38](/Users/isea/Desktop/截屏2021-01-07 上午10.08.38.png)

范围

范围 (Ranges) 其实很好理解,但很多 Vim 用户的理解不到位。

  • 很多命令都可以加一个数字,用于指明操作范围
  • 范围可以是一个行号,用于指定某一行
  • 范围也可以是一对通过 ,; 分割的行号
  • 大部分命令,默认只作用于当前行
  • 只有 :write:global 是默认作用于所有行的
截屏2021-01-07 上午10.22.31
命令 操作的行
:d 当前行
:.d 当前行
:1d 第一行
:$d 最后一行
:1,$d 所有行
:%d 所有行(这是 1,$ 的语法糖)
:.,5d 当前行至第 5 行
:,5d 同样是当前行至第 5 行
:,+3d 当前行及接下来的 3 行
:1,+3d 第一行至当前行再加 3 行
:,-3d 当前行及向上的 3 行(Vim 会弹出提示信息,因为这是一个保留的范围)
:3,'xdelete 第三行至标注 为 x 的那一行
:/^foo/,$delete 当前行以下,以字符 "foo" 开头的那一行至结尾
:/^foo/+1,$delete 当前行以下,以字符 "foo" 开头的那一行的下一行至结尾

需要注意的是,; 也可以用于表示范围。区别在于,a,bb 是以当前行作为参考的。而 a;bb 是以 a 行作为参考的。举个例子,现在你的光标在第 5 行。这时 :1,+1d 会删除第 1 行至第 6 行,而 :1;+1d 会删除第 1 行和第 2 行。

使用:t和:m命令复制和移动行

![截屏2021-01-07 上午10.25.13](/Users/isea/Library/Application Support/typora-user-images/截屏2021-01-07 上午10.25.13.png)

指定范围上执行普通模式命令

  1. 批量注释

    :1,5normal I#

  2. 批量执行宏

可视模式

Vim的可视模式允许我们选中一块文本区域并在其上进行操作,表面看这应该很容易理解,因为大多数编辑软件都沿用此模式

Vim具有3种不同的可视模式,分别用于操作字符文本、行文本或块文本

某些可视模式命令执行的基本功能与普通模式相同

在普通模式中,我们先触发修改命令,然后使用动作命令指定其作用范围

在可视模式中,我们先选中选区,然后再触发修改命令。

面向字符的可视模式

按 v 可激活面向字符的可视模式

我们能够选择任意的字符范围,不论它是单个字符,还是位于一行内,或是跨若干行的指定字符范围,都没问题。该模式适用于操作单词或短语。

面向行的可视模式

按V(v和Shift键一起按)可激活面向行的可视模式,

面向列块的可视模式

按 (v和Ctrl键一起按)则可激活面向列块的可视模式

面向列块的可视模式则允许我们对文档中的列块进行操作。

demo

替换行与列

行首添加

文件

打开的文件都是作为缓冲区的一部分显示的。

窗口 是缓冲区上一层的视窗。如果你想同时查看几个文件或者查看同一文件的不同位置,那样你会需要窗口。

标签页 (标签)是窗口的集合。因此当你想使用多种窗口布局时候请使用标签。

缓冲区

在一次编辑会话中,可以打开多个文件。用Vim的缓冲区列表可以对这些文件进行管理。

文件与缓冲区的区别

常会说“我们正在编辑一个文件”,但真实情况并不是这样,我们所编辑的只是文件在内存中的映像,也就是 Vim 术语中的“缓冲区”。

:ls命令会列出所有被载入到内存中的缓冲区的列表

用 :bn 和 :bp 来遍历缓冲区列表

参数列表

参数列表易于管理,适用于对一批文件进行分组,使其更容易访问。

参数列表记录了在启动时作为参数传递给Vim的文件列表。

默认情况下所有参数都被放在全局参数列表下,

但是你可以使用 :arglocal 命令去创建一个新的本地窗口的参数列表。

使用 :args 命令可以列出当前参数。使用 :next:previous:first:last 命令可以在切换在参数列表中的文件。通过使用 :argadd:argdelete 或者 :args 等命令加上一个文件列表可以改变参数列表。

窗口

分割窗口

截屏2021-01-07 下午1.49.22

窗口切换

截屏2021-01-07 下午1.54.25

关闭窗口

:close

标签页

标签页是可以容纳一系列窗口的容器

截屏2021-01-07 下午1.59.51

切换标签

标签页的编号从1开始,我们可以用 {N}gt 命令在标签页间切换,可以把此命令记成“跳到标签页{N}”

如果省略了数字前缀,则会跳到下一个标签页。gT 命令的功能与此相同,只是跳转方向相反

移动

对字符进行查找

f{char} 命令是在 Vim 中移动的最快方式之一。它会在光标位置与当前行行尾之间查找指定的字符,如果找到了,就会把光标移到此字符上;如果未找到,则保持光标不动

Vim会记录上一次执行的查找命令,再次查找时可以使用 ; 命令来完成相同查找。

如果查询跳过头了,可以使用 , 命令返回光标之前的位置

f{char}  :  正向移动到下一个{char}所在位置
F{char}  :  反向移动到上一个{char}所在位置
t{char}  :  正向移动到下一个{char}的前一个字符上
T{char}  :  反向移动到上一个{char}的后一个字符上

基于单词移动

截屏2021-01-07 下午2.09.56

基于行的移动

截屏2021-01-07 下午2.06.40

跳转文件首行

vim普通模式下,使用 gg 跳转到当前文件的第一行;

vim命令行模式下,使用 :0:1 跳转光标到当前文件的首行。

跳转文件尾行

vim普通模式下,使用 G 跳转光标到当前文件的最后一行 (尾行); vim命令行模式下,使用 :$ 跳转光标到当前文件的尾行。

跳转文件任意行

vim普通模式下,使用 nG 跳转光标到当前文件的第 n 行。

vim命令行模式下,使用命令 :n 跳转光标到当前文件的第 n 行。

在匹配括号间跳转

% 命令允许我们在一组开、闭括号间跳转

标注

你可以使用标注功能来标记一个位置,也就是记录文件某行的某个位置。

标注 设置者 使用
a-z 用户 仅对当前的一个文件生效,也就意味着只可以在当前文件中跳转
A-Z 用户 全局标注,可以作用于不同文件。大写标注也称为「文件标注」。跳转时有可能会切换到另一个缓冲区
0-9 viminfo 0 代表 viminfo 最后一次被写入的位置。实际使用中,就代表 Vim 进程最后一次结束的位置。1 代表 Vim 进程倒数第二次结束的位置,以此类推

如果你想定义当前文件中的标注,可以先按下 m 再按下标注名。比如,按下 mm 就可以把当前位置标注为 m。在这之后,如果你的光标切换到了文件的其他位置,只需要通过 'm 或者 ``m`即可回到刚才标注的行。

按键 跳转至
'[ 与 ``[` 上一次修改或复制的第一行或第一个字符
'] 与 ``]` 上一次修改或复制的最后一行或最后一个字符
'< 与 ``<` 上一次在可视模式下选取的第一行或第一个字符
'> 与 ``>` 上一次在可视模式下选取的最后一行或最后一个字符
'' 与 ``'` 上一次跳转之前的光标位置
'" 与 ``"` 上一次关闭当前缓冲区时的光标位置
'^ 与 ``^` 上一次插入字符后的光标位置
'. 与 ``.` 上一次修改文本后的光标位置
'( 与 ``(` 当前句子的开头
') 与 ``)` 当前句子的结尾
'{ 与 ``{` 当前段落的开头
'} 与 ``}` 当前段落的结尾

寄存器

Vim 的寄存器是一组用于保存文本的简单容器。 它们既可像剪贴板那样,剪切、复制和粘贴文本;也可以记录一系列按键操作,把它们录制成宏。

类型 标识 读写者 是否为只读 包含的字符来源
Unnamed " vim 最近一次的复制或删除操作 (d, c, s, x, y)
Numbered 09 vim 寄存器 0: 最近一次复制。寄存器 1: 最近一次删除。寄存器 2: 倒数第二次删除,以此类推。对于寄存器 19,他们其实是只读的最多包含 9 个元素的队列。这里的队列即为数据类型 queue
Small delete - vim 最近一次行内删除
Named az, AZ 用户 如果你通过复制操作存储文本至寄存器 a,那么 a 中的文本就会被完全覆盖。如果你存储至 A,那么会将文本添加给寄存器 a,不会覆盖之前已有的文本
Read-only :.% vim :: 最近一次使用的命令,.: 最近一次添加的文本,%: 当前的文件名
Alternate buffer # vim 大部分情况下,这个寄存器是当前窗口中,上一次访问的缓冲区。请参阅 :h alternate-file 来获取更多帮助
Expression = 用户 复制 VimL 代码时,这个寄存器用于存储代码片段的执行结果。比如,在插入模式下复制 <c-r>=5+5<cr>,那么这个寄存器就会存入 10
Selection +* vim *+剪贴板 寄存器
Drop ~ vim 最后一次拖拽添加至 Vim 的文本(需要 "+dnd" 支持,暂时只支持 GTK GUI。请参阅 :help dnd:help quote~
Black hole _ vim 一般称为黑洞寄存器。对于当前操作,如果你不希望在其他寄存器中保留文本,那就在命令前加上 _。比如,"_dd 命令不会将文本放到寄存器 "1+*
Last search pattern / vim 最近一次通过 /?:global 等命令调用的匹配条件

引用一个寄存器

我们可以通过给命令加 "{register} 前缀的方式指定要用的寄存器。若不指明,Vim 将缺省使用无名寄存器。

将文本存到指定的寄存器中: 命令 "aY 可以将当前行复制,并存储到寄存器 a 中。这时移动光标至其他位置,通过命令 "AY 就可以把这一行的内容扩展到寄存器 a 中,而之前存储的内容也不会丢失。

系统剪贴板

Vim的加号寄存器与系统剪贴板等效,

程序中用剪切或复制命令获取了文本,就可以通过 "+p 命令(或在插入模式下用 +)将其粘贴到Vim 内部。

可以在 Vim 中录制一系列按键,并把他们存储到寄存器中。

对于一些需要临时使用多次的一系列操作,把它们作为宏保存起来会显著地提升效率。

对于一些复杂的操作,建议使用 Vim 脚本来实现。

q 键既是“录制”按钮,也是“停止”按钮。

  • 首先,按下 q,然后按下你想要保存的寄存器,任何小写字母都可以。比如我们来把它保存到 q 这个寄存器中。按下 qq,你会发现命令行里已经显示了 "recording @q"。
  • 如果你已经录制完成,那么只需要再按一次 q 就可以结束录制。
  • 如果你想调用刚才录制的宏,只需要 [count]@q
  • 如果你想调用上一次使用的宏,只需要 [count]@@

串行执行

5@a

并行执行

:1,5normal @a

模式匹配

查找

普通模式下,按下 / 键会调出 Vim 的查找提示符,可在它的后面输入要查找的模式或者原义文本。另外,只有当我们按下 键时,Vim才会执行查找命令

当我们使用 / 键执行一次查找时,Vim将进行正向扫描。

而如果是用 ? 键调出查找提示符的话,Vim则会进行反向查找。

n 命令用于跳转到下一处匹配,而 N命令则用于跳转到上一处匹配。

在普通模式下,* 命令让我们可以查找光标下的单词。

替换

substitute是一个ex命令,允许我们先查找一段文本,再用另一段文本将其替换掉。

命令的语法如下所示: :[range]s[ubstitute]/{pattern}/{string}/[flags]

pattern

模式,可以使用正则

将substitute命令的查找域留空,意味着Vim将会重用上次的查找模式。我们可以利用这一特点精简工作过程。

flags

标志位 g使得 subsititute 命令可在全局范围内执行,即可以修改一行内的所有匹配,而不仅仅是第一处匹配。 标志位c让我们有机会可以确认或拒绝每一处修改。 标志位 n 会抑制正常的替换行为,即让 Vim 不执行替换操作,而只是报告本次substitute 命

统计次数

%s///gn

其他

vimrc 文件

.vimrc 是控制 vim 行为的配置文件,位于 ~/.vimrc

前缀键

各类 vim 插件帮助文档中经常出现 ,即,前缀键。vim 自带有很多快捷键,再加上各类插件的快捷键,大量快捷键出现在单层空间中难免引起冲突,为缓解该问题,引入了前缀键

按键映射

递归 非递归 模式
:map :noremap normal, visual, operator-pending
:nmap :nnoremap normal
:xmap :xnoremap visual
:cmap :cnoremap command-line
:omap :onoremap operator-pending
:imap :inoremap insert

经验法则:除递归映射是必须的,否则总是使用非递归映射。

The Ultimate vimrc

Key Mappings

map <C-j> <C-W>j
map <C-k> <C-W>k
map <C-h> <C-W>h
map <C-l> <C-W>l

Plugin

map <leader>z :Goyo<cr>

vim-surround

NERD Tree

map <leader>nn :NERDTreeToggle<cr>

其他软件的vim模式

vscode

​ Easymotion

​ 多光标模式

​ "workbench.action.showCommands",

pycharm

chrome

zsh

tmux

参考

vim 配置方案 https://github.com/amix/vimrc

插件管理 vundle https://github.com/VundleVim/Vundle.vim

vscode vim插件 https://github.com/VSCodeVim/Vim

vim 配置方案 https://github.com/SpaceVim/SpaceVim

<<Vim 使用技巧>>

⚠️ **GitHub.com Fallback** ⚠️