对 Practical Vim 一书的总结

引言

如果有一个神器让你在编辑文件的过程中不需要用到鼠标(有些人可能会说,我一直用笔记本的触摸板,从没用到过鼠标,哈哈),你会用它吗?但是如果这个神器需要一点学习成本,你会选择使用它吗?我相信这个答案会因人而异,因为每个决定的背后都有一个 trade-off,就像算法一样(在空间与时间之间做出选择),所以找出当下环境下适合自己的决定才是最重要的。

如果你的决定刚好是选择使用这个神器,那么这篇文章的目的就是大大减小你的学习成本。看这篇文章之前,我希望你能先读一读这篇文章:从Vim小白到Vim superstar,它可以让你收获很多!我本想把整本书中所有的 tips 总结下来,后来想一想完全没有必要,当你搞定这2篇文章以后,如果你对 Vim 还有更大的兴趣的情况下,你可以读完整本书,了解 Vim 更多的玩法,然后你可以尝试着去了解 Vim 的哲学。当然了,如果你熟练这2篇文章介绍的命令,相信你一定可以快速地编辑文件

显然,我并没有列出所有 Vim 的玩法,但是在你的脑海中一定要有这样一种思维方式:在 Vim 中,想要完成一个编辑任务可以有多种方式,有没有更简单的方式来完成这样的编辑任务。比如:现在想要删除一个字符,你完全可以进入 insert 模式下,然后删除字符,最后退回到命令行模式; 然而,你可以直接用 x 命令就可以做到这点。

Tip 2 - Don’t Repeat Yourself

下面是一段JS代码,但是每个语句后面没有分号。我想在这3行代码的末尾加上分号。用Vim其实可以很快就做到这点。假设我当前光标在第一行开头。

var foo = 1
var bar = 'a'
var foobar = foo + bar
  1. A; 在第1行末尾插入一个分号
  2. j. 把光标移动到第二行,重复步骤1的命令
  3. j. 把光标移动到第三行,重复步骤1的命令

下面是用一个按键就可以替代组合键的方式。

Practical Vim

Tip 3 - Take One Step Back, Then Three Forward

下面是一段JS代码,但是字符串之间的连接全部紧邻在一起,没有用合适的空格把它分开。因此我想把下面的JS代码

var foo = "method("+argument1+","+argument2+")";

变成下面的样子

var foo = "method(" + argument1 + "," + argument2 + ")";

用下面的方式就可以快速的做到这一点。

Take One Step Back, Then Three Forward

  1. f+ 在当前行中寻找字符’+'下次出现的位置
  2. s 它会删除当前光标下的字符,然后进入Insert Mode
  3. ; 重复步骤1的命令,继续向前查找字符’+'的位置
  4. . 重复上次文本的变化(即上图中第三行发生的变化)

其实通过这个例子,我有一些想法。当我们要做一些编辑工作时,我们应该仔细地考虑一下如何让剩下的编辑工作重复上一次的动作,从而可以大大简化命令。就像书中开头所说,在Vim中想做一件编辑工作可以有很多种方式,但是我们应该认真思考一下哪种方案的编辑效率最高。

Tip 4 - Act, Repeat, Reverse

在这个Tip中没有什么好说的,主要就是说我如何重复上次执行的命令,假如我不小心执行过了,我应该如何回退。

Repeatable Actions and How to Reverse Them

对于上面表格中的最后一条命令我想多说一句,它和Vim小白到Vim superstar 这部分的含义是一样的,只不过它把宏记录到寄存器x 中。

Tip 6 - Meet the Dot Formula

从Tip2和Tip3中其实可以看出来,每当我们想要用. 命令做重复的动作时,都有一个共同的特点。那就是:

One Keystroke to Move, One Keystroke to Execute

我们把上面这个模式称做Dot Formula

Tip 8 - Chunk Your Undos

从进入Insert mode直到返回Normal mode,这段时间内我们对文本的一切变化都被记作单次改变,因此当我们回到Normal mode按u 键的时候会取消这次改变。

因此,我们应该经常在句子末尾暂停一下回到Normal mode,给Vim留下线索形成断点,从而在撤回键入的时候会很方便。一个通用的法则就是:在Insert mode下编辑文本的时候,如果你已经停顿了一段时间,问自己一个问题:我应该离开Insert mode吗?如果答案是yes,then do it.

