之前在前东家为了完成每年的技术交流KPI任务,给公司里几个爱好者搞了个vim入门讲座。刚好有几页slides似乎对题,拿出来说说。
题主要动力,那就先洗一波脑,说说用VIM有啥好处。
首先是普及度,全平台制霸,除了windows其他主流系统基本预装。ipad里能用,安卓里也能用
其次各种IDE和主流编辑器都有vim模拟器,一次学习到处使用
大部分IDE和开发用的编辑器都能很方便地配置一键开vim(在纯vim里打开当前文件并且光标移动到同一位置),也就是说万一模拟器搞不定的功能,随时可以跳到纯vim里干。完事之后保存退出返回原本的IDE或者编辑器即可,由于vim启动速度极快,整个过程非常流畅。
动图尺寸太大显示不出来,具体例子可以看我的这个回答
同理,由于vim启动或退出都极快,我们可以轻易搞一个全局脚本,在任何输入框中开vim编辑,利用vim的编辑功能。
当然在网页文本框里嵌入vim(neovim)也是可以的。chrome的neovim插件比较酷炫但其实个人感觉还是有点坑(偶有泄露,nvim实例没有正常关闭),实际工作中我一般用 wasavi
总之还是那句,一次学习到处使用。就这一点在我看来无论学习曲线多高其实都已经值回票价了。
其他vim的使用细节就不一一谈了,题目问为什么vim在熟练的人手中会(看上去)神乎其技。我在交流课件中总结了三条(自以为的)“vim理念”:
第一,vim主打按键序列作为快捷键,而非使用组合功能键。
组合键的主要问题是,如果要使用全键盘流快捷键,功能一多,再考虑到快捷键的设置要有一定的表义,字母键不够用。而手指要一直按住功能键导致按键序列不能过长(一般二级快捷键到顶了),更多的组合花样只能在功能键上玩,windows有三个功能有7种按法,MacOS有四个功能键11种按法,问题功能键本身是不表义的,结果又回到了老问题上,记不住。
而按键序列本质上没有这样的问题,可以在保证表义的前提下可以有无限多种组合。无非就是常用的设短一点,不常用的搞长一点,慢慢按总比用鼠标选菜单快。比如我在IDE里“开纯vim”的快捷键就设成 `空格-v-i-m-空格`,五个键,但按起来非常顺手也很快。
近两年年纪大了小尾指感觉有点劳损,我干脆就把IDE的快捷键大部分都配成了空格打头空格结尾的按键序列,既表义按得又舒服。比如说我的intellij配置
你在旁边看我劈里啪啦一通乱敲全都是快捷键好像很牛逼哄哄,其实很好记,根本没啥心智负担。
第二,类似编程的编辑体验
这是吸引程序员的大杀器。使用vim编辑时,不要看成自己在码字,而是在用各种短命令去变换一坨数据(文本)。这一页列了几个我认为比较有代表性的点:
1) 使用一些基本元素来组合成复杂操作。比如说 【ciw】 (change in word)包含了三个元素,组成一个“修改当前单词”的操作,每个元素都可以自由替换,例如【diw】 (delete in word), 【caw】 (change a word), 【ci"】 (change in " )。看似花样很多其实组合逻辑很清晰。
另一个角度是,在vim里有些操作直接记组合比“记单个命令再组合”更自然。比如说,【xp】直接看成“交换两个字符”的固定组合,比看成“我先删除一个字符,再把它粘贴到下一个字符后面”要自然。同理交换两行,直接记【ddp】,在当前单词前加入字符,直接记【bi】,之后加字符直接记【ea】
还有一点值得一说的是,vim的指令设置是按照其逻辑脉络形成体系的,而不是根据具体需求进行功能拼凑。举例来说,vim里有个【r】指令,作用是不进入插入模式,直接替换光标上的单个字符。这个命令对于一些小修改,比如说大于号写错了改成小于号,减号改成下划线之类很好用。但是在选中模式下,它的效果是把所有选中的文本都改成同一个字符。逻辑上看,非常自然。选择文本后执行一些行级命令,就是对范围内每一行都执行该命令。那选择文本后执行字符级的修改命令,当然是对文本内每一个字符都执行该命令了。但有很长一段时间我都觉得这个特性没啥用。通常在用到重复单个字符的场景我都知道要用多少个,那如果我要用20个单一字符覆盖光标后的文本,我可以用【20R】,为啥要先选中20个,再一次性替换。直到有一天我看到有人这样写 markdown 的标题:
没想到这是个文本下划线的终极解决方案,但你要说当年r指令的设定是冲着这个用法来的,我是不信的。同样的道理,vim里你常常会发现有一些顺理成章但看似没啥用的设定,突然有一天在某个场景有奇效,连装插件都省了。
2)有丰富的定位和限定作用范围的命令
比如说到行首就有两种精确的定位命令,到绝对首列的 【0】,到第一个非空字符的【_】和【^】。到下一行默认的【j】是“无视软回车(word wrap)移动到下一个绝对行号”,还有到“下一个可视行”的【gj】(我在配置里把它们换过来了)。还有【f】【F】【t】【T】【W】【E】【{】【}】等等一堆定位指令。
这么花里胡俏有什么用?方便录宏(macro)。录宏三步曲:【对齐定位、操作、下一个】。大部分IDE和编辑器虽然也有录宏重播的功能,但没提供好用的对齐定位功能,宏功能就变成了鸡肋。辛辛苦苦录好一个宏,换个位置文本结构有一点不同,就没法用了。
而在vim里,录宏不仅轻量方便。【qq】就可以开录,【@q】重放,很顺手。重要的是,由于对齐定位特性丰富,宏可以适应很多场景。比如说,我知道一个字符串里有【lambda】这个单词,我希望把这个字符串里的第二个括号里的内容改成【x+1】。那我的录宏策略可以是:
1、对齐定位:【/lambda回车qqF"f(%f(】 (查找lambda,qq开始录宏,首先对齐,反向在当前行搜索前一个双引号,对齐到字符串开始位置。然后定位,正向在当前行搜索下一个(,匹配另一边括号移动到第一个括号结尾处,再在当前行搜索下一个左括号,定位到“第二个括号”)
2、操作:【ci(x+1】(修改括号内内容)
3、下一个:【n】(查找下一个lambda)
4、结束录制:【q】
然后按【@q】,接着一直按【@@】重复播放就行了。
不熟悉vim的人在旁边看可能都没留意到我录了宏在回放,只会觉得从第二个开始我的操作速度突然变快了,突然就全部搞完了。
在我的角度看,我相当于在极短时间内用vim的编辑命令写了个小程序在重复执行。这也是用vim的一个小原则:尽量习惯使用对齐定位的功能移动光标,避免过多使用没有适普性的hjkl。
3)大部分命令都可以看着是一个函数,接受【数字】【动作】【文本对象】作为输入参数。数字通常表示“重复执行”。这个就不细说了,简单入门vim之后都懂。
4)使用 :norm 命令,有时配合 :global 命令,可以直接用编辑命令显式写“代码”。这个这里也不深入说了,可以看normal和global命令的文档或相关资料。
值得一提的是,在选中文本状态下,norm命令会对被选中的每一行执行指定的编辑命令。可以用来在一些简单场景代替宏,或者用来快速回放宏。
比如说,要在选中文本的每一行的结尾加逗号: 执行【:norm A,】即可。
录了一个单行范围的宏要在选中文本的每一行上回放,执行【:norm @q】即可。
这些操作全都非常贴合程序员的思路。
举个例子,搬运我在
问题下的答案。本质上就是需要对两个列表里的内容做一个规则稍微复杂的按行合并,用利用宏有不少方案(例子里的被替换位置刚好是列对齐的,而且被替换内容都是一个单词,有些编辑器对于这个场景用多光标可能会更简单,但这里提供的解决方案本质上并不依赖于被替换位置列对齐,适用性相对更广):
例如分屏之后进行合并然后两边屏幕都移动到下一行,然后重复播放(注意我配置了用@t来重复执行@q)
再比如利用相对行号前后移动再配合宏和norm命令
或者用t命令直接复制指定相对行
这些方案都符合日常操作的思维习惯,只要简单配合宏就能快速达成需求。
关于宏的进阶操作,比如说保存和编辑,因为不太切题就不占用篇幅了。感兴趣的话可以移步这篇文章:
======================
似乎不少人感兴趣,趁今天有空把第三点补全。
第三点:Vim是Unix生态里的重要一环
这是什么概念?不少人对vim的理解是,它是“命令行下的一个比较好用的文本编辑器”。其实并不止于此,我们可以把vim看成是unix类命令行生态圈等一个重要组成环节。这主要归结于一下几个特性:
1、你可以把vim配成默认EDITOR (set EDITOR=vim
),然后在任何bash类(包括zsh)命令行下用ctrl-x ctrl-e可以把当前正在输入的命令行载入vim里,修改完毕后保存退出(:x或:wq或ZZ),vim里的内容会替换到命令行里。所以vim可以成为一个加强版的长命令编辑工具。
2、你可以把一个命令行应用的输出pipe给 vim -
,把其输出作为一个文件进行编辑
3、你可以在vim里用 :r !<外部命令>
的方式执行一个外部命令 (如果命令行很长,可以在输入过程中用ctrl-f或者在一开始就用q:
代替 :
来进入“命令模式窗口”),命令执行结果会读入到当前文本的光标下方
4、你可以在vim里选中一些文本,然后用:'<,'>!<外部命令>
把选中内容作为外部命令的输入,执行后的输出内容将替换掉选中内容。同样,可以不选中,用 :%!<外部命令>
把整个文本区的内容作为外部命令的输入,执行结果将自动替换掉整个文本区。关于这点有两个引申推论:
4.1 如果连续执行 :%!<外部命令>
,效果跟链式pipe是一样的,但你可以看到每一步的中间结果还可以现场做一些改动,再传给下一步
4.2 如果选中的文本内容本身是一些shell命令,对其执行 :'<,'>!bash
或者 :'<,'>!zsh
效果就是执行这些shell命令。具体效果可以看看我的这个回答
以上这些特性加起来,会带来两个独特的体验:
1、 你会发现vim其实可以作为大部分命令行工具的输入输出界面。甚至你自己有某些独特需求,你都不用去花心思学vim编程。随便用个顺手的语言写个命令行工具,从标准输入流(stdin)拿到输入,把结果输出到标准输出流(stdout),专注业务逻辑就行了。具体应用时拿vim来调用就行。
2、只要能找到合适的命令行工具(大概率可以),很多需求根本不用装插件。
比如说,格式化json,直接用
就很香,功能比我用过的所有json格式化插件都强。
格式化xml可以用xmllint (系统自带,xmllint),格式化javascript可以用js-beautify (js-beautify)
第四点:小功能定制方便
注意我并不是说用vimL来写插件或者function,大多数情况下一些小功能,利用宏,command和norm命令以及上面的外部命令整合就能玩出花来。
举例来说,要在当前位置下加入uuid,大部分工具都是装插件吧。vim下面可以怎么做呢?
首先我录个宏
qq 【开录】 ma 【记录当前光标位置】 :r !uuidgen 【macOS自带的生成uuid命令行工具,注意执行后uuid在新的一行,光标在该行行首】 yg_ 【复制到行尾】 "_dd 【删除当前行(生成uuid所在的新行)且不覆盖0号寄存器(也就是保留前面yank的内容)】 `a 【恢复光标位置】 q 【结束录宏】
这时0号寄存器里就是生成的uuid,我可以选择用p复制到光标位置或者viWp替换掉当前光标所在的uuid。当然现在我每次用@q执行这个宏都能生成一个新的uuid。
问题是宏是容易丢失或被覆盖的,要长久使用怎么办?像这么简单的场景,不用写function,直接用command加norm命令就行了,在vimrc里加入以下配置即可
注意norm!
后面的东西是怎么来的?别忘了你的宏这时还在q寄存器里,"qp
复制出来就行了。当然你也可以手打,注意编辑命令中的回车要打成 <c-v><c-m>
(也就是上图中的绿色^M)。
以后你用 :Uuid
命令就能生成一个uuid放在0号寄存器里了。
还有一个我经常用的自定义命令是下面的 :TAFmtJson
作用是调用外部命令jq -S
格式化当前buffer的一个json,把object里的字段按字典顺序排好,并且设好语法高亮和按语法折叠。这时我只要搜索我想要的关键字,vim就会自动打开从root到查找结果路径上的折叠,保证搜索结果可见。这是一种非常方便的检查深层json路径的手段(比如说你想确认关键字所在位置的往上三层的父节点是否符合预期)。到目前为止我都没找到其他可以替代这个方案的工具(当然也可能是因为我有了这个手段后没有认真找的缘故)。
换句话说,大部分工具提供的扩展方案,都是调用API(看看隔壁emacs和vscode),而不会让你“写个脚本模拟人手按ctrl-f查找,再模拟在搜索框里输入要查找的东西,再模拟按搜索按钮“。扩展编程与日常的编辑方案是割裂的。Vim里面同样有相同层次的vimL扩展,但还有这种直接模拟手打命令的流氓方案,而且刚好和“宏的内容就保存在寄存器”里这个特性相得益彰。这也是我之前提到vim的设定自成体系的一个例子。
(完)
有人看了觉得简陋,
因为人只看到了 键盘上的按键,只认得26个英文字母,10个数字,和少量标点符号。
—————分割线—————
vim 的使用是遵循语法的
有 语法 !(敲黑板)
有兴趣的请自己查看vim help,我只凭印象随便列举一点一般用法。
动词:
i insert,c change,r replace,d delete,y yank,p paste,f find,v visual
介词:
i in,a around,t to,f forward
名词:
w word,p paragraph,t tag,s sentence
举例子:
fcrC
find c replace to C
找到小写c替代为大写C
2. 改函数内容
ci{
change in {}
改变括号{}里的内容
3. 移动文本位置
dwf.p
delete word find . paste
删除单词,寻找符号 . ,粘贴至符号后
4. 删除粘贴操作
d$
delete to the end of the line
删除至行末
dd8jp
delete line go down 8 line paste
删除当前行,下移动8行,粘贴至下一行。
5.加注释
ctrl+v 10j shift+i // esc esc
visual select ,10 line below ,insert // ,exit exit
光标视图选中下方的10行,插入 文本 //,退出插入,退出光标选中。
花大量时候在vim上是纯属浪费时间,有这功夫不如学点其它的。
你要知道,vim存在的意义是因为服务器用的linux版本,只有命令行,没有图形化界面,所以迫不得已只能用这个东西。
vim学点够用的就可以了,别把会vim当成什么神技,这东西一点都不神,就是个编辑器,任何你能在win/mac上使用的编辑器都比他强。
没有鼠标的加持,根本不好用。
vim就好像是一个没有手的人,他虽然可以用脚去完成日常工作,甚至有些高手可以用脚非常迅速高效的完成工作,但是你要是说用脚干活是神技,我只能说你脑子有猫饼。
比如请问,我想把第一行的某个位置到第三行的某个位置都剪切掉,并复制到别处。不查百度,90%用vim的人都不会这个操作。
如果是ide,这个操作有任何难度吗?
vim为了尽可能多的操作,会设计一些很少使用的快捷键,这增加了学习成本。
比如插入常用的就这仨:i、I、A
还有些人会让你记o、O、a啥的,你自己用了就知道,很少用。
用vim是迫不得已的手段,但这不是目的,不要搞反了。
最后这句,vim是手段,不是目的才是核心啊,为什么都会漏了?
vim这个东西,就和我用五笔一样的。有人问我要不要学五笔,我都是这么回答的:
“五笔除了打的准以外,已经没有太大优势了,效率不比拼音高多少,学习成本还高。如果你想打的准一些,可以考虑学五笔,不然没必要。”
打出字是目的,用什么输入法是手段。会一种就可以了,没必要再花费高昂的成本学习,除非现有的手段无法帮助你完成目的。
vim也是如此,会点基本的,可以完成工作就可以了。你花了很多精力去深挖并不能给你带了什么。
别人在简历里写深入了解XX框架,深入了解NGINX,深入了解XX算法。你在简历里写你无敌精通宇宙第一懂vim?
至于像评论区里的几个典中典,说只有学习完了vim40几个文档的至少一半,才能算入门,我看了都觉得搞笑,魔怔了。
这次舆论的重点在于警察到底是多久赶到的。
没拜码头,收保护费,打砸门面这种原因我们都知道,也不怕;
但是公权力私用或者黑白勾结这种事,就会让人非常害怕;
如果西安公权力真的黑白勾结,还睁眼说瞎话,那就需要处理整顿了。
我朝的治安也不是一直这么好的,人民也不是软弱无比的,60年代西安打的也很凶的。难不成西安各公司以后都要雇佣保安公司保护经营?
这次出警距离1公里,走路10分钟都到了,所以就坐等这次真实的出警时间是多少了。
因为本身男人就有从来不给不能实现具现的人或物花钱的本能,加上中国男性更加的世俗化,以及中国社会对中国男性硬件方面的要求,导致追星给女偶像花钱这样的事情很难发生在当下的中国男性身上。
但并不是说男性对女性的需求就少了,因为在色情业方面,中国的卖淫业一直有着强大的供需关系,各种洗脚房暗娼,从高端到低端,从几千到几十,从一线城市到留守农村,从企业董事到农民工,买春现象非常普遍存在。没有庞大的消费者,商品早就消失了,根本用不着扫。
即便是前段时间爆出来,某官员给冯某主播刷了上亿的公款,最后还不是为了见面发生性关系么。
而对于女团这种东西,用部分新闻下评论就是“不给肏零分”,中国男性可能会欣赏某个女明星,听听她的歌看看她的剧,但是要花钱的话没戏,这一点男性比女性鸡贼的很,才不会浪费时间花费金钱去搞什么粉丝应援。
在这点上,我认为女性就做的不如男性,十分的傻,把精力和金钱都浪费到了无用的地方,有那个精力多锻炼身体、学习知识、关心政治,才有机会在政治、经济、文化领域夺取占比。