vim
一直是程序员之间比较有争议的一个话题。有人认为她是编辑器之神,有人则认为她古老过期,远远不如IDE,或是以当红小生vscode
为表明的图形化文本编辑器。不管爱恨,咱们的开发工做,大到远程登陆服务器coding
,修改config
文件,小到git commit message
,或多或少总要接触她。git
为何要写这篇blog呢,是由于我发现各大平台充斥的vim
教程类blog其实很不友好,大多数是命令的堆砌,不多有对思想的解读。由此形成的结果,不少工程师对vim
老是敬畏三分,或者就算部分人可使用vim
,也只是以本身的固有思惟,结合vim的命令操做,并无真正掌握vim
的精髓。因此我尝试用本身的方式,试图帮助你们系统地创建起vim
的知识系统。程序员
文章主要结构以下:shell
vim
编辑器最简单、基本的操做,让你快速入门,在遇到vim
时,能够不至于惊慌,从容完成任务。若是想到某些操做,好比经常使用的复制、粘贴之类,能够到第二部分查找对应高阶操做,按部就班使用vim
。vim
一系列高级操做,将咱们的效率最大化。注:这部分信息量较大,建议您在阅读部份内容后,快速浏览不熟悉的命令,作到心中有数;随后可前进到第三部分;回过头来,再按部就班,边学边练。vim
思想的精髓,既让咱们真正对vim
的操做融会贯通,又让咱们能够在使用其余IDE/编辑器时应用这些思想,甚至在咱们本身设计、实现功能、组件时,都能进行应用。这才算真正掌握了神器vim
。vim有三个模式,分别为普通(正常)模式、插入模式以及命令模式。vim
i
等命令进入插入模式。:
后,能够发现,屏幕的右下角会出现:
,此时便进入了命令模式。本文中使用:
开头的命令,即可视为输入:
进入命令模式后,输入后面的字符,执行命令。不少人对于vim
的第一点疑惑,便来源于此。咱们习惯了图形化编辑器下,始终处于插入状态。然而在vim
中,大多数状况下,咱们会处于正常模式。只有当须要输入字符时,进入插入模式;当须要使用命令时,进入到命令模式。在插入和命令模式下,输入Esc
即可返回正常模式。一张图归纳以下:服务器
注:后文讲解,如无特殊说明,均为普通模式下操做。编辑器
若是不追求效率,只想完成修改文件的任务,并保存退出,只须要掌握如下三个命令:工具
h j k l
最简单的移动,至关于键盘上面的方向键,分别对应左下上右。i
ZZ
(注意区分大小写)流程以下:布局
h j k l
移动到想要修改的位置i
进入插入模式,此时经过输入(字母、数字、符号),删除(Backspace)等,完成基本修改操做Esc
回到普通模式,ZZ
,保存修改并退出。普通模式下,vim
的命令主要分为如下三种:spa
动做,用以移动光标,或者定义操做的范围;好比:插件
h
:定义操做范围为一格,单独使用时,向左移动光标一格。w
:定义操做范围为一个单词,移动光标到下一个单词首部。操做,这种命令须要在后面接表示操做范围的指令;
d
,删除,后接表示一个单词操做范围的w
,即dw
时,表示删除到当前词尾。c
,修改,后接表示一个单词操做范围的w
,即cw
时,表示修改当前单词。(编辑器行为表现为,删除到当前词尾,同时进入插入模式)。命令,直接执行的命令,其中一部分,在执行命令后,直接进入编辑模式;好比:
D
,删除至行末。I
,到行首进入插入模式。 咱们的使用方式主要也是三种:命令、动做、操做+动做。 此外,在动做类的命令前,加上number
为可选项,可实现重复n次
的效果:[number] + h/j/k/l
向左/下/上/右
移动number
个字符。好比,'2j',向下移动光标2个字符。
依旧使用d
和w
来举例,d
是删除,w
是单词,dw
表明删除一个单词,d2w
表明删除两个单词。后面的命令,大多均可应用此种形式组合使用,你们多注意,养成这种操做 + [次数] + 范围
的思惟模式,触类旁通,即可发挥最大功效。
这里有仅大小写不一样的两组命令,两组命令的功能,是相同的:跳转光标到对应位置。可是对应的单位不一样,分别为word
和string
。具体区别是:
string
仅以空格分开;
word
以字母数字之外的字符分开。
以这个字符串为例:hello world-hehe111 abcde
word
有5个,分别为hello
world
, -
, hehe111
和abcde
。
string
有3个,分别为hello
world-hehe111
和abcde
。
两组命令以下:(跳转光标至)
w
下一个单词开头e
当前或下一个单词结尾b
当前或上一个单词开头ge
上一个单词的结尾W
下一个字符串的开头E
当前或下一个字符串结尾B
当前或上一个字符串的开头GE
上一个字符串的结尾举个例子,当光标位于hehe111
的第一个字符h
时,先后的单词/字符串信息以下:
前一个 | 当前 | 后一个 | |
---|---|---|---|
单词 | - | hehe111 | abcde |
字符串 | hello | world-hehe111 | abcde |
那么以上各个敲击以上各个命令的结果,便一目了然(加粗字表示命令运行后光标位置):
0
移动到当前行行首
^
移动到当前行的第一个非空字符
$
移动到当前行尾
(
跳转到当前或前一个句子的开头
)
跳转到当前或下一个句子的结尾
{
跳转到当前或前一个段落的开头
}
跳转到当前或下一个段落的结尾
这里段落很容易理解,是以空行分隔开的。句子麻烦些,是按照句号来算的。
记得在这些命令前添加 d
试一下效果吧,掌握操做+范围
这种命令形式吧。
gg
移动到文本第一行行首G
移动到文本末行行首[n] + %
:按百分比近似定位到某行,该行位于整个文件的n%
处[n] + gg/G
跳转到第n
行,经常使用。要想用好上述几个命令,有两个简单的建议:
ctrl-g
。该命令的做用是显示当前行的位置信息(第几行,相对整个文本行数的百分比)。~/.vimrc
中添加以下代码片断set nu " 显示行号
set cursorline " 高亮光标所在行</pre>
复制代码
H
:屏幕顶部行首M
:屏幕中央行首L
:屏幕底部行首ctrl-d/u
:前进/后退半页ctrl-f/b
:前进/后退整页ctrl+e
:上滚一行ctrl+y
:下滚一行zt
:使光标所在位置移动到屏幕的顶部(全部内容作位移)zz
:使光标所在位置移动到屏幕的中央(全部内容作位移)zb
:使光标所在位置移动到屏幕的底部(全部内容作位移)f+单个字符
:在本行内向右移动到指定字符F+单个字符
:在本行内向左移动到指定字符t+单个字符
:在本行内向右移动到指定字符的前一个字符T+单个字符
:在本行内向左移动到指定字符的前一个字符%
: 在“( )”、“[ ]”、“{ }”类符号的首尾间切换*
和 #
: 匹配光标当前所在的单词,移动光标到下一个(或上一个)匹配单词(*是下一个,#是上一个)。m+[a~z]
:在当前光标作标记,如ma'+[mark]
:光标返回指定标记所在的行,如'a
,则光标返回到标记a
所在行首ctrl+o
:跳转回光标前一个位置ctrl+i
:跳转回较新的光标位置:marks
:显示所有mark:delmarks [mark]
:删除指定marki
:在光标前插入字符I
:在行首插入字符a
:在光标后插入字符A
:在行尾插入字符o
:在光标下发插入空行O
:在光标上方插入空行c
:修改,后面须要接范围
c+w
:删除光标位置单词,并进入插入模式
c+l / s
:删除光标位置字符,并进入插入模式
c+c / S
:删除光标所在行,并进入插入模式
c+$ / C
:删除光标位置到行尾的字符,并进入插入模式
r
: 替换当前字符。
R
:(进入replace模式)持续替换光标所在字符,直到使用ESC退出替换模式。
x
: 删除当前位置或下一个位置的字符。
d
:删除,属于动做指令,后面须要加操做类指令。好比以下命令:
de
:删除到当前单词结尾。dw
:删除到下一个单词开始。de
的区别在于,dw
会删除两个单词之间的空格。daw
:删除一个单词,包含单词的边界(空格)。d0
:删除至行首。d$ / D
:删除至行尾。da[
:删除[ ]整个块,包含符号自己;
di[
:删除[ ]块,不包含符号自己;
da/di +
' " { ( 等,也与接[相似,删除整个区块。惟一须要注意的,"和'仅仅在行内。
dt[x]
:在本行,删除到[x]。好比,dt"
删除到双引号,dtf
,删除到字母f
。 d/foo
:在全文, 删除到 “foo” 。
剪切操做其实就是咱们以前讲的删除。也就是d
。删除的内容,默认会存放到剪切板中。也就至关于进行了剪切。
从这里你们能够看出,i
和a
的做用比较特殊,表明与区块相关的某种操做。区别就在于,i
不包含区块边界符号。a
包含。这两个操做符很重要,在后面的复制操做中还会用到。此外还有t
,/
。此外,i
和a
还能够接t
,此时t
表示一对xml标签。i
:区块,不包含边界。a
:区块,包含边界。t
:"to",本行到哪里。/
:接匹配,全文到哪里。
p
:粘贴到光标后,或下一行。P
:粘贴到光标前,或前一行。为何会有光标先后或上下一行两种状况呢?是由于咱们复制或剪切的内容有多是字符串或者整行:
y
,复制,属于操做,后面须要接动做来标识复制的范围。好比:
yw
:复制到当前单词结尾。ye
:从当前位置复制到本单词的最后一个字符。y$
:复制到当前行尾。yy
或Y
:复制当前行。nyy
:复制从光标所在行起的n行,注意n在最前面。0y$
: 命令意味着:
0
→ 先到行头y
→ 从这里开始拷贝$
→ 拷贝到本行最后一个字符固然也能够结合咱们刚刚介绍的进阶操做符来进行操做:
yi"
:复制两个引号之间yit
:复制两个xml标签之间y/[x]
:复制到x。vim 有 12 个剪切板,分别是 0、一、二、...、九、a、“、+。:reg
:查看各个剪切板里的内容。y
,p
默认使用 "剪切板中的内容。 "[n]y
:复制到剪切板n
中。"[n]p
:粘贴剪切板n
中的内容。
查看是否支持系统剪切板:
vim --version | grep "clipboard"
复制代码
观看输出中,clipboard
前面是+
仍是-
。如果-
,则说明不支持系统剪切板。 +
号剪切板比较特殊,是系统剪切板,用于与系统其余应用互动:
"+y
,将内容复制到系统剪切板,ctrl+v
将其粘贴到其余应用中,好比vs code
。"+p
,将其余应用中复制的内容,粘贴到vim中。v
:进入可视模式。V
:进入行选择模式。Crtl + v
:进入块选择模式。
进入可视模式后,能够经过以前的移动操做,来进行选择。好比:hjkl
:先后左右选择。$
:选择到行尾。i"
:选择两个引号之间。
选择后,可使用
d
进行删除/剪切,y
进行复制。gU
:变大写。gu
:变小写。J
:把全部的行链接起来(变成一行)。<
或 >
:左右缩进。=
:自动缩进 。=
:调整格式化缩进。gg=G
:全文代码格式化。
gg
,到文章开头=
,调整格式G
,到文章结尾。编辑模式下Ctrl + n/p
出现提示,此时会出现补全的选项。按住Ctrl
不放,用n
和p
来遍历提示选项,到达期待的选项后,无需其余操做,继续输入便可。
u
:撤销前一个动做U
:撤销当前行的一系列动做CTRL-R
:Redo,意思就是我又不想撤销了。/
: 查找,此时Terminal左下角会出现/
,在后面输入想要查找的内容,回车便可。?
:反向查找,一样道理,左下角会出现?
。/[search]\c
:忽略大小写。好比:/test\c
,查找test,忽略大小写n
: 下一个匹配N
: 前一个匹配命令模式下:
s/old/new/
:用new
替换old
s/old/new/g
:全局替换set hlsearch
:高亮搜索结果qa
操做序列 q
, @a
, @@
qa
把你的操做记录在寄存器 a。
@a
会replay被录制的宏。@@
是一个快捷键用来replay最新录制的宏。:w
:保存修改:wq
:保存修改并退出ZZ
:保存修改并退出q!
:不保存修改,强制退出e!
:不保存修改,强制从新打开当前文件你们能够看到,
!
的做用便在于,强制。除此之外,他还有另外一个很强势的功能,就是执行shell命令。具体信息,你们能够详细阅读下一节。
.
:重复执行前一个命令。这个命令很灵活、实用,建议多多尝试。:help [command]
:查看某命令的help此外,在命令行中执行以下命令,即可进入vim的教程。vimtutor
复制代码
这是vim
的一个很神奇的功能,在编辑的时候能够与外部文本互动,甚至执行一些shell
命令。
:w [file-name]
:将当前内容输出到指定文件中
:r [file-name]
:将另一个文件的内容输出到当前位置
:e filename
:vim下打开指定文本
ctrl+w, s
:水平拆分窗口
ctrl+w, v
:垂直拆分窗口
ctrl+w, ARROW(h,j,k,l或方向键)
:在窗口间切换光标。
ctrl+w, w
:在窗口间切换光标。
:qa
:关闭全部窗口。
:saveas
:另存为。
:n/bn/bp
:在打开的多个文件间切换。
:![command]
:vim下执行某shell命令。
好比,:!ls
,便会暂时切换到shell下,输出当前目录的文件名。此时输入回车,即可退回当前vim
编辑的文件中。
若是你以为这种输入命令的方式还不够过瘾,vim
还提供了保留当前工做现场,直接进入shell的方式。这种命令一个典型的工做场景是,如咱们编辑了一个文件,可是发现没法保存(没有写权限),此时能够先进入到shell下,执行相似chmod u+w [filename]
,的命令,为当前用户获取该文件的写权限,而后再回到 vim 保存刚刚的修改。 有以下两种方法:
:shell
或 :sh
,当退出当前 shell 时(好比exit
),就会回到 vim。ctr-z
进入 shell,fg
退回 vim。这部分主要是一些vim的config。能够直接命令模式输入,也能够保存到~/.vimrc
中,即可每次打开vim
自动应用。(其中一些命令是互相冲突的,请自行选择有用的命令)。
syntax on # 开启语法高亮
set nu[mber] # 显示行号
set nonu[mber] # 隐藏行号
set cursorline # 高亮当前行
set ruler # 显示光标位置信息
set noruler # 隐藏光标位置信息
set hlsearch # 高亮匹配
set nohlsearch # 取消高亮匹配
nohlsearch # 临时取消高亮(只取消一次查询的高亮)
set incsearch # 在输入字符串过程当中显示匹配点
set nowrapscan # 找到文尾后中止查找
set wrapscan # 恢复为到文尾后自动从头开始
set ic/ignorecase) # 忽略大小写
set noic/noignorecase # 区分大小写</pre>
复制代码
这部分主要是一些我在使用vim
过程当中的一些思考和感悟,试图尽力阐述出来。若是你们能有一些思考和收获,说明个人思考是有意义的。若是你们有不一样看法,十分欢迎拍砖交流。
ctrl-c/v
,也就是咱们熟悉的copy & paste. 若是你平时注重效率,养成了快捷键的习惯,还可能知道一些诸如ctrl-a/x/s/w
等。不知你注意到没有,如刚刚列举的不少快捷键,都由 特殊的命令符+字母
构成。由于在此时,键盘上的大多数按键,都是能够输入到文本中的字符。而在vim
的正常模式下面,没法直接向文件中输入这些字符,至关于不用按ctrl
等特殊的命令符,直接能够把这些按键,用做命令的快捷键。HJKL
。虽然移动将手移动到键盘上的方向键,并未真正的浪费多少时间,可是其对思惟的打断,其实很是影响效率。d
deletec
changew
worde
endb
backI
editf
findr
replace快捷键应有尽有,各个维度移动,都切合使用者思惟,几乎能够作到”指哪儿打哪儿“。 好比,移动、删除、复制、等等操做,均可以结合精细化的位置,根据符合人类思惟的不一样维度,进行操做。 好比,字符,单词,行,文章,屏幕,匹配(位置、文字、符号),以及相似书签的Mark等。
vim
的大部分快捷键,都是原子操做,并经过与范围结合,排列组合,灵活多变,完成各类强大的功能。这也与unix
的主要思想契合:每一个命令作好,且只作好同一件事。 与此同时,经过用数字和宏,代替无心义的重复。 此外,对一些经常使用操做,提供了现成的宏,方便操做。好比,dd
,是删除整行,同时也能够直接用D
来完成。I
,A
等,也是相似道理。
相似栈的思路,能够放下当前操做,保存现场,而后进入另外一个操做。当操做完成后,回到当前现场。
vim
的快捷键,或者说命令,不只很符合咱们的思惟,并且还能在很大程度上扩展咱们的思惟。 拿编辑代码时最多的操做,移动光标来讲。原来咱们的移动,基本就是经过键盘的方向键,上下左右,或者经过鼠标,移动到想要去的位置。而在vim中,你会发现,光标除了上下左右,还能够移动到词首,词尾,句首,句尾,行首,行尾,页面首部,页面中部,页面尾部,文档首部,文档尾部,文档任意一行,甚至还能够移动到某个指定字母,某个tag,匹配大、中、小括号。度过最初的不适应后,经过刻意练习和平常使用,肌肉造成记忆,便无需刻意回想是用什么命令,而是潜意识完成操做。掌握了这些命令后,当你使用原来的编辑器时,也会去寻找这些快捷键。这就不只仅是使用vim时候提供效率了,而是经过提升编辑操做的意识、思想,提升了总体的工做效率。
使用vim一段时间后,我在其余工具中进行编辑时,编再也没法忍受,一个一个自读地移动光标。因而也会主动去找单词、行级别移动的快捷键。
cmd + ←/→
移动到:当前行首/尾部alt + ←/→
移动到:当前单词首/尾部ctrl + f/b
前进/后退一个字符Esc + f/b
前进/后退一个单词ctrl + a/e
行首/行尾ctrl + h/d
删除光标前/后一个字符ctrl + w
删除光标前一个单词ctrl + k/u
删除光标前/后全部内容ctrl + y
粘贴以前删除的内容这篇文章到这里也就结束了,洋洋洒洒写了这么多,一次读下来就接受,很难;仅仅经过阅读就掌握,更难。想要真正用熟vim
,掌握思想,须要后续更多思考、实践。可是相信我,这些付出,必定是值得的。由于它不只能让你掌握一个开发利器,更能带给你颇有价值的思想。