还有一个要注意的就是,如果在Insert mode中,你使用方向键,那就创建了一个新的undo chunk.

Tip 9 - Compose Repeatable Changes

在Vim中做一件事情通常有几种方法,但是我们应选哪一种呢?想要选择出最好的一种方法,最明显的策略就是看看哪种方式需要最少的按键(即VimGolf)。但是,如果VimGolf的分数一样,我们应该如何选择呢?其实下面我举个例子大家一下就知道怎么选择了。假设我们有下面一句文本,光标在末尾的字符h上,现在我想要把nigh 这个单词删除。

The end is nigh

书中给出了3种方式做到这一点,它们分别是:

  1. dbx
  2. bdw
  3. daw 上面2个命令很简单,我就不解释了。关于这个命令请参考,Zone selection

上面的命令都可以删除掉nigh,但是如果我们想要继续删除掉前面的单词呢,哪个命令是可重复的?相信大家按. 命令之后自有答案。因此选择哪个这里我就不多说了。

Tip 10 - Use Counts to Do Simple Arithmetic

当我们处于Vim的Normal mode下,Ctrl a 对一个数字加1,Ctrl x 对一个数字减1,如果当前光标下面的字符不是数字,那么这2个命令会在当前行寻找下一个数字并相应地加1或减1,如果没有找到数字,则没有动作。

我们有下面的CSS片段,光标在行首。现在我想要把要第一个0px 改成180px,我们可以通过后面的命令做到这点:180 Ctrl a

.blog { background-position: 0px 0px }

**Number Formats : ** Vim把以0开头的数字当作8进制,如果你想要Vim对待所有的数字为10进制,你需要加入set nrformats=到你的vimrc文件中。

Tip 12 - Combine and Conquer

Vim如此强大的大部分原因来自于operators和motions可以自由组合。

Operator + Motion = Action

你可以通过:h operator命令来查看完整的operators列表。就像上面的公式所描述的一样,1个Operator紧跟着1个motion将组成1个Action. 学习要新的motions和operators就像学习Vim中的词汇,随着我们词汇的增加,我们可以表达出更多的想法。

在Vim的语法中还有一条规则,当一个operator命令被重复地调用,它将作用于当前行。比如dd 删除当前行,gUgU 把当前行的字母变成大写,更方便的方式就是gUU,对开这个前缀g 我们可以认为它是一个类似于Ctrl 的功能,它会更改后面按键的行为。

Vim已经给我们提供了很多的Operator 和 Motion,我们也可以定制自己的Operator 和 Motion,如果你想定制自己的Operator,使用:h :map-operator 命令查看具体的细节; 如果你想定制自己的motions,使用:h omap-info 命令查看具体的细节。

Bonus: 最后我给大家一个非常方便地命令,我们可以用:[range]Commentary 去注释掉给定范围内的代码。比如:10,20Commentary 会注释掉10行到20行之间的代码。下面是一个关于注释的插件,大家可以去试试着用一下。

commentary.vim

Tip 13 - Make Corrections Instantly from Insert Mode

当我们在Vim的Insert模式下输入单词时,我们有可能会出现错误输入一个单词的情况。如果这个错误出现在单词的末尾,我们可以用backspace 键去删除那个错误,然后继续写那个单词就行了。但是,如果这个错误出现在单词的开头呢,并且这个单词很长呢?书中提到了2个方法:

  1. 我们直接删除整个单词,然后重新书写这个单词
  2. 另一个方法就是你切换回命令行模式,按b 键回到单词开头,修正错误,然后按A 键进入Insert模式,继续编辑。

对于方法1来说,我们直接在Insert模式下就可以进行,下面是相应的3个命令。

  • Ctrl + h 等同于backspace
  • Ctrl + w 删除一个单词
  • Ctrl + u 删除到光标所在行首

Tip 14 - Get Back to Normal Mode

