HOME | Links | About | Read

vim 技巧

下文中会有不少知识的罗列,你只需要大致看一眼就可以,需要用到再细细看

Table of Contents

预备篇

首先转一篇以前在百度linux吧(作者8pm)看的,算是教程吧,可以从中体会到大体学习的思路

学会盲打

零之贰

将我这贴复制保存起来,以备后用,贴吧东西难保存

配置文件先从最简开始,在伍级前别考虑配置插件,千万别硬背命令,千万别直接取用别人的配置文件
基本还是长时间待在 insert mode下,会觉得vim也不过尔尔,也不好用,
这个时候,编辑效率可能比用原来的一般编辑器还低,别人问使用什麼编辑器时,
多半会回答:vim 再配一个 nano, kate, kwrite, gedit, geany 或其他 IDE 之类的

养成习惯待在 normal mode(normal 不是白叫的),只有输入时才进入 insert mode,输入完马上 <ESC>
学习 normal mode 下的移动命令,这个时候输入文字标准流程:

  1. normal mode 移动命令准确定位光标(记住,搜索命令也是移动命令)
  2. 进入 insert mode 编辑(进入 insert mode 别只用 i,要习惯视乎情况,使用 I a A o O s C)
  3. <ESC> 返回 normal mode

这个时候,编辑效应会恢复到和你之前用的普通编辑器一样,甚至有少量提高

学习什麼是 operator(命令 d y c 等),什麼是 motion(所有能移动光标的命令,h j k l w e f t / ? 等等)
学习 operator + motion 的方式,如 ct. (将当前光标到 . (点) 之间的内容删除并进入 insert mode 准备修改)
学习基础的 Ex 命令,:s 什麼的

这个时候,编辑效率开始明显提高,在用其他一般编辑器时,会开始觉得不习惯和低效率

学习 text-objects,知道 operator + text-objects 的方法,可进行手术般精准的定位和修改,
既然你主要用在 c/c++,举一些在这个情况下有用的例子:

ci"(由 change operator 和 text-object i" 组成)
这个命令会找到当前光标所在行的下一个 " 括起来的字符串,清除引号裏面的内容,并进入 insert mode 以方便修改
用起来比解释起来简单,你可用 const char* hello = "Hello world."; 类似这样的代码来测试

yaB (由 yank operator 和 text-object aB 组成)
这个命令会将当前光标所在的代码块({} 括起来的内容,包括花括号本身)复制到默认 register,
方便在其他地方用 p 贴出来(当然,写代码不鼓励 copy and paste),你可用用任何一个 {} 来测试,然后找另外地方p
gUiw (由 make uppercase operator 和 text-object iw 组成)
这个命令会将当前光标所在的 word 全部变成大写
如将 maxsize 变成 MAXSIZE  
这个时候,开始知道为什麼 vim 精确高效,而且并不是因为全键盘无需鼠标

习惯 operator + motion 后,发现 . 命令很好用,多注意使用可重复的命令组合
练习使用书签定位,q 记录宏,使用多个 register,使用 args,使用 buffer
使用其他的 Ex 命令
这个时候,想不起没用 vim 之前的日子是怎麼过来的

开始 map 经常反覆使用的命令,开始写 vimscript,开始知道自己需要什麼样的插件
试推荐几个:
pathogen 或 vundle,tagbar, CtrlP, Gundo, UltiSnips,surround,Syntastic,
Conque,ack.vim,vim-commentary,fugitive(如果是 git 用户)
还有不少,但多对 c/c++ 没直接帮助,就不提了
这个时候,对其他编辑器提不起兴趣,或许 emacs 除外

拥有完全个人化的 vimrc,基本进入化境,成为江湖上的传说
常有旁人观察你编辑后,激起雄心壮志想要学 vim,尝试几个小时候因为觉得热键太不"人性化”而放弃,
但偶尔会向人提起他见过江湖上有你这麼一号人物

常用命令

替换命令

https://houye.xyz/images/vim-note.png

拷贝,删除和粘贴

在 vi 中 y 表示拷贝, d 表示删除, p 表示粘贴. 其中拷贝与删除是与光标移动命令结合的, 看几个例子就能够明白了

  • yw 表示拷贝从当前光标到光标所在单词结尾的内容.
  • dw 表示删除从当前光标到光标所在单词结尾的内容.
  • y0 表示拷贝从当前光标到光标所在行首的内容.
  • d0 表示删除从当前光标到光标所在行首的内容.
  • y$ 表示拷贝从当前光标到光标所在行尾的内容.
  • d$ 表示删除从当前光标到光标所在行尾的内容.
  • yfa 表示拷贝从当前光标到光标后面的第一个a字符之间的内容.
  • dfa 表示删除从当前光标到光标后面的第一个a字符之间的内容.
  • yy 表示拷贝光标所在行.
  • dd 表示删除光标所在行.
  • D 表示删除从当前光标到光标所在行尾的内容.

关于拷贝, 删除和粘贴的复杂用法与寄存器有关, 可以自行查询.

数字和命令

