关于开发工具方面的书,有两本获得了超高的评价,一本是《Pro Git》,另一本就是本文的主要参考《Practical Vim》,副标题Edit Text at the Speed of Thought更为形象生动——以思考的速度去编辑。这本书中包含了一百多个非常实用的Vim使用技巧,不管你是已经使用Vim多少年的专家,相信都能从中获取新的养分。推荐大家在读完本文后进一步去读一下这本书进行深入学习。

多年以前对Intellij IDEA爱不释手,又苦于从Eclipse转型的困难,于是写了一篇《十大Intellij IDEA快捷键》,反响和收获都超乎想象。最近重度使用Vim,所以趁热打铁再来一篇Vim的使用手册,整理一下相信于人于己都会有益处的。关于本文的组织和内容:本文从一个编辑器的角度来审视Vim,按照文本编辑器应有的功能来组织文章结构。此外,字里行间也涵盖了一些非常流行的、对Vim基本功能增强的插件用法,具体安装配置请参考《Python+Vim:天作之合》。


1.Vim之道

大家可能好奇:Vim还需要专门一本书来学吗?像本文最后一部分,整理或从网上找一个常用命令的Cheatsheet不就行了?不然。前言所述的技巧其实只是一个引子,会几个常用命令只是皮毛。当我们感慨Vim在小细节上的用心和鬼斧天工时,更重要地一点其实是Vim的内核和灵魂。其实不只是Vim这种开发工具,学习任何东西都一样,抓住其历史背景和设计初衷,体会设计者匠心独运的那一部分。之后再去看使用方法、技巧等细枝末节,就会发现一切都顺理成章。这一部分就是要重点说说Vim骨子里到底是什么样的,看看大浪淘沙后的Vim中包含的大智慧。


1.1 编辑的本质:重复!

文本编辑从本质上来说就是重复的。我们经常要在好几处做小改动,于是我们不断移动光标去修改,然后继续下一项改动。Vim是个神器,但其本质与其他工具无异,都是用自动化来对付重复。而自动化的核心就是:如何将我们的工作打造成一系列可以重复的小动作单元。如果不自己想清楚,那比Vim更高级的工具也救不了我们。

以小见大,我们日常生活工作中有很多其他事情本质上也都是重复的。作为天性“懒惰”程序员,我们当然要想法让自己以后更省事省时间。所以同样的道理,我们也需要梳理出整个工作流程,将它们变成一个个可重复的小逻辑单元,然后运用各种工具自动化。同样,关键在于梳理出可重复工作单元的思维过程。

1.2 Vim解药:dot配方

当我们想清楚了,Vim能帮助我们快速实现自动化,秘密就在Vim里一个最最基本的万能键:.(dot)。当我们按下它时,就像念了咒语、施了法术一样,会在当前光标位置重复上一次的操作。我们可以将dot想作一个微型的宏(Macro),我们之前做的一系列操作都被Vim自动录制并保存到某处,当按下dot时Vim帮我们自动播放之前录制的内容。

书中给了三个例子:在每行后加分号、一行中每个加号两边加空格、查找替换单词,来说明dot的万能。更重要地是为大家展示了“dot配方”的样子:一键移动(找到下一个目标)+一键操作(完成任务),简洁明了!如果我们的每个动作都能打造成这样理想的小单元,那我们就能很快速地完成所有任务。所以一个理想的dot配方就是:用Motion或其他搜索方法移动光标到下一个目标,然后用Operator+Motion/TextObject完成修改,最后不断用;和.重复这个配方。下面就要讲到这里提到的Operator、Motion、TextObject三个重要的概念。


2.组合的力量

Vim的常用操作可以用次数N+操作Operator+操作范围Motion/文本对象TextObject来表示,Vim的强大很大程度上来自于这种组合。当我们熟悉了这种组合方式,我们就能“研制”出自己的配方。那种摸着了门道,自己琢磨出新东西的窃喜大家可以自己体会。不仅如此,我们还能定制自己的Operator或Motion去扩充现有的词汇表。而且的确有人这样做了,比如注释/取消注释操作,比如根据不同语言扩展更多的TextObject。前面没有特意强调次数N,因为有时与其花时间去数要重复几遍,还不如操作一次,然后用dot去重复来得快。现在我们就来看看Vim的Operator、Motion、TextObject词汇表吧!


