写给女朋友的vim练级指南

·  阅读 252

前言

本文内容侧重于为习惯在现代IDE环境中开发的程序员提供vim操作模式入门和提高的学习路线。笔者认为,现代IDE已经足够先进和便捷,而众所周知vim难度高学习曲线非常陡,使用纯粹的vim编辑器并不是vim新手的最佳学习途径,新手容易在一大堆零散命令以及操作技巧中受到打击。

对于vim新手来说,依托IDE的vim插件,在比较轻松的环境下练习肌肉记忆以及vim思维方式,不失为一种合适的选择。而且,在IDE的vim插件中练就的操作,几乎全部都是适用于纯粹的vim编辑器的,不必担忧这是错误路线,因此如果你还有20%的意愿选择想学习vim,请跟随本文设计的路线进入练习,笔者保证在经过少数的练习时间后,得到的回报是200%的。既可以在IDE中使用vim模式优雅修改代码,也可以得心应手地在远程服务器等cmd环境中使用vim编辑器。

Tips: vim起源于Unix下的vi和ed编辑器,它们比鼠标以及所有可点击界面出现的都要早,因此,“不用点击” “纯键盘操作”等基因被延续了下来。vim就像学习弹钢琴一样,经过陌生到熟悉的阵痛期,将会体验到vim那句口号“以思维的速度去编辑代码”的成就感。

环境准备

本文使用的IDE是Android Studio,插件是Intellij IDE平台通用的IdeaVim,插件版本1.9.2。

安装完重启后,IDE右下角即有一个绿色渐变的图标V表示已启用了vim模式,如果是灰色V则表示关闭了vim模式,点击即可以打开插件菜单。这里有一项比较重要的,Enabled启用和关闭vim模式,当遇到目前积累的vim知识不足以实现手头比较紧急的修改任务时,暂时点击关闭。

菜单Open ~/.ideavimrc打开配置文件,可以修改vim的默认行为,增加一些帮助提高效率的插件等,vim是高度可定制化的,IdeaVim插件的自定义配置保存在系统用户目录(Mac示例:/Users/youzi)下的.ideavimrc文件中,该目录下可能还有另一个文件叫.vimrc,没错它是系统中的vim编辑器的配置文件。

现在先进行一项重要的配置:与系统共享剪贴板。相信如果之前用过vim可能会遇到一个情况,在浏览器中<⌘+c>别人的一段代码,使用粘贴操作却无法粘贴到vim(使用<⌘+v>更不可以呀),同样的在vim中使用复制操作复制的文本,也没法在浏览器软件中<⌘+v>出来,非常影响效率,这是因为vim有独立的一套剪贴板,在vim中称为寄存器(古老吧,就当作剪贴板看待),话不多说,增加一项配置:

set clipboard^=unnamed,unnamedplus
复制代码

使配置生效可以重启IDE,但如果是通过菜单Open ~/.ideavimrc在IDE中打开配置文件,编辑区右上角会有一个悬浮按钮可以快速应用新的配置。

为了保持纯粹,这里不再做过多配置,行文中会再次安利一些其他vim配置,酌情添加。

---- 下面正文开始 ----

第一阶段

认识几种模式

vim与可点击编辑器不同的是区分了几种模式,因此与其他编辑器不同,开始使用vim之前不是尝试去敲键盘看效果,而是要先看说明书,这里借用笔者的vim编辑器启蒙博客的一段经典的开始:

  1. 刚启用IDE vim插件时,vim处于Normal模式下
  2. 按下按键i,此时进入了可编辑状态,也就是Insert模式
  3. 现在可以输入文本进行编辑文件了
  4. Esc,返回了Normal模式
  5. 按下按键v,此时发现光标所在的字符底色是选中的蓝色,也就是可视选择状态,类似于按住了鼠标左键
  6. 使用键盘↑←↓→即可控制选中的范围
  7. Esc,返回了Normal模式
  8. 键盘输入冒号:,此时处于命令模式,编辑区的底部会有一条命令输入栏,输入的字符都会作用在这里,在命令模式可以输入一些控制指令
  9. 再输入w,回车,这个在vim编辑器中表示write写入文件,也就是保存指令,在IDE中没有多大意义(IDE会自动保存修改),这里只是展示一下命令模式,输入命令回车后,会回到Normal模式
  10. 处于命令模式时,可以直接按Esc返回Normal模式,而放弃输入命令

