vi-vim-cheat-sheet-sch

这里仅做我已经掌握的命令的记录,更多命令学习还是要参照之前列出的学习教程

vimtutor

目前笔记主要来源vimtutor

移动、选择相关

按键/命令效果
h
j
k
l
H移动到屏幕顶行
J合并当前行和下一行
L移动到屏幕底部
G移动到文件结尾。 10G,移动到文件从头开始的第10行。
gg移动到文件开头。10gg,移动到文件从头开始的第10行。
<C-g>查看当前光标所在文件、行列信息
wword,跳转到下一个单词头部
eend,跳转到下一个单词尾部
bback,跳转到上一个单词头部
W(大写w)跳转到下一个单词头部,但是仅将空格视为单词分隔符
E跳转到下一个单词尾部,但是仅将空格视为单词分隔符
B跳转到上一个单词头部,但是仅将空格视为单词分隔符
0(数字)移动到行首
M(大写m)移动到窗口中间
{跳转到段首
}跳转到段尾

插入/打开相关

按键/命令效果
i在光标前插入
I(大写i)在行首插入
a在光标后插入
A在行尾插入
o在光标所在位置的下方打开新的一行,并进入插入模式
O(大写o)在光标所在位置的上方打开下新的一行,并进入插入模式

删除相关

删除通常是组合命令,例如d作为删除指令的操作符,后跟其他命令达到组合效果

按下d之后,界面最底部会提示你已经按下了d,它在等待第二个按键的按下

按键/命令效果
x删除光标所在字符
d操作符,删除指令的第一步操作
dw即d + w,删除从光标所在单词直到下一个单词头部
de即d + e,删除从光标所在单词直到单词尾部
db即d + b,删除光标所在单词直到上一个单词头部
dW
dE
dB
dd删除整行
d$删除从当前光标到行尾
D删除从当前光标到行尾

删除类命令的格式为

plaintext
1
d   [number]   motion

正常模式命令基本结构

plaintext
1
operator   [number]   motion

其中:
operator - 操作符,代表要做的事情,比如 d 代表删除
[number] - 可以附加的数字,代表动作重复的次数
motion - 动作,代表在所操作的文本

计数操作

数字可以和命令搭配,达到重复的效果,例如:

2w向后跳转两个单词

d2w向后删除两个单词

d10d删除10行

10dd也是删除10行

撤销操作

按键/命令效果
u撤销一步
U将当前行撤销到原始状态
<C-r>意思是ctrl + r,撤销 执行过的 撤销命令
这里需要注意,该命令是针对于撤销命令的,而不是针对于文本的
撤销操作相当于一个栈,每执行一次撤销操作就入一次栈
<C-r> 则是针对此进行出栈,因此只针对于撤销命令有效
所以你只能在撤销之后执行<C-r> ,而不能指望平白无故对文本执行“重做”

置入命令

vim中最后一次被删除的内容会被保存到寄存器中

按键/命令效果
p将寄存器内容粘贴到光标之后
P(大写p)将寄存器内容粘贴到光标之前

替换与更改

按键/命令效果
r替换字符。替换操作符,在光标处按下r之后,光标会变成下划线闪烁
此时可以将任意字符替换光标处字符
R进入到替换模式,连续替换字符直到按下esc。
c更改。更改操作符,在光标处按下c之后,光标会变成半方块闪烁
此时可以按下其他组合命令
更改本质上其实就是删除到指定位置 + 进入插入模式
cec + e。替换光标至单词尾部的内容。
首先会删除光标处到单词尾部内容,然后进入插入模式
cwc + w。替换光标到下一个单词头之前空格的内容。
c0c + 0。替换光标到行首的内容。
c2ec + 2 + e。
c$c + $。替换光标到行尾的内容。
C(大写c)相当于c$
s删除字符并进入插入模式
s$删除到行尾并进入插入模式
s2删除两个字符并进入插入模式‘
S相当于s$

更改类命令的格式是:

 C   [number]   motion

上/下一次跳转位置命令

按键/命令效果
<C-o>o即older。光标回到上一次跳转的位置。
<C-i>i即inner。光标回到下一次跳转的位置。

注意这里的跳转动作是指“光标跳转”这类光标突然移动的行为,像是hjkl、web等有规律的依次移动不会被记录跳转。

会被记录到跳转历史中的操作:

  1. 文件切换:使用 :e:split:vsplit 等命令切换文件时,光标位置会被记录。
  2. 标签跳转:使用 Ctrl + ] 跳转到标签定义,或者使用 Ctrl + T 返回时,光标位置会被记录。
  3. 搜索跳转:使用 *#nN 等搜索命令跳转到匹配项时,光标位置会被记录。
  4. 函数跳转:使用 Ctrl + i 跳转到函数定义,或者使用 Ctrl + o 返回时,光标位置会被记录。
  5. 书签跳转:使用 m 设置书签,然后使用'或` 跳转到书签时,光标位置会被记录。
  6. 光标跳转:G、gg、H(跳转到窗口顶部)、L(跳转到窗口底部)