2.1 操作(Operator)

首先我们要了解一点,就是Vim超快速的移动能力得益于不同模式的区分,使得一副键盘上的按键在不同模式下表示不同的含义。这样我们只需用同样的单个按键就能完成看似非常高级的移动。

  • c (change):修改(删除并进入插入模式),非常实用,比先用d删除再进入插入模式要方便得多。更重要地是可以用dot来重复执行。
  • d (delete):删除,不用多说。
  • y (yank):拷贝到Vim的寄存器中,因为c已经被change占用了,所以只能换成另一个单词yank的首字母y。
  • g~ (swap case) gu (make lowercase) gU (make uppercase):这三个是大小写转换相关的。
  • > (shift right)、< (shift left)、= (autoindent):这三个在格式化代码时常用。

惯例:(一)操作重复写的话表示范围motion是当前行,例如dd是删除当前行,>>是增大一个缩进当前行,gUgU(或gUU)是当前行都变大写。(二)在当前行中可以使用f/F{char}向前/后查找字符,t/T{char}类似,区别是停留在char之“前”(向前搜索则停在前面,向后则停在后面),用;和,可以重复上一次的向前/后查找动作。因为这个区别,我们通常用f/F作快速查找移动,用t/T配合d/c做修改编辑。在后面介绍文本对象时,我们会看到类似的用法。