在IDE中,可以通过光标的形状判断当前处于Normal还是Insert模式,矩形光标表示正处于Normal,常规的竖线光标表示正处于可编辑状态的Insert模式。

Esc是救命键,如果不知道自己正处于什么模式,多按几次Esc就回到了Normal模式。对比其他文本编辑器,Vim设计的几个模式咋看起来很奇怪甚至可能会觉得多余,这里打个比方,就像一个画家在画画,Insert模式时画家在画板上挥毫勾勒作品,但画家每画几笔,也要停下来思考构图,画家在思考时可能会想刚刚画下的那笔需要移个位置、刚刚那笔应该使用朱砂着色,思考相当于Normal模式,而vim比画板高级,它可以在思考模式下把刚刚写的代码移动位置、全局替换单词等许多功能。对于程序员来说,绝大多少时间并不是在输入代码,而是在思考和阅读代码,在代码中穿梭跳转,即使涉及到修改,也不一定非要在Insert模式,Normal模式下复制、替换、移动或是删除代码也是更加常见的场景。

本小节的目标是认识vim当前所处的状态,以及各个模式之间的切换,领会之后可以进入下以小节。

Tips:如果在vim编辑器环境而非IDE练习,除了知道切换模式,还需要知道怎么退出。多按Esc确保在Normal模式,输入:q!回车;冒号进入命令模式,q表示quit退出,!叹号表示放弃所有更改。

认识基础常用的操作符与动作命令

这一小节的名称可以先不必理解,需要注意的是练习以下每个操作符与命令的前提,都是先把编辑器EscNormal模式。

vim风格的移动命令

前面介绍按v进入可视选择状态时,移动光标使用的是键盘的方向键,其实vim也有自己的方向键,右手键区的h j k l分别代表的就是← ↓ ↑ →,记忆方式可以想象j是向下的箭头。使用h j k l还是← ↓ ↑ →都可以,这只是个习惯问题。现在可以在编辑器Normal模式(或者按v在可视选择状态)中体会一下h j k l精确移动光标。

除了逐字符移动光标,还可以按w移动到下一单词开始处、或者e移动到下一单词结尾处(注意e的行为跟光标当前是否在单词结尾相关)。现在可以在编辑器Normal模式(或者按v在可视选择状态)中体会vim对单词的定义,单个或连续的符号被当作一个“单词”。

以上动作命令可以结合数字,实现更快的移动:例如想注释(或移动)当前光标所在行和往下5行,则可以按如下操作

  1. v进入可视选择
  2. 5j使光标向下移动5行
  3. <⌘+/>注释代码(或使用IDE的移动代码功能Shift+Option+上下方向键移动这6行代码)

这里再配上几个移动命令,偶尔会派上用场:

  • 0 -> 数字0表示移动光标到行首
  • ^ -> 移动到行首第一个非空字符(空字符就是blank字符:空格、回车换行、tab)
  • $ -> 到行尾
  • g_ -> 到行尾最后一个非空字符
  • 实际的代码编辑场景下,其实$g_更常用和方便输入

练习以上的移动命令,在小范围精确移动光标的场景下多练习,加深印象。

到这里为止,可能你还不能丢开触控板,还是习惯滑动和点击到特定的代码位置才会开始vim相关操作,这没有关系,在讲完下一小节的常规复制、粘贴、剪切(删除)后,再继续学习更符合人类思维习惯更快速的移动命令。

Tips: IDE本身支持显示代码行号,可是在使用数字加j k上下移动时,难道要口算加减法吗?显然有点费力。点击右下角图标V -> Open ~/.ideavimrc打开配置文件增加一行:

set clipboard^=unnamed,unnamedplus
"我是vimrc的注释,新增下面这行,注意没有逗号
set number relativenumber
复制代码

最后记得应用vimrc的更改。解释一下,number让编辑界面展示绝对行号,再结合使用relativenumber,最终把非光标所在行的行号改为 1 2 3 4 5...

vim的复制粘贴

这里的复制粘贴,依然是在Normal模式下讨论的。

首先停下敲键盘,眼熟一遍按键:y表示复制;p表示粘贴;d表示剪切(删除);u表示撤销一次操作(这里介绍它是方便重复练习使用~)。因为接下来输入的很多操作会需要2个及以上的按键输入组合才能实现,现在有必要先介绍一下IDE的右下角状态栏有一个显示已经输入命令的位置:

cmd_status_bar.png

如图所示,当前笔者输入了y2。这个有助于知道是不是已经有已输入但没结束的指令(换个说法 是不是误触键盘,导致在Normal模式输入了一些乱七八糟的“指令”),如果这里存在不想要的输入,按Esc即可清除。

现在先结合可视选择来使用y p d操作,这对于原本习惯鼠标操作的程序员是比较友好的。下面以复制粘贴操作讲解,d剪切与y复制类似,剪切的内容同样到了vim的剪贴板,不再赘述。

Normal模式下,光标定位到期望复制的开始处,按v进入可视选择,再按移动命令选中想要的,如$选中到行尾,或者按N次hjkl控制光标移动去选中,接着按y即完成复制,同时退出了可视选择回到了Normal模式。再移动光标到期望粘贴的地方,按小写p粘贴到光标所在字符之后,按大写P粘贴到光标所在字符之前。

接着放弃可视选择的帮助,直接去执行复制和剪切指定的代码段,这需要使用组合命令了。

Normal模式下,光标定位到期望复制的开始处,按y,表示打算复制内容,接着输入移动命令即完成了复制。举一些例子:ye从光标位置复制到单词结尾、y$从光标位置复制到行尾,y3e从光标位置复制到第三处单词结尾,^y2e定位光标到行首接着复制前两个单词。可以发现,没有可视选择的支持,控制光标移动都是一步到位,不能再输入N次移动命令选好再y复制这样玩了。到现在为止,可以看出 越熟练控制光标移动,操作vim的效率会越高。

练习<移动光标><操作><移动光标>的组合命令,虽然到目前还是不能做到媲美触控板的效率,但是已经实现变强的第一步了~~

如果还记得前面我们设置过vim与系统共享剪贴板,那现在可以试一下在vim之外复制粘贴啦。

回到标题,现在可以来厘清操作符和动作命令了。移动光标的是动作命令,而刚刚学习的复制粘贴剪切即是操作符。vim强大的根源,很大部分就是体现在操作符 + 动作命令 = 操作这个语法规则中。

这个语法规则也有一些例外,这里举一些常用的操作:

  • yy 复制当前行
  • 3yy 复制包括当前行的三行
  • dd 剪切(删除)当前行
  • 3dd 剪切(删除)包括当前行的三行
  • >> 当前行增加缩进
  • 3>> 包括当前行的三行增加缩进
  • << 当前行减少缩进

第二阶段

再谈模式切换

前面从Normal模式进入Insert模式只介绍了按键i,这显然是不够的,IDE的<Shift+↵>新起一行等操作在代码编辑中特别常用,下面介绍从Normal模式进入Insert模式的更多常用命令。

插入模式命令不多,并且都是成对出现的,很方便记忆:

  • i Insert,在光标前插入
  • a Append,在光标后插入
  • I 在当前行首的非空字符前插入
  • A 在当前行末插入
  • o 在当前行的下面插入空行
  • O 在当前行的上面插入空行

可以总结一下vim命令的一个规律,向后和向下等方向是方便输入的小写字母,向前和向上是对应的大写字母。

以上这些是纯粹的插入指令,vim还有一种更加常用的指令c,在Normal模式下删除所选范围的代码再进入Insert模式,换个说法就是替换,它的用法与y复制d剪切类似,搭配移动光标的组合命令实现快速删除并进入Insert。 下面的示例演示指令c的用法:

  • cw 替换当前光标位置到单词结尾的内容
  • c$ 替换当前光标位置到行尾的内容(只输入大写C也是同样效果,但是,不建议初学记忆太多)
  • cc 替换当前行
  • 3cc 替换三行
  • v 3j c 可视选择这个老朋友在这里也是可用的

说完NormalInsert,也许读者已经注意到,vim命令都要在Normal下使用,那在编辑模式中突然想执行命令可不可以呢?像平时写代码,写着写着<⌘+v>粘贴个代码不是非常常见吗,Insert切换到Normal粘贴了再切换回Insert很显然就不舒服了。vim提供了Insert模式临时输入命令的切换手段,这就是Insert-Normal模式,这名字取的就跟没取一样,要从Insert模式切换到Insert-Normal模式,输入<⌘+o>,接着就可以输入命令了例如p粘贴一下代码,命令执行完,会自动回到Insert模式。