不会被记录到跳转历史中的操作:

  • 普通模式下的光标移动:使用 hjkl、方向键或鼠标移动光标时,这些操作不会被记录到跳转历史中。
  • 文本编辑操作:例如插入、删除、替换等操作,也不会被记录为跳转动作。

另外,跳转历史的记录是具有唯一性的,某一个位置只会被记录一次,且更新的时刻会取代旧的时刻。例如反复使用H和L,再进行<C-o>时会发现光标并不会按照H和L的反复行为而反复跳动,而是仅按照最后一次H和L的顺序挑动了一次。

<C-o>和 <C-i> 本身不会更改跳转历史记录,它只是相当于一个跳转历史记录链表里的一个指针。

搜索相关

按键/命令效果
f{char}搜索并跳转到光标所在行,光标之后任意单一字符,执行一次就会自动失效
F{char}搜索并跳转到光标所在行,光标之前的任意单一字符,执行一次就会自动失效
;执行上一次的f系列命令,也就是说你可以f{char}之后按下;继续刚才的查找
/{anyword or char or something}进入查询模式,后面输入你任意想查询的内容。按下回车之后,会跳转到光标所在之后的第一个匹配项,且会自动高光所有匹配项,
?进入查询模式,反向查找
n跳转到查询模式下的下一个匹配项。即使使用了:noh关闭了高亮,当你按下n时,光标还是会跳转到你上一次查询模式下的匹配项,且开启匹配高亮
N反向跳跃
*快速进入查询模式,查询光标所在单词。

普通模式下按/进入查询,此时页面下方也出现了/符号,等待你输入要查询的内容。

输入内容之后,所有匹配项会被打上高亮。若内容存在,按下回车,光标会自动跳转到当前光标之后的第一个匹配的位置,之后若按下n则跳转到下一个匹配项,按下N则调转到上一个匹配项。匹配跳转是循环的,即最后一个匹配项的下一个是整体的第一个匹配项。

?则进入反向查询,光标会自动跳转到当前光标之前的第一个匹配的位置。

n也是可以加数字的,vim中几乎所有命令都可以加数字

搜索过程中的跳转也会记录到跳转历史

输入 :set xxx 可以设置 xxx 选项。一些有用的选项如下:

  'ic' 'ignorecase'	查找时忽略字母大小写
  'is' 'incsearch'	查找短语时显示部分匹配
  'hls' 'hlsearch'	高亮显示所有的匹配短语

例如:set hls is ic 会将搜索结果高亮,且显示部分匹配内容,且忽略大小写

  1. 在选择项前加no则是关闭选项,例如:set noic关闭大小写忽略
  2. 如果在搜索之后想要关闭高亮,使用:noh:nohlsearch即可,比:set nohls更简短
  3. 如果只是想在单次查询中忽略大小写,而不是一直开启这个选项,在输入被查询短语之后加上/c即可,例如\myword/c

搜索的设计目的是为了光标跳转,因此光标跳转到了用户预期的位置即可,所以没有设置诸如按下回车代表“用户找到了指定位置并关闭搜索功能”这样的设计

调用shell命令

:! + shell命令,用于在vim窗口下直接执行单条shell命令,输入完毕之后按回车开始执行,执行完毕提示按回车或其他按键返回,注意不要按esc。

:term用于在vim窗口分割出一个新窗口,启动一个内置的终端模拟器,进入到vim的终端模式。这个命令允许用户在 Vim 编辑器中直接运行一个交互式的 shell 或其他终端程序,而无需离开 Vim 环境。这在需要同时编辑文件和运行终端命令时特别有用。在终端模式下,按下<C-ww>进行terminal和vim编辑器内容的跳转

PixPin_2025-06-02_23-55-23

vim内部用来执行shell命令的shell是可以通过修改vim配置文件进行设置的,具体设置方式见vim安装及简单配置

帮助类命令

按键/命令效果
:help xxx查看关于xxx按键或命令的解释
<C-d>:下输入命令时,当你忘记了命令的全名称,你可以按下ctrl+d来查看匹配的所有可能的命令列表
{TAB}按下tab键,可以自动补全命令并列出一行供选择的自动补全命令,再次按下tab进行下一个选择。按下空格或者回车进行确认。简而言之,他就像是shell的tab命令补全一样。

help只能解释vim内部的命令

ctrl + dtab则可以对外部命令也生效

比如在:!运行shell命令时,你也可以用ctrl + d和tab。显然这个是调用的外部shell的补全列表

