vim-note

这里仅做我已经掌握的命令的记录,更多命令学习还是要参照之前列出的学习教程
vimtutor
目前笔记主要来源vimtutor
移动、选择相关
按键/命令 | 效果 |
---|---|
h | 左 |
j | 下 |
k | 上 |
l | 右 |
H | 移动到屏幕顶行 |
J | 合并当前行和下一行 |
L | 移动到屏幕底部 |
G | 移动到文件结尾。 10G,移动到文件从头开始的第10行。 |
gg | 移动到文件开头。10gg,移动到文件从头开始的第10行。 |
<C-g> | 查看当前光标所在文件、行列信息 |
w | word,跳转到下一个单词头部 |
e | end,跳转到下一个单词尾部 |
b | back,跳转到上一个单词头部 |
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 | 删除从当前光标到行尾 |
删除类命令的格式为
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之后,光标会变成半方块闪烁 此时可以按下其他组合命令 更改本质上其实就是删除到指定位置 + 进入插入模式 |
ce | c + e。替换光标至单词尾部的内容。 首先会删除光标处到单词尾部内容,然后进入插入模式 |
cw | c + w。替换光标到下一个单词头之前空格的内容。 |
c0 | c + 0。替换光标到行首的内容。 |
c2e | c + 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等有规律的依次移动不会被记录跳转。
会被记录到跳转历史中的操作:
- 文件切换:使用
:e
、:split
、:vsplit
等命令切换文件时,光标位置会被记录。 - 标签跳转:使用
Ctrl + ]
跳转到标签定义,或者使用Ctrl + T
返回时,光标位置会被记录。 - 搜索跳转:使用
*
、#
、n
、N
等搜索命令跳转到匹配项时,光标位置会被记录。 - 函数跳转:使用
Ctrl + i
跳转到函数定义,或者使用Ctrl + o
返回时,光标位置会被记录。 - 书签跳转:使用
m
设置书签,然后使用'
或` 跳转到书签时,光标位置会被记录。 - 光标跳转: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
会将搜索结果高亮,且显示部分匹配内容,且忽略大小写
- 在选择项前加no则是关闭选项,例如
:set noic
关闭大小写忽略 - 如果在搜索之后想要关闭高亮,使用
:noh
或:nohlsearch
即可,比:set nohls
更简短 - 如果只是想在单次查询中忽略大小写,而不是一直开启这个选项,在输入被查询短语之后加上
/c
即可,例如\myword/c
搜索的设计目的是为了光标跳转,因此光标跳转到了用户预期的位置即可,所以没有设置诸如按下回车代表“用户找到了指定位置并关闭搜索功能”这样的设计
调用shell命令
:!
+ shell命令,用于在vim窗口下直接执行单条shell命令,输入完毕之后按回车开始执行,执行完毕提示按回车或其他按键返回,注意不要按esc。
:term
用于在vim窗口分割出一个新窗口,启动一个内置的终端模拟器,进入到vim的终端模式。这个命令允许用户在 Vim 编辑器中直接运行一个交互式的 shell 或其他终端程序,而无需离开 Vim 环境。这在需要同时编辑文件和运行终端命令时特别有用。在终端模式下,按下<C-ww>
进行terminal和vim编辑器内容的跳转
vim内部用来执行shell命令的shell是可以通过修改vim配置文件进行设置的,具体设置方式见vim安装及简单配置
帮助类命令
按键/命令 | 效果 |
---|---|
:help xxx | 查看关于xxx按键或命令的解释 |
<C-d> | 在: 下输入命令时,当你忘记了命令的全名称,你可以按下ctrl+d来查看匹配的所有可能的命令列表 |
{TAB} | 按下tab键,可以自动补全命令并列出一行供选择的自动补全命令,再次按下tab进行下一个选择。按下空格或者回车进行确认。简而言之,他就像是shell的tab命令补全一样。 |
help只能解释vim内部的命令
ctrl + d
和tab
则可以对外部命令也生效
比如在:!
运行shell命令时,你也可以用ctrl + d和tab。显然这个是调用的外部shell的补全列表
但是我发现当我将shell换成了nushell时,我在nushell配置文件中设置的自定义命令没有办法被补全,这个怎么配置之后还需要进一步进行研究
Vim实用技巧
从这里开始是通过阅读《VIm实用技巧第二版》(《Practical Vim》)时记录的笔记,和上面的vimtutor笔记一样,不全,因为无法一次性理解和记下所有的技巧,这本书应该反复阅读。
1.普通模式
.操作
.操作能重复执行上次进行的修改,可以用ESC主动表示一次修改的完毕
;命令
重复执行之前执行过的f
查找相关命令,包括F、T、t
例如对于下面文档
1 | var foo = "method("+argument1+","+argument2")"; |
试图将+左右两边加上空格
执行的操作是这样:
f+
找到光标之后的第一个+
s
删除光标所在字符并进入插入模式,输入”空格+空格”,按下ESC,表示一次修改完毕
;
重复执行刚才进行f查找的字符+,光标定位到所在位置
.
重复刚才的修改,即s空格+空格
之后反复 ; 和 . 直到完成所有修改
以退为进的思想
上面的操作中,一般来看可能首先想到的是直接向+左右增加空格,但是实际上我们执行的是先删除+,再插入”空格+空格”,退一步而进了三步,这样可以让一个完成的修改命令被.
记录下来,更方便之后的重复执行。
合而为一的思想
有时候无需输入就可以完成查找和修改
*
可以直接查询光标所在单词
n
进行跳转
cw
change word
修改完之后再次n
,然后.
执行刚才的修改
之后n.
直到所有目标被修改完毕
.范式
从上面给出的例子来看,vim执行编辑,最理想的模式就是:用一个按键移动,另一个按键执行。
而.通常用于执行,因此这种理想编辑模式可以称之为.范式
尝试向.范式靠拢,构造可重复的修改
当可能会进行一些重复性操作时,执行修改最好在一步完成
例如现在光标放在了一个单词除开头外的任意位置,如何删除这个单词?
反向删除
使用
db
(delete back)删除当前光标至离其最近的”上一个单词开头”的所有内容,现在还剩下光标所在位置的一个字符没被删除,使用x删除光标所在字符。正向删除
使用
b
跳转到单词开头,dw
删除光标所在位置开始整个word的所有内容daw
a
可以理解为一个文本对象的选择,aw
指光标所在的一个word文本对象daw
可以看作delete a word但是注意,daw 和 d1w 或 d2w不是一个概念,a是一个特有的文本对象标记
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 |
可以为加减操作之前加上次数
执行、重复、回退–更灵活的处理方式
通过上面的理解,我们可以认识到,先进行一次修改,然后重复他,可以很大程度上减少按键次数。
同时,为了更灵活的处理,比如不小心多执行了一次操作,可以进行一次撤销。但是问题是,“一次操作”的粒度怎么设定?
重复有时候比用次数更好
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 中,也可以使用它们。
其他的切换回普通模式的方式
插入模式只专注于做一件事,那就是输入文字,而普通模式却是我们大部分时间 所使用的模式(顾名思义),因此能快速在这两种模式间切换是很重要的。
其他模式下,比如可视模式、插入模式,回到插入模式下,经典方式是使用<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
将光标所在单词转为全大写。