现在可以更加符合期望地切换到Insert去继续修改代码啦~ 即使还不能丢开触控板,但是相信已经对vim少了许多的畏惧和抵触。

重复

日常写代码中实际上是存在许许多多的重复性操作的,例如为一个HashMap添加一堆埋点的key-value,在IDE中我们会使用<⌘+d>复制多行put(key, value)再做修改。vim对重复的处理除了上面演示的数字组合命令,如yy5p复制当前行并粘贴5次,还有vim中的.命令,它可以让我们非常方便地重复上次的修改,这个“上次的修改”可以很简单,也可以很复杂,一次修改的单位可能是字符,一个单词,一整行甚至整个文件。

可以尝试在输完一次操作后,按.,看下vim会如何重复上一次的操作,这里先留给读者探索感受,后文会对.命令这个vim的多面手再做深入介绍。

更快地移动光标

以查找代替移动

对于上面的基础移动操作,在实际使用IDE浏览代码的过程中肯定是效率很低的,相信在IDE中常常是<⌘+f>查找来移动目光到想要的位置,这一小节就来讲讲vim的查找。

首先介绍在光标所在行内的查找,键入fa表示从当前光标位置开始,向后查找当前行的第一个字符a,如果找到了光标会移过去字符a的位置,如果没有则光标不会改变位置,类似的三个查找命令还有:

  • Fa向前查找第一个字符a
  • ta向后查找当前行的第一个字符a,如果找到了光标会移过去字符a的前一个字符位置
  • Ta向前查找当前行的第一个字符a,如果找到了光标会移过去字符a的后一个字符位置 还可以结合数字实现查找第x个:
  • 2fa向后查找当前行的第2个字符a

别忘了结合y dc等操作的练习,举个例子,要复制if (event.code == Option.isSuccess())中if的条件内容,当前光标在=处,目前可以这样操作:T( y 2t)

接下来看对标IDE的<⌘+f>查找的vim实现。键入/,此时编辑器底部出现了命令模式的命令输入栏,接着键入想搜索的内容,回车即可将光标定位到搜索结果的第一个,按n跳转到下一个结果,按N则跳转上一个结果。到这里也许会问,命令模式怎么粘贴啊,就算搜索的是一个单词,纯手打又慢又容易出错。

想要在命令模式下粘贴内容到命令输入栏,就要用到vim寄存器的概念了,假设现在已经复制了想要搜索的内容,键入/,接着按<⌘+r>,再按数字0,即可粘贴vim的0号寄存器的内容到命令输入栏了,更多关于寄存器的概念这里先不了解。

依赖代码结构的光标移动

有时候我们可以不必用到上面的查找指令来达到类似的效果,像代码中的变量名、方法名等独立的单词(指前后有空格的一整块),当光标在单词上时,按*即可跳转到该单词下一个出现的位置,按#即可跳转到该单词上一个出现的位置,这在查变量或者方法使用时可以很快捷地跳转。

vim提供了%命令,可以在一组开、闭括号间跳转,默认情况下,%可作用于() [] {},如果想要复制、替换的是代码块,现在可以很方便选中啦,即使是地狱嵌套的代码,也不用睁大眼睛看辅助线和IDE高亮去匹配括号了~

区域选择

前面介绍了这么多光标移动操作,无非就是在践行<移动光标><操作><移动光标>这条组合命令,但vim能做的不仅仅是这些,对于选中想要的代码这件事,除了通过前后光标的位置来确定,还有另一种更优雅的方式。

vim有一个文本对象(text-objects)的概念,文档解释是基于结构定义的文本区域,听起来有点迷茫,大概的意思可以近似理解为“被引号、括号、空格括起来的文本区域”。由于此功能先讲容易糊涂 一看便清楚,先上例子:

Normal模式,下面这句代码,当前光标在 Util 的 U 处
mViewModel.timeStr.set("CreateTime: ${TimeFormatUtil.format(date.time)}")

1. 想选中set方法内的整个字符串,可以键入 vi) 或者 va"
2. 想选中TimeFormatUtil,可以键入 viw,接着还想进一步选中{}内的内容,可以键入 i}
3. 想替换{}内的内容,可以键入 ci{ 或者 ci}
复制代码