但是我发现当我将shell换成了nushell时,我在nushell配置文件中设置的自定义命令没有办法被补全,这个怎么配置之后还需要进一步进行研究

Vim实用技巧

从这里开始是通过阅读《VIm实用技巧第二版》(《Practical Vim》)时记录的笔记,和上面的vimtutor笔记一样,不全,因为无法一次性理解和记下所有的技巧,这本书应该反复阅读。

1.普通模式

.操作

.操作能重复执行上次进行的修改,可以用ESC主动表示一次修改的完毕

;命令

重复执行之前执行过的f查找相关命令,包括F、T、t

例如对于下面文档

javascript
1
var foo = "method("+argument1+","+argument2")";

试图将+左右两边加上空格

执行的操作是这样:

f+找到光标之后的第一个+

s删除光标所在字符并进入插入模式,输入”空格+空格”,按下ESC,表示一次修改完毕

;重复执行刚才进行f查找的字符+,光标定位到所在位置

.重复刚才的修改,即s空格+空格

之后反复 ; 和 . 直到完成所有修改

PixPin_2025-06-04_22-38-30

以退为进的思想

上面的操作中,一般来看可能首先想到的是直接向+左右增加空格,但是实际上我们执行的是先删除+,再插入”空格+空格”,退一步而进了三步,这样可以让一个完成的修改命令被.记录下来,更方便之后的重复执行。

合而为一的思想

image-20250604225653142

有时候无需输入就可以完成查找和修改

*可以直接查询光标所在单词

n进行跳转

cw change word

修改完之后再次n,然后.执行刚才的修改

之后n.直到所有目标被修改完毕

PixPin_2025-06-07_13-37-54

.范式

从上面给出的例子来看,vim执行编辑,最理想的模式就是:用一个按键移动,另一个按键执行。

而.通常用于执行,因此这种理想编辑模式可以称之为.范式

尝试向.范式靠拢,构造可重复的修改

当可能会进行一些重复性操作时,执行修改最好在一步完成

例如现在光标放在了一个单词除开头外的任意位置,如何删除这个单词?

  1. 反向删除

    image-20250607141435406

    使用db(delete back)删除当前光标至离其最近的”上一个单词开头”的所有内容,现在还剩下光标所在位置的一个字符没被删除,使用x删除光标所在字符。

  2. 正向删除

    image-20250607141706412

    使用b跳转到单词开头,dw删除光标所在位置开始整个word的所有内容

  3. daw

    a可以理解为一个文本对象的选择,aw指光标所在的一个word文本对象

    daw可以看作delete a word

    但是注意,daw 和 d1w 或 d2w不是一个概念,a是一个特有的文本对象标记

    image-20250607143019857

    a也可以理解上“光标所在位置的’all’对象”

vim中的单词(word)与字串(WORD)

单词word:是指由iskeyword选项定义的字符串。即由字母、数字或下划线组成的非空白字符序列,它们之间用空白字符或标点符号分隔

字串WORD:是指用空白符分隔的字符串。

单个字符当然也会被看做成一个单词。

很多小写的命令都是针对于单词的,而大写的则针对于字串,如w和W,e的E,b和B等

vim普通模式设计哲学

与很多编辑器刚开始就是插入模式不同,vim的默认模式是普通模式(normal)。

就像是闲庭信步一样,普通模式是vim最舒适的模式。

vim设计普通模式的哲学之一,就是“画家大部分的时间并不是在画画”,而是在进行构思、调配颜料之类的操作,当他执行用画笔画画的时候,说明已经决定实在要添上几笔了。而添上几笔也不一定用画笔,可能是用棉棒稍微修改一下不满意的地方,可能是用颜料将一大片画好的地方清空等。程序员编码也如此,回想一下,你可能百分之七十的时间都是用来思考,百分之十的时间用来修改,百分之二十的时间是在敲代码。

所以vim的普通模式也是如此,很多你不必进入到插入模式完成的操作,例如删除、查询、替换等,在普通模式下通过几个按键就可以完成,且还用诸如.等范式让你的工作更轻松。

就像画家只花一小部分时间涂色一样,程序员也只花一小部分时间编写代码。绝 大多数时间用来思考、阅读,以及在代码中穿梭浏览。而且,当确实需要做修改时, 谁说一定要切换到插入模式才行?我们可以重新调整已有代码的格式,复制它们,移 动其位置,或是删除它们。在普通模式中,我们有众多的工具可以利用。

​ —-《practical vim》

加减操作

按键/操作效果
<C-a>add,如果光标所处位置是数字,则为其+1
<C-x>如果光标做出位置是数组,则为其-1

可以为加减操作之前加上次数

PixPin_2025-06-07_15-08-42

执行、重复、回退–更灵活的处理方式

通过上面的理解,我们可以认识到,先进行一次修改,然后重复他,可以很大程度上减少按键次数。

