目录

Vim-Emacs实用技巧总结

技巧一:在插入模式下想看到更多上下文内容

插入模式下,如果当前行正在窗口底部或者顶部,有时需要滚动一下屏幕,以便看到更多的上下文。可以通过快捷键 C-o zz 来实现,其中 C-o 快捷键可以切换到插入-普通模式,即插入模式下可以输入一个普通模式的命令, zz 则可以重绘屏幕,并把当前行显示在窗口正中间。

技巧二:实际行与屏幕行的区别与移动

Vim中有实际行与屏幕行的区别,原因是当每行内容超过窗口宽度时会被回绕显示,因此有了屏幕行的概念。实际行的常用移动操作有: j,k,0,$,^, 而屏幕行的移动操作就是在实际行操作前加上字符g,即对应为: gj,gk,g0,g$,g^ 。注意: ^ 操作是移动到行首第一个非空字符位置。

技巧三:单词与字串的理解与移动

Vim中字串的定义就是右非空白字符序列组成,字串间以空白字符分隔。 Vim中单词的移动操作为: w,b,e,ge ,因为符号也被理解为一个单词,所以单词的移动比较慢,可以通过字串来进行相应移动,操作为: W,B,E,gE

技巧四:行内字符查找操作

f{char} 是Vim中移动最快的操作之一,他会在光标位置到当前行行尾之间查找指定字符,如果找到了,会把光标移动到此字符位置;如果没有找到,则不会移动。下面将列出字符查找命令集中所有命令:

快捷键 描述
f{char} 正向移动到下一个{char}所在之处
F{char} 反向移动到上一个{char}所在之处
t{char} 正向移动到下一个{char}所在之处的前一个字符上
T{char} 反向移动到上一个{char}所在之处的后一个字符上
; 重复上一次字符查找命令
, 反转方向查找上一次字符查找命令

技巧五:文本对象

文本对象本身不是不是动作命令,不能用于在文本中移动,但可以用于v可视模式以及操作符待决模式中使用文本对象。在命令语法中看到{motion}时,该处就可以使用文本对象,例如: d{motion},y{motion},c{motion} 。文本对象由两个字符组成,第一个永远是i或a,而以i开头的文本对象会选择分隔符内的文本,以a开头的文本对象会选择包括分隔符在内的整个文本。常见分隔符文本对象:

文本对象 选择范围 文本对象 选择范围
ab 一对圆括号 ib 圆括号内部
a" 一对双引号 i" 双引号内部
a{ 一对花括号 i{ 花括号内部
aw 当前单词及一个空格 iw 当前单词
aW 当前字串及一个空格 iW 当前字串

技巧六:Vim寄存器

Vim包含常用的寄存器有无名寄存器、有名寄存器(“a-“z)、复制专用寄存器(“0)、黑洞寄存器(”_)等。若操作没有指定寄存器,将使用无名寄存器, s(等同于xi),x,d{motion},c{motion},y{motion} 都会覆盖无名寄存器的内容,可以通过在上述操作前添加 "{register} 前缀来指定使用另外一个寄存器。案例讲解:

  • 案例一:使用无名寄存器实现一些快速操作

    快捷键 描述 理解
    xp 调换光标之后两个字符 x操作将当前光标位置字符剪切下来保存到无名寄存器,p将无名寄存器中内容粘贴到光标后
    ddp 调换当前行和下一行位置 dd操作将当前行内容删除并保存到无名寄存器,p将无名寄存器中内容粘贴到下一行
    yyp 复制当前行副本到下一行
  • 案例二:糟糕,丢失了复制内容

    如右一段文本:collection = getcollection(); 想要将collection复制到无名寄存器,并用复制内容替换getcollection这样一个操作,使用如下命令操作: yiw -> ww -> diw -> P 通过上述操作后实际上该文本不会改变,这是因为第一个yiw操作复制到无名寄存器中的内容被diw操作的内容覆盖了。

    有如下三种操作可以解决:

    1. 使用有名寄存器,操作为 "ayiw -> ww -> diw -> "aP
    2. 使用黑洞寄存器,这是一个有去无回的寄存器,操作位 yiw -> ww -> "_diw -> P
    3. (推荐)使用复制专用寄存器,当使用 y{motion} 操作时,要复制的文本不仅会被拷贝到无名寄存器中,同时还会被拷贝到复制的专用寄存器中,操作为 yiw -> ww -> diw -> "0P

技巧七:粘贴面向字符或面向行的区域

Vim中普通模式的粘贴命令,根据要插入文本的性质不同,执行结果也不同。主要有 linewise-register和characterwise-register 两种类型。那么粘贴命令 p和P 如何如何才能知道把寄存器中的文本粘贴到光标前后还是当前行前后呢?这取决于这个指定的寄存器是怎么被赋值的,如果是面向行的复制或删除操作,将创建面向行的寄存器;如果是面向字符的复制或删除则创建面向字符的寄存器。

  • 粘贴面向字符的区域

    粘贴面向字符区域的内容时,因为需要判断需要粘贴到光标前还是光标后,这种方式很不直观。所以推荐使用 <C-r>{register} 命令,该命令可以在插入模式下直接使用而不同切换到普通模式。例如:粘贴复制专用寄存器0中的内容可用<C-r>0命令。

  • 粘贴面向行的区域

    粘贴面向行区域的内容时,则使用 p,P 命令并且也比较直观。

技巧八:插入模式下如何快速跳出括号

在插入模式下,因为使用了smartparens,所以会自动补全括号,那么输入代码后,如何快速跳出括号呢?因为使用的是vim键位,目前暂时没有找到优雅的解决方案,而是使用emacs的快捷键,实现左移/右移单个字符: C-f 右移一个字符, C-b 左移一个字符, 注意:上述快捷键不需要切换到普通模式,插入模式也可以使用

技巧九:标记

Vim中的位置标记允许我们快速跳转,可以手动设置标记,Vim也会自动记录一些位置。 m{a-zA-Z} 命令会用选定字母标记当前光标位置。小写位置标记只在每个缓冲区局部可见,大写位置标记则全局可见。 `{mark} 命令会将光标移动到设置标记位置。 mm `m 则是一对便于记忆使用的命令。以下是Vim的一些常用自动标记:

命令 描述
`` 文件中上次跳转动作之前的位置
`. 上次修改的位置
`^ 上次插入的位置
  • 交换两个单词

    可以利用标记命令来实现交换两个单词的技巧,命令如下: de -> mm -> <move> -> ve -> p -> `m -> P

技巧十:分离快捷键TAB与C-i

因为在终端没办法区分Tab和C-i快捷键,他们的 ASCII码值相同 。不过在GUI启动中可以将这两个快捷键进行区分,在配置文件 dotspacemacs-distinguish-gui-tab 变量中,设置为ture则进行区分,设置为nil则不区分。