聪明的小朋友可能已经看出来是什么情况了,接下来看看区域选择的语法格式:

  • <action>i<object>
  • <action>a<object> 这里的<action>表示想要对文本区域执行的操作,它可以是v选择、y复制、c替换并进入编辑、d删除;i或者a表示选取的范围是否包含选区边界;<object>表示某种结构,可以是w表示一个单词、括号的左或右、t表示xml标签。ia加上<object>,就是所谓的文本对象了。

区域选择也是可以结合数字使用的,再贴个例子理解一下:

text_objects.jpg

如果小朋友还是很迷茫,不知道区域选择快在哪,这里可以演示一个简单的例子:yiw复制当前光标的单词,然后光标定位到另一个单词,viwp就粘贴替换掉另一个单词啦。相比通过移动光标去控制选取,区域选择是不是更舒服了呢~ 先用着常见的<object>,只要熟练度上来了,了解更多的<object>只是看一眼就会的事。

浏览:滑动与跳转

触控板与鼠标滚轮的滑动是我们习以为常的操作,IDE还准备了<⌘+g>跳转到指定行数,这些在vim模式下依然都可用,不过既然现在要提高效率,手不用在键盘和触控板来回切换,还是有必要学习一下vim中可以怎么实现滑动的。

首先是三个比较简单少用的

  • 812G 跳转到第812行
  • gg 跳转到文件第一行
  • G 跳转到文件最后一行 笔者比较常用的代替触控板的操作是下面几个命令的组合运用:
  • <⌘+d> down,向下翻半屏
  • <⌘+u> up,向上翻半屏
  • zz 让光标所在行在编辑区居中显示
  • zt top,让光标所在行大概位于编辑区顶(够看就行,好像不会位于最上一行) 以上的翻页足够用于浏览代码了,差不多看到目标代码后再加上zzzt,即可准备开始修改操作了。

因为我们是基于IDE vim模式进行的操作,或许你已经看到过这个提示:

key_map_switch.png

在vim模式下,首次使用vim与IDE都定义过的组合键时,会弹出这个提示说该快捷键现在用于vim命令啦,这也是在IDE的vim模式操作比较尴尬的点,因为可能会面临两难的选择:到底我该把组合键给IDE用还是给vim用🤣 举个例子:<⌘+b>在IDE中是快速跳转到光标所在的变量或方法的定义位置或使用位置,在vim中也有类似的命令gdgD,但用了就会发现跟IDE的<⌘+b>没法比啊,所以把<⌘+b>留给IDE用吧~ vim中的<⌘+b><⌘+f>是一对,表示backward向下滑动一整屏 forword向上滑动一整屏,留一个或都不留都是没啥问题的,根据自己的喜好来选择即可。

点击右下角图标V -> Settings...打开IDE的设置,如下图所示,在这里可以自由设置组合键该给谁使用。

key_handler.png

到这里已经学会了笔者日常使用中90%的vim功能啦,为了不增加记忆负担,行文中只挑特别紧要的命令讲解,勤加练习比死记硬背更有效~

下一部分会讲解命令模式的部分实用场景,以及补全前面埋下的一些需要重点讲解的操作,不用着急进入下一阶段,练习上面的知识才是最有效的提高方式。

第三阶段

查找并替换

前面练习区域选择的时候举了一个例子:yiw复制一个单词,viwp替换掉另一个单词,那如果再执行viwp还奏效吗?你会发现执行了一次viwp后vim的默认剪贴板已经变了,那如果要替换多处要怎么做呢,这里介绍vim的substitute命令(记住名字中里一个s就行了)。

在IDE中智能修改变量名可以使用组合键<Shift+F6>,现在我们来舍近求远,用另一种方式给当前文件的某变量改一下名。

光标定位到变量名,yiw复制一下,键入:进入命令模式,接着输入%s/,接着<⌘+r>再按数字0粘贴刚刚复制的变量名到这里,接着输入/新的变量名/gc,回车,此时编辑区会选中待修改的位置,命令输入栏会提示询问是否使用新的变量名替换这个位置,这里我们按y同意此位置修改n跳过此位置修改,完整选项含义后文再列出。

看一下整体输入的命令:

  • :%s/old/new/gc 手动控制将文件中的old替换为new
  • :%s/old/new/g 不询问直接将文件中的old替换为new,比较危险,因为hold也会中招