同时,为了更灵活的处理,比如不小心多执行了一次操作,可以进行一次撤销。但是问题是,“一次操作”的粒度怎么设定?

重复有时候比用次数更好

plaintext
1
there is a word with two apple.

如果我们想删除”with two apple”,有几种显而易见的操作方法

首先想到的可能是最一劳永逸的d3w,这样可以一次性删除这三个单词;

另外3dw或许也是一个不错的选择:执行三次dw;

当然也可以这样:dw..,先执行一次dw,之后重复两次。

让我们比较一下这三种方式,前两种按键次数最少,特别是当我们要删除更多的单词的时候;而且这两种操作在撤销上的粒度是一样的:将删除三个单词视作了一次修改。也就是当我们按下u时候,被删除的三个单词都恢复了。

最后一种方式则是按键次数最多的,且它的粒度是删除一个单词。

看起来是不是前两种方式更好?但是事实上,当单词更多时,我不得不先用肉眼数一下要删除的单词的数量,我还要确保我正确输入了这个数量,如果删除多或少了,我执行撤销,则全部的修改都恢复了,工作回到起点。

但是如果我用了看似更多的按键次数的第三种处理方式—-重复,我可以“肆无忌惮”地执行差不多次数地重复修改,如果我删除了过多的单词,我只需要再撤销几次就行,因为我的粒度足够细。

所以有时候看起来更懒地“次数”操作,效率或许不如“重复”操作,这也契合了我们所说的“执行、重复、回退”这一思想。

2.插入模式

插入模式只专注于做一件事,那就是输入文字

插入模式下的删除

如果你已经进入了插入模式,发现自己输入些错误,如果错误发生在距离光标较近的单词末尾,直接按下退格键进行删除即可,但是如果问题出现在单词的头部,专业的打字员给你的建议是将这个单词删除然后重新拼写,它的效率要比以下两种方式更快:1.回到普通模式然后db 2.使用方向键移动到单词开头使用del键删除;或者按下多次退格键删除这个单词。

首先,回到普通模式需要你先按下esc,其次,执行完删除操作,你还需要再进入插入模式,这一连串会打断你的操作,甚至会打断你的心流。如果你选择用方向键,我的建议是,vim中最好舍弃方向键,它太远了,而且不优雅。

很多情况下,不需要模式的切换,当你位于插入模式下时:

按键/命令效果
<C-h>删除光标所在前一个字符,相当于退格键
<C-w>删除光标所在的前一个单词
<C-u>删除至首行

这些命令不是插入模式所独有的,甚至也不是 Vim 所独有的,在 Vim 的命令行模 式中,以及在 bash shell 中,也可以使用它们。

PixPin_2025-06-11_15-57-51

其他的切换回普通模式的方式

插入模式只专注于做一件事,那就是输入文字,而普通模式却是我们大部分时间 所使用的模式(顾名思义),因此能快速在这两种模式间切换是很重要的。

其他模式下,比如可视模式、插入模式,回到插入模式下,经典方式是使用<ESC>

但是这个按键还是有点远,插入模式下还有其他的方式进行模式的切换:

按键/命令效果
<ESC>返回普通模式
<C-[>返回普通模式
<C-o切换到 插入-普通模式

但是我觉得ctrl键也不容易按到

Vim 区分模式的特点在下面这种特定场景中却显 得有点烦琐:当我们处于插入模式时,想运行一个普通模式命令,然后马上回到原来 的位置继续输入。Vim 为此提供了一种巧妙的方法,以减少模式切换所带来的不畅, 这就是插入-普通模式。

插入-普通模式

插入-普通模式是普通模式的一个特例,它能让我们执行一次普遍模式命令。在此模式中,我们可以执行一个普通模式命令,执行完后,马上就又返回到插入模式。

要从插入模式切换到插入-普通模式,可以按<C-o>

在当前行正好处于窗口顶部或底部时,有时我会滚动一下屏幕,以便看到更多的上下文。用zz命令可以重绘屏幕,并把当前行显示在窗口正中,这样就能够阅读当前行之上及之下的半屏内容。

我常常会键入<C-o>zz,在插入-普通模式中触发这条命令。此操作完成后就会直接回到插入模式,因此我可以不受中断地继续打字。

tips

如何将外部剪切板的内容粘贴进vim

"*p按键将外部剪切板(通常是系统剪切板)的内容粘贴进vim光标处

Vim语法的额外规则:连续使用两次操作符命令

Vim 的语法只有一条额外规则,即当一个操作符命令被连续调用两次时,它会作用于当前行。所以 dd 删除当前行,而 >> 缩进当前行。gU 命令是一种特殊情况,我们既可以用 gUgU ,也可以用简化版的 gUU 来使它作用于当前行。

gU将内容转变为大写,如gUaw将光标所在单词转为全大写。