2.2 移动(Motion)

  • w/b:下一个/前一个word。还有W和B,表示下一个/前一个WORD。这里提一下word和WORD的区别,word是字母、数字、下划线组成的一个单词,WORD是空格分隔的单词。
  • e、ge:下一个/前一个word的末尾。同理也有E和gE。
  • f{char}:在当前行向后查找匹配的字符,F是向前查找。;和,可以重复上一次的f/t和F/T查找。
  • t{char}:与f类似,但光标会停在匹配的字符前,同理T向前查找停在字符后。
  • *:下一个匹配的word
  • %:在开闭括号间来回跳跃,支持()、{}、[]。
  • (:下一个句子,)是上一句。
  • {:下一段,}是上一段。
  • :非常有用的移动,可以跳回到上一次的位置。假如我们想修改一对小括号成花括号,则先移动到(,然后用%移动到末尾的),修改成},这时用%是无效的,因为此时括号已经不匹配,于是“就出场了,使我们跳回到(的位置。

2.3 文本对象(Text Object)

TextObject可以像Motion一样,用在Visual模式或与一个Operator结合,但不同的是文本对象不能在Normal模式下单独使用去移动光标,毕竟文本对象表示的是一个文本对象、一个范围。《Practical Vim》中做了精彩的比喻:如果说Motion是迎面飞踢的话,那TextObject就是剪刀踢。大家在Vim中,任意一个word中间按一下daw就能体会到这个比喻的妙处了。在word中间的某一个字符,我们彷佛腾空而起向两边踢出双腿,“干掉了”整个word。神奇吧?但如果你以为文本对象只有这么大点本事那就错了,下面就来看看我们有多少种对象吧!

文本对象由前缀a或i和下列后缀自由组合形成,a(around)表示包含下列标签以及中间的内容,i(inside)表示只包含中间的内容:

  • w W s p:与前面一致,表示word、WORD、句子和段落。
  • ) or b:一对小括号,(…)
  • } or B:一对花括号,{…}
  • ]:一对中括号,[…]
  • >:一对尖括号,<…>
  • :一对单引号
  • :一对双引号
  • `:一对`…`
  • t:一对html标签,例如tags

一切就绪,现在就来见识一下文本对象的威力吧。比如现在光标位于{hello}的e上,这时我们用ciw,就能直接删掉整个hello并且进入插入模式进行编辑,同理我们如果执行daw就能直接删除整个{hello}包括花括号。是不是想起了什么?没错,此处的用法与前面介绍的f和t的惯例类似,所以可以用一句简练的话来总结:Delete a(around)/f(inclusive). Change i(inside)/t(exclusive). 删除周围,修改其中。用好文本对象,甚至还能自己根据需求扩展的话,那真是威力无穷!


3.最优解:高尔夫记分法

很多时候我们会有多种方式去完成一个操作,如何进行选择呢?一个有趣的规则就是Vim高尔夫。我们知道高尔夫球是记每位选手的挥杆数,谁用的次数最少谁是胜者。Vim也是一样,谁需要的按键少谁赢,当次数一样时,还有更重要的一点:是否可重复,即是不是个有效的dot配方

书中给出了一个例子,当光标在一个单词的末尾最后一个字符上,如果删除这个单词?方案一:db往回删,但留下了当前光标下的最后一个字符,所以还要敲一下x。方案二:先b回到单词的第一个字符,再dw删除。方案三:diw,即delete+inside+word删掉当前单词。三种方案都是三次按键得三分,这时就看谁是有效的、可重复的“配方”了。胜者很明显,就是diw,因为dbx相当于两次操作,dot没法都重复。而bdw是先移动再操作,看似是我们前面提到的理想情况,但注意:一键移动是找到下一个目标,而这里的b是在目标上做了一次移动,所以这个方案还是很难重复在另一个单词上的!

大家感兴趣的话可以去VimGolf这个网站上玩一玩,上面有很多有趣的挑战。就像刷题一样,不过看起来似乎比Leetcode要更有乐趣一些,毕竟多了解一些技巧使我们能在日常工作中获益。


4.最后两招:Visual模式与宏录制

在一些不理想的情况下,我们没法非常完美的用一个dot配方就完成编辑,这时我们还可以求助于下面两个办法。限于时间和篇幅的关系,这一部分写的比较简略,实际上内容还是挺多的。感兴趣的同学,请直接去读原书和其他资料吧。

4.1 Visual模式

可视化模式可以细分为三种子模式:字符、行、块,分别在Normal模式下按v、V、Ctrl-v进入。如果一个编辑任务有简单的dot配方的话,我们倾向于不使用可视化选择修改的方法。书中提到了Visual模式的问题:不可重复!比如我们改了一个长度为3的单词,当我们想在另一行某个长度为4的单词上重复时就会发现问题,只有3个字符被修改了。所以这种方法只适用于:1)一次性的简单修改;2)修改范围不容易用dot配方写出来;3)两个Visual模式提供的很酷的功能:一就是V进入行模式,然后r-,则这一行都会被改为-,想想手写表格时这有多方便;二就是Ctrl-V进入块模式按列修改,方法为选好范围后按c,再输入想要的内容后Esc回到Normal模式,就会发现该列的每一行都变成了刚才我们输入的内容。

4.2 宏(Macro)

在Vim中进行宏录制非常简单,Normal模式下按q{register},比如qa就表示把这个宏保存到寄存器a,然后我们就可以输入命令了,最后按q退出。按@a或5@a就能任意重复刚才的宏了。看起来简单,但如果不遵循编写宏的三个黄金规则的话,写出来的宏就是一堆废代码,没有可重用的价值:

  1. 正则化(Normalize):第一步就是利用0、$、I、A正则化光标位置,因为每一行的长度、形状可能都不一样,如果不这样做的话再重复执行的时候就会在错误的位置上开始。
  2. 可重复的修改:利用f{char}等命令找到目标,然后修改。在这里,Vim的Motion还有起到了一个保护的作用。如果宏中的某一条Motion移动失败了,那宏就自动终止,不会执行后面的命令。
  3. 移动到下一目标:如果想不断在每行上执行的话,那在宏的最后,加上j。这样的话执行5@a重复5次时,宏就会自动在5行上运行了。

看到最后,是不是觉得其实本质上宏就是一个精心设计好的dot配方?其实一个最简单的宏就是qq;.q,然后执行@q。因为我们知道一个dot配方是由找目标和修改两步组成,所以我们可以写一个一次性的宏来减少我们敲击;.的次数。

关于宏还有个有趣的地方,就是宏可以并行或串行执行,前面的5@a其实是串行执行,如果中间一次执行失败了,就会立刻终止。那怎样才能并行执行呢?很简单,利用命令模式下执行:normal @a,这样其中某一条的失败不会影响其他的执行。


5.总结:Cheatsheet

前面主要介绍了Vim的核心价值——编辑,编辑也的确是最主要的工作,但我们每天的工作流还有很多其他部分组成:打开文件、打开包含特定关键字的文件、开始编辑、保存关闭。编辑部分也有一些前面没讲到的,例如下一页、复制粘贴、Undo等。所以,在本文的最后一部分做统一的整理。一些Vim插件能对这些周边工作有更强大的支持,所以这里也会介绍一下常用的插件。

操作 快捷键
文件管理 打开
(Ctrlp插件)
Ctrl-p:文件名模糊查找后:
Enter:当前窗口打开
Ctrl-v:水平分隔当前窗口
Ctrl-x:垂直分隔当前窗口
Ctrl-t:新建Tab打开文件
Tab gt:下一个Tab
gT:上一个Tab
1gt:第一个Tab
:tabonly:只保留当前Tab,关闭所有其他
编辑1
(Dot Formula)
操作符 c:修改
d:删除
y:复制
p:粘贴
gu gU g\~:小写、大写、大小写转换
< > =:左缩进、右缩进、自动缩进
cc dd yy gUU << ==:只当前行
移动 w b:下/上一个word
W B:下/上一个WORD
e ge:下/上一个word末尾
E gE:下/上一个WORD末尾
f:下一个匹配字符
t:下一个匹配字符前
\*:下一个匹配word
%:在() [] {}开闭括号间跳跃
(:下一个句子
{:下一个段落
` `:跳回到之前光标所在的位置
文本对象 w W:word和WORD
s:一个句子
p:一个段落
) or b:一对(…)
} or B:一对{…}
]:一对[…]
>:一对<…>
‘:一对’…’
“:一对”…”
`:一对`…`
t:一对<xml>…</xml>
编辑2 跳跃移动
(Easymotion插件)
/:查找后跳到指定字母索引的位置
\ j:向下跳到指定字母索引的行
\ k:向上跳到指定字母索引的行
更多移动 0 ^ _:行首
$ g_:行尾
gg:文件开头
G:文件末尾
ngg:第N行
H M L:屏幕上/中/下
zt zz zb:滚动当前行到屏幕的上/中/下
Ctrl-D Ctrl-F:下半页/下一页
Ctrl-U Ctrl-B:上半页/上一页
gj gk:下/上一显示行
开始编辑 i:光标前
a:光标后
I:行首
A:行尾
o:新加下一行
O:新加上一行
r:替换当前光标位置的字符
x:删除当前光标位置的字符
J:下一行追加到本行的末尾
复制粘贴 “1y:拷贝到寄存器1
“1p:从寄存器1复制
v{motion} p:可视化选中后粘贴,不影响匿名寄存器
查找替换 :s/foo/bar/g:只替换当前行的每一处
:%s/foo/bar/gc:整个文件进行确认和替换
:5,12s/foo/bar/g:替换5-12行(包括)
:.,$s/foo/bar/g:从当前行一直到文件末尾
:.,+2s/foo/bar/g:当前行以及后两行
:vimgrep /foo/ **/*:在整个项目中查找
撤销重做 u:Undo
Ctrl-r:Redo

Vim终极指南:所思即所得相关推荐

  1. ASIC设计-终极指南

    ASIC设计-终极指南 ASIC Design – The Ultimate Guide ASIC设计-终极指南 ASICs代表特定于应用的集成电路,指的是针对特定应用而设计的半导体解决方案,与其他解 ...

  2. Blender数字雕刻终极指南学习教程

    CGBoost–Blender中的3D雕刻大师–数字雕刻终极指南 大小:29G 含课程项目文件 Master 3D Sculpting in Blender – The Ultimate Guide ...

  3. Unity提高工作效率的终极指南

    本套课程指南通过关于如何更快.更智能地工作的最新技术,帮助Unity创作者节省时间并提高工作效率 你会学到: Unity的创建者节省了时间,提高了生产力. 关于如何更快地使用程序员和艺术家工具集的技巧 ...

  4. Unity电子游戏优化终极指南 The Ultimate Guide to Video Game Optimisation

    大小解压后:5.2G 含课程文件 时长9h 1280X720 MP4 语言:英语+中英文字幕(根据原英文字幕机译更准确) 电子游戏优化终极指南 信息: 学会从你的Unity游戏开发项目中挤出每一帧表现 ...

  5. 如何编写更好的SQL查询:终极指南-第二部分

    上一篇文章中,我们学习了 SQL 查询是如何执行的以及在编写 SQL 查询语句时需要注意的地方. 下面,我进一步学习查询方法以及查询优化. 基于集合和程序的方法进行查询 反向模型中隐含的事实是,建立查 ...

  6. 【 Linux 】Vim学习指南

    本文转载自:Vim学习指南 你想尽可能快地自学vim(为大家所熟知的最好的编辑器) .这是我学习的方法:从细处入手然后慢慢掌握所有技巧. Vim 六十亿美元的编辑器 设计优良,强壮,快速. 学习vim ...

  7. Vim实战指南(一):基础编辑命令

    原文地址:Vim实战指南(一):基础编辑命令 Introduction Vim和Emacs作为两大神级文本编辑器各有利弊,本实战指南不加讨论的介绍Vim. 本实战指南不是教你按照Vim的键位图来编辑文 ...

  8. 每周一书《Oracle 12 c PL(SQL)程序设计终极指南》

    本周为大家送出的书是<Oracle 12 c PL(SQL)程序设计终极指南>,此书由机械工业出版社出版, 孙风栋,王澜,郭晓惠 著. 内容简介: <Oracle 12c PL/SQ ...

  9. 教程 | 理解和实现自然语言处理终极指南(附Python代码)

     教程 | 理解和实现自然语言处理终极指南(附Python代码) 时间 2017-02-16 14:41:39 机器之心 原文  http://www.jiqizhixin.com/article ...

  10. 终极指南:如何使用Visual Studio Code进行 Java 开发?

    VS Code(Visual Studio Code)已成为多语言开发人员的首选文本编辑器. 大量Javascript.TypeScript.Go.Python 和其它语言的开发人员都在使用VS Co ...

最新文章

  1. MATLAB【六】 ———— matlab 随机散斑模拟
  2. go get 代理 找不到包_初步看看Go1.10 支持 HTTPS 代理
  3. 15 个最佳的 jQuery 表格插件
  4. pythonc语言结构_C语言结构体笔记
  5. Jenkins Pipeline高级用法-ShareLibrary
  6. DelayedOperation分析
  7. (2)WePHP 控制器与使用模板
  8. 软件工程中需要学习和掌握的软件都有哪些_9个B端产品经理需要懂的技术
  9. html网页制作中的问题,网页制作中注意应用HTML标签的问题
  10. 线段树(SegmentTree)学习笔记
  11. 菜鸟的B4A(B4X)开发成长日志
  12. 微信分享 链接地址文档
  13. mac hdmi 外接显示器没声音
  14. 各种零知识证明的比较!
  15. win10休眠_硬派玩家 | Win 10关机速度变慢?这还真不是错觉
  16. ZN-M160G光猫 Telnet打不开
  17. 基于Unity的HTC Vive虚拟现实交互开发(一)环境配置
  18. 川奇吕电商概括短视频账号策划运营方案怎么写
  19. 量子计算机幕后故事,惊心动魄! 你不知道的北斗卫星发射幕后故事
  20. u-boot for tiny210 ver2.2.1(by liukun321咕唧咕唧)

热门文章

  1. python基础语法全解/数据类型/面向对象编程
  2. matlab计算恒向线航程
  3. 【GCN-CTR】剪枝特征:Detecting Beneficial Feature Interactions for Recommender Systems (AAAI‘21)
  4. Python连接MySQL数据库locahost无法连接的问题
  5. 后盾人tp5教程_5个出色的应用程序以开放数据为后盾
  6. Unrecognised input. Possibly missing opening ‘{‘
  7. 怎么调linux系统的屏幕刷新率,怎么改屏幕的刷新率?
  8. 加速ubuntu开机速度
  9. hdfs误删文件恢复教程
  10. 震惊!世界海底光缆分布图!