单词old的位置是支持正则匹配的,写一些常规的正则匹配感觉应用场景不多,写精确的匹配式又复杂了,还不如想点别的办法完成操作,因此这里不做介绍了。

  • y 替换此处匹配
  • n 跳过此处匹配
  • q 退出匹配
  • l last,替换此处匹配后就退出
  • a all,替换此处以及之后的全部匹配

隔空复制、移动

我们要复制或改动某处代码,下意识的操作是把光标移过去,从前是触控板,现在是vim移动命令,但是如果我们能用目光焦点去移动代码块,不费力气去想怎么移动光标,是不是编辑效率就能更接近大脑的思考速度了呢,vim在命令模式下提供了移动m和复制t的指令,两个指令的记忆方式:move移动、copy To复制到某处。

语法:

  • :[range]m{position}
  • :[range]t{position}

可以看到两个指令使用上是完全一致的。[range]是需要移动或者复制的行号或行号范围,可选,缺省是当前光标所在行;{position}是目标行号,可以用.表示当前行。这里对[range]说明一下,行号既可以是绝对行号,也可以是相对行号,因此不管前面有没有设置vimrc显示相对行号,都不会影响使用。

举几个例子:

  • :12t. 把第12行(绝对行号)的内容复制到当前行
  • :t12 把当前行内容复制到第12行
  • :8,12t. 把第8到12行的内容复制到当前行
  • :8,12t96 把第8到12行的内容复制到第96行
  • :t. 等价于yyp,复制并粘贴当前行

上面是绝对行号的例子,相对行号需要配合+-号来表示:

  • :-10,-2t+2 把往上第10到往上第2行的内容复制到往下第2行

现在,无需考虑怎么移动光标以及怎么选中,即可完成内容的复制和移动啦~ 如果觉得输入指令比较累,键入:后是可以使用↑↓方向键调出历史指令的,修改一下旧指令即可。

标记跳转

IDE有Bookmarks功能,vim也有类似给代码某个字符位置添加标记的功能,并且在vim中允许我们通过命令快速跳转到标记。

Normal模式下键入m和一个用于标记的字母(区分大小写),标记成功后,使用`和标记的字母即可跳转回标记的位置。用于标记的字母,a-z是文件范围内的标记,A-Z是全局可跳转的标记,纯粹的vim编辑器没有支持将标记处特别显示,在IDE中,如果使用了A-Z的全局标记,效果是和Bookmarks一样的,会在行首显示标记字母。vim还会自动为我们标记好上次修改的位置,使用`.可以方便的跳转到上次修改的地方。

有关vim的其他跳转技巧,笔者认为IDE的Double Shift更加灵活方便,这里就略过不提。

高效率的重复

前面介绍了.命令,它可以重复上次的修改,想要最大效率地利用这个重复,则需要比较巧妙的规划好"一次修改",理想的状态下,我们希望是一键可以移动到下一处修改位置,然后用.一键完成修改,再一键移动到下一处。

因为移动命令会切割"一次修改",所以目前想要提高.的效率,可以从减少不必要的移动开始着手,思考自己的操作是否是符合以上的一键移动一键修改这个期望。

举个例子,现在期望在光标所在行以及往下的2行末尾增加分号,如果使用以下操作步骤:

  1. $ 到行尾
  2. a 光标后插入,输入分号,<Esc>
  3. j 移动到下一行
  4. 重复步骤1、2

可以发现,这里1和3都是在移动光标,我们可以使用上面学过的A来把1 2合成一步,这样就减少了移动的操作,变成了下面的样子:

  1. A 行尾插入,输入分号,<Esc>
  2. j 移动到下一行
  3. . 命令重复
  4. j 移动到下一行,. 命令重复 当把不必要移动收进一次修改中之后,再结合j或10j等一次移动去重复修改,.命令才能发挥更大的优势。

结语

以上是学习路线的全部内容,完结撒花✿✿ 本文是为女朋友梳理一条切实可行的vim入门路线,对于个别操作的介绍没有面面俱到,如果你跟随本文掌握了全部的使用技巧,问接下来该做什么,笔者的建议是命令模式:help多看看vim的文档。祝变得更强!

参考文献

[1] 陈皓.简明VIM练级攻略[EB/OL].(2011.09.07).[2022.03.30].https://www.coolshell.cn/articles/5426.html
[2] Drew Neil.Practical Vim[M], 2012
复制代码

分类:
开发工具
标签:
收藏成功!
已添加到「」, 点击更改