学前须知
vim 是什么?
- vim 是人类目前已知的最好 [1] 的 文本编辑器
- vim 是价值60亿美元的 文本编辑器
- vim 会成为你最后一个 文本编辑器,因为它是最好的
vim 的宗旨:
更好,
更强,
更快。
学习 vim 的建议步骤:
- 活下来
- 感到舒适
- 感到自己更好、更强、并且更快
- 成为 vim 超人
敬告学习者:
- 学习 vim 的过程是很痛苦的,但用起来棒极了
- 你先要学习最基本的生存技能,然后一点点地去探索奇技淫巧
- 就像学习乐器一样,你学习的最开始阶段会很痛苦
- 别指望在3天之内, ^in 3 days 把 vim 玩的比其它编辑器更好
开始学习
第一,活下来
一个标准的编辑器应该具备这样的特点:在键盘上打点什么,然后屏幕上就出现什么。但是现在的 vim 不行,它还处于普通(Normal)模式。你需要按下字母 i
来进入插入(Insert)模式。
现在你应该感觉好多了,折腾半天,总算用上了 记事本 (还tm是没有保存、编辑的阉割版)。既然你这么想,请按下 ESC
键,让我们回到普通模式。
然后,你需要知道这几个东西:
-
i
: 进入插入模式;ESC
返回普通模式 -
x
: 删除当前(光标闪烁处)字符 -
:wq
:保存并退出(:w
保存,:q
退出) -
dd
: 剪切当前行 -
p
: 粘贴
这就是 vim 的最基本内容,不过你还是应该知道:
-
hjkl
: 移动光标,等同于插入模式下的←↓↑→
[^j down] -
:help <command>
: <command> 的帮助文档,比如:help i
(:help
收获完整帮助文档)
[^j down]: 为了记住这鬼东西,你要告诉自己 j
和 ↓
有点像
现在,你已经知道了最基本的生存技能,大概能顺利活着了。
什么时候你掌握好了(把这几个命令用得很自然,就像吃喝拉撒一般),就可以进入第二阶段了。(估计得费上几天功夫)
对了,得说几句帮助你理解普通模式:
你一定知道 Ctrl-c
是 复制
,这跟字母 c
本身几乎毫无关系(你非得说 c for copy
我也没办法)。这就好像一用了 Ctrl
,就改变这整个世界的原本意思。 vim 的普通模式,就相当于一直按着 Ctrl
(或其它某些 非打印字符
键)进行各种处理。
最后还有点事儿:
-
<xxx>
: 应依情景被替换的内容(内容类别由xxx
指定),比如<command>
就意味着此处应输入某命令,<text>
则代表文本 - 所有以
:
开头的命令,结尾都默认要按下Enter
键,比如:q
其实意味着你要按下:
、q
和Enter
3个键 - 命令都要用 西文 输入,要
:
不要:
- 非
:
打头的命令,你是看不见(它们的显示)的
第二,感到舒适
既然你活下来了,就有必要提高点生活质量,而非像一条狗 [3] 那样无奈、痛苦。
这里是更多的技巧 ^more skills ,值得记下来并进行尝试 [4] :
1、进入插入模式的替换方案:
-
a
: 在光标后的位置开始插入 -
o
: 在光标后的一行开始插入 -
O
: 在光标前的一行开始插入 -
cw
: 把光标闪烁处到单词结尾处的东西删掉,然后插入
为进一步说明,假设现在处于普通模式,屏幕上有文本 word
,光标在 r
处闪烁,想输入 <text> 。[^new line]
为得到的效果 | 应选用的插入模式进入命令 |
---|---|
wo<text>rd |
i |
wor<text>d |
a |
word\n<text> |
o |
<text>\nword |
O |
wo<text> |
cw |
[^new line]: 你应该知道 \n
代表换行(new line)
2、基本移动
-
0
: 到达当前行的开头(相当于Home
键) -
^
: 到达当前行开头第一个非空白类字符 -
$
: 到达当前行的结尾(相当于End
) -
g_
: 到达当前行结尾最后一个非空白类字符 -
/<pattern>
: 查找<pattern>
,比如/word
就是在查找word
这个单词
3、复制粘贴
-
P
: 在光标闪烁处之前粘贴(p
则是在之后) -
yy
: 复制当前行(相当于ddp
或ddP
—— 剪切并粘贴)
4、撤销和重做
-
u
: 撤销 -
Ctrl-r
: 重做
5、打开、保存、退出和文档切换
-
:e <path/to/file>
: 打开某路径下的文档 -
:w
: 保存 -
:saveas <path/to/file>
: 把当前文本保存到某路径下 -
:x
/ZZ
/:wq
: 保存并退出当前文档 -
:q!
: 退出并不保存当前文档(:qa!
退出所有打开的文档并不保存) -
:bn
/:bp
:切换到下一个/上一个打开的文档
第三,感到自己更好、更强、并且更快
祝贺你走到了这里!现在要开始一些有趣的东西了。 [5]
首先,更好
来看看 vim 怎么体现机器的自我修养吧。 [6]
-
.
: 重复上一条指令 -
N<command>
: 重复做N次<command>
来看一些例子:
-
2dd
: 剪切当前2行(光标闪烁行及下一行) -
3p
: 粘贴3次剪切板的文本
假设现在屏幕上显示:
line1
line2
而光标在 line1
那行,那么在普通模式下输入 2dd3p
(注意你看不见这些非 :
开头的命令,别慌),文本就会变成:
line1
line2
line1
line2
line1
line2
100iword <ESC>
: 效果如下,千万别忘了最后按下ESC
键,也别忘了那个空格
word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word.
:重复上面的命令,这里的话,就是再写100个word
3.
: 再写3个word
(而非300个,多聪明的 vim 命令)
其次,更强
vim 一大优点就是,它能让你更有效地穿梭于文本之间。别跳过这节。
行间移动:
-
NG
: 到第N行 -
gg
: 到文本开头(相当于1G
) -
G
: 到文本结尾行
词间移动:
-
w
: 到下一个单词开头 -
e
: 到当前单词结尾 -
W
: 跳过最近的空白区,到下一个非空白字符 -
E
: 到最近空白区前的那个非空白字符
假设现在处于普通模式,屏幕上有文本:
The quick-brown* fox jumps over the lazy dog.
而光标在 u
上。那么:
输入的命令 | 光标会到达的位置 |
---|---|
w |
- |
e |
k |
W |
f |
E |
* |
码农的“凌波微波”
-
%
: 到达开括号处,适用于大中小三种括号
比如普通模式下, 有文本printf("foo");
,光标位于"foo")
的任意位置,按下%
, 都可以立马到达(
处。 -
*
/#
: 到当前单词出现的下一个/上一个位置
如果你不觉得 %
、 *
和 #
特别有用,只能说你不是码农,或者不是资深码农。
最后,更快
还记得上一阶段提到的基本移动吗?学习它的原因是,你会写大量的 <start position><command><end position>
样式的指令。
比如 0y$
的作用是,从当前行的第一个字符,复制到这行的结尾; ye
, 从光标处复制到这个单词结束; y2/word
复制了光标所在处和 word
第2次出现中间的文本。
能用于复制命令 y
的,自然也能用于剪切命令 d
,虚拟选择命令 v
,大写命令 gU
, 小写命令 gu
,……这需要你去不断探索。
第四,成为 vim 超人
你现在应该能很爽地用 vim 了。不过接下来,才是 vim 真正的杀手锏。
1、 行内移动
你只需要小手一按,就能:
-
0
: 到第0列去 -
^
: 到第1个字符去 -
$
: 到-1列去 -
g_
: 到第-1个字符去 -
f<char>
: 到光标后寻找某字符 -
,
/;
: 到该字符出现的上一处/下一处去 -
Nf<char>
: 到光标后某字符出现的第N处去 -
t<char>
: 到光标后某字符前面的那个字符去 -
F
,T
:和f
跟t
差不多,不过都是向找光标前找
假设在普通模式下,屏幕上有文本 x = fib(6 + 7); #this is a comment.
,光标在 b
处,那么:
命令 | 光标会到的位置 |
---|---|
0 |
x 前的那个
|
^ |
x |
$ |
. 后 再之后的那个
|
g_ |
. |
fi |
this 的那个 i
|
2fi |
is 的那个 i
|
ti |
h |
Fi |
fib 的那个 i
|
Ti |
b |
结合这节和之前的东西,你会发现 dt<char>
能把从光标处到某字符之前的东西都剪切走。
tbc……