从Insert模式到Normal模式最经典的方法是Esc键,但是对于许多键盘来说,Esc键的距离有点远,因此更好地一种方式是按Ctrl + [

有一种场景我们可能总会碰到,当我们在Insert模式下,我们想只运行一个Normal 命令,然后回到Insert模式下继续编辑,Vim提供了一个非常漂亮的方案来解决这个问题 - Insert Normal mode

在Insert模式下,我们可以按Ctrl + o 进入Insert Normal模式,在这个模式下,我们可以执行一个命令,然后就会返回到Insert模式。比如:我在编写代码的时候,正在编辑窗口最底下的一行代码,现在我想看看后面的代码是怎么写的,大家可能会想这多简单啊,拿起鼠标滚下轮就行了,但是,我们只用键盘会更快。有了Insert Normal模式我们可以很好地解决这个问题,zz 命令可以把当前行刷新到窗口的中间,因此我们可以用Ctrl + o zz 命令就可以快速查看下面的代码了。

Tip 15 - Paste from a Register Without Leaving Insert Mode

假如我们在Normal模式下用yy 命令复制了一行代码,然后用p 命令把粘贴复制的内容,紧接着我进入Insert模式编辑一下刚刚粘贴的代码,然后我又想粘贴上面复制的内容。最直接的一种方式其实就是你回到Normal模式然后用p 命令。但是,我们有更快捷的方式做那个。

在Insert模式下,我们可以直接粘贴Register中的内容,按Ctrl + r {0-9a-z"%#*+:.-=} 键。后面中括号中的内容是寄存器名称,它们各自的含义请参考:How to paste yanked text into Vim command line?

Tip 16 - Do Back-of-the-Envelope Calculations in Place

expression 寄存器允许我们去执行计算,然后把计算结果直接插入到文档中。

在Insert 模式下,我们可以通过Ctrl + r + = 访问expression 寄存器,它会在屏幕底部出现一个提示区域,在这个区域中可以输入表达式,比如1+1 ,输入完毕以后我们按下回车键,Vim会插入表达式的计算结果到文档中。

expression 寄存器不仅仅局限于这些简单的计算,在后面的Tip中我会提到更高级的一些例子。

Tip 17 - Insert Unusual Characters by Character Code

Vim可以通过字符的数字码插入任意的字符,尤其是我们想插入键盘上不存在的字符时,这个功能非常方便。

在Insert模式下,我们可以输入Ctrl + v + {code} 来插入字符,Vim要求这个数字码包含3位数字。比如,如果我们想要插入大写字母A,通过输入Ctrl + v + 065 就可以达到这样的目的。

对于一些字符来说,它们的数字码可能超过3位数字,不要担心,Vim也给我们提供了解决方案。比如,我们想要输入一个倒着的 号,通过输入Ctrl + v + u00bf,后面的数字码也就是用4位的16进制表示。你可以查找unicode表来找到更多字符对应地数字码。

Ctrl + v 还有一个功能就是,当我们给出的是非数字位的情况,它们按给定字符的字面含义去要插入。比如,在我的Vim中,当我按下tab 键时,Vim会把它转换为空格插入,而当我用Ctrl + v 去插入Tab 键时,Vim就会把它认作是一个制表符插入到文档中,而不会把它转换成空格之后再插入。

Tip 18 - Insert Unusual Characters by Digraph

这个Tip的表达公式是Ctrl + k + {char1} + {char2},比如我想输入个分数 1 2 \frac{1}{2} 21,那么你可以输入Ctrl + k + 1 + 2,大家自己去试试效果吧,这里我不多说了。

大家可以通过:h digraph-table 命令去查看更多有趣的digraph及相应地字符。

Tip 19 - Overwrite Existing Text with Replace Mode

Replace mode 基本上和 Insert mode 一样,除了它是用新输入的文字替代已经存在的文字。

在 Normal mode 下,我们可以用 R 键进入 Replace mode,完成替换以后,可以用 Esc 键退回到 Normal mode 下。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Linux中使用vim复制一整行的方法是使用yy命令。在命令行模式下,将光标移动到要复制的行上,然后按下yy即可复制整行。\[2\]如果要复制多行,可以使用nyy命令,其中n是要复制的行数。例如,要复制3行,可以使用3yy命令。复制的内容将被保存在vim的寄存器中,可以使用p命令将其粘贴到其他位置。 #### 引用[.reference_title] - *1* [【Linux】vim最基本指令,如何做到复制粘贴之类的功能?](https://blog.csdn.net/weixin_71138261/article/details/128540648)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [linux vim一些实用的快捷键和方法](https://blog.csdn.net/u010865136/article/details/127521181)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [linux vim常用快捷键](https://blog.csdn.net/weixin_45866062/article/details/128493832)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值