在 vi 中数字与命令结合往往表示重复进行此命令, 若在扩展模式的开头出现则表示行号定位. 如:

  • 5fx 表示查找光标后第 5 个 x 字符.
  • 5Fx 表示查找光标前第五个x字符
  • 5w(e) 移动光标到下五个单词.
  • 5yy 表示拷贝光标以下 5 行.
  • 5dd 表示删除光标以下 5 行.
  • y2fa 表示拷贝从当前光标到光标后面的第二个a字符之间的内容.
  • :12,24y 表示拷贝第12行到第24行之间的内容.
  • :12,y 表示拷贝第12行到光标所在行之间的内容.
  • :,24y 表示拷贝光标所在行到第24行之间的内容. 删除类似.

分割窗口

使用split或vsplit :5sp makefile –横向分割窗口,新窗口占用5行
:10vsp makefile –纵向分割窗口,新窗口占10列
分割窗口的大小调整:

  • 横向分割的窗口,调整窗口的高度:`n Ctrl+w + or -`n为增加或减少的行数,+增加,-减少。不加n每次增减一行。
  • 纵向分割的窗口,调整窗口的宽度:`n Ctrl+w > or <`n为增加或减少的列数,>增加,<减少。 不加n每次增减一列。

CTRL-W w 命令可以用于在窗口间跳转。
由于你可以用垂直分割和水平分割命令打开任意多的窗口,你就几乎能够任意设置窗口的布局。接着,你可以用下面的命令在窗口之间跳转:

  • CTRL-W h 跳转到左边的窗口
  • CTRL-W j 跳转到下面的窗口
  • CTRL-W k 跳转到上面的窗口
  • CTRL-W l 跳转到右边的窗口
  • CTRL-W t 跳转到最顶上的窗口
  • CTRL-W b 跳转到最底下的窗口

如果你用的是垂直分割,CTRL-W K 会使当前窗口移动到上面并扩展到整屏的宽度。
还有三个相似的命令:

  • CTRL-W H 把当前窗口移到最左边
  • CTRL-W J 把当前窗口移到最下边
  • CTRL-W L 把当前窗口移到最右边

最后我说一个更方便的,vim的窗口顺序为

147
258
369

所以可以用n+Ctrl+w+w,如果你要跳到8号窗口,你可以按8,再Ctrl+w+w

移动与定位操作

  • 0 移动到光标所在行的行首
  • $ 移动到光标所在行的行尾
  • g0,g$:移动到光标所在行的行首和行尾,分行显示的行仅在子行内移动。
  • gg:移动到文档起始位置
  • G:移动到文档结束位置

大小写的切换

  • ~ 将光标下的字母改变大小写
  • 3~ 将光标位置开始的3个字母改变其大小写
  • g~~ 改变当前行字母的大小写
  • U 将可视模式下选择的字母全改成大写字母
  • u 将可视模式下选择的字母全改成小写
  • gUU 将当前行的字母改成大写
  • 3gUU 将从光标开始到下面3行字母改成大写
  • guu 将当前行的字母全改成小写
  • gUw 将光标下的单词改成大写。
  • guw 将光标下的单词改成小写。

寄存器

  • :registers 查看寄存器

寄存器分类

  • 无名(unnamed)寄存器:"",缓存最后一次操作内容;
  • 数字(numbered)寄存器:"0 ~ "9,缓存最近操作内容,复制与删除有别, "0寄存器缓存最近一次复制的内容,"1-"9缓存最近9次删除内容
  • 行内删除(small delete)寄存器:"-,缓存行内删除内容;
  • 具名(named)寄存器:"a ~ "z或"A - "0Z,指定时可用;
  • 只读(read-only)寄存器:":, "., "%, "#,分别缓存最近命令、最近插入文本、当前文件名、当前交替文件名;
  • 表达式(expression)寄存器:"=,只读,用于执行表达式命令;
  • 选择及拖拽(selection and drop)寄存器:"*, "+, "~,存取GUI选择文本,可用于与外部应用交互,使用前提为系统剪切板(clipboard)可用;
  • 黑洞(black hole)寄存器:",不缓存操作内容(干净删除);
  • 模式寄存器(last search pattern):"/,缓存最近的搜索模式。

默认将复制内容存到0号寄存器,删除内容存到1号寄存器

  • :y+寄存器名称 可以将内容复制到相应寄存器
  • :p+寄存器名称 可以将相应寄存器的内容粘贴到下一行

基本操作(一般模式下)

  • "寄存器名y “寄存器名d "寄存器名p 代表着复制 删除 和 粘贴 如:
  • "ayy 就是复制当前行到 "a 字母寄存器中
  • "b3yy 复制当前行和下面2行 到 “b 字母寄存器
  • “ap 粘贴 “a 字母寄存器的内容
  • “cd2l 向右删除2个字符 并且把内容存到 字母寄存器 “c 中
  • “cp 粘贴 ”c 字母寄存器里面的内容
  • ”d3dd 删除当前行和下面2行 并且把内容存到 字母寄存器 “d 中
  • “fdf. 删除当前位置到句号 并且把内容存到 字母寄存器 “f 中
  • “gd'c 删除当前位置到标记c位置 并且把内容存到 字母寄存器 “g 中