Learn Vim Efficiently 2
这里将介绍vim的语法和光标浏览,这几乎是vim最重要的部分。
一、语法
强烈推荐阅读: https://github.com/iggredible/Learn-Vim/blob/master/ch04_vim_grammar.md
不同于其他文本编辑器的快捷键(需要同时按下两个键或者三个键),vim的命令更像是编程,有一套特定的语法。
在vim中只有一个语法规则:
1 | 动词+名词 |
1.1 动词
所谓动词就是Operator,操作符。
用:h operator
可以查看16种操作符,这里列举三种最常用的操作符。
1 | y Yank text (copy) |
1.2 名词
所谓名词就是motions,你用来在vim中移动的符号。这里是一些motions。
1 | h Left |
1.3 动词+名词的语法体现
假设你有如下文本:
1 | cosnt string learn = “vim”; |
在正常模式下,你的光标在字母c
上。
复制一整行:
y$
- y是复制,$是移动到一行末尾
删除const:
dw
- d删除w一个单词
向左拷贝3个字母:
y3h
删除2个单词:
d2w
所以vim的命令不需要刻意记忆,就像自然语言。
以行为单位的操作很频繁,所以vim将准备了一些行操作的快捷方式:
yy
,dd
和cc
1.4 更加快捷的操作
假设你有如下文本:
1 | int print(){ |
- 快速删除括号内的内容
di(
- 快速删除双引号里的内容
di"
- 快速删除中括号内的内容
di[
这将是vim的必杀技。di
代表着delete inner。对于结构化的文本,特别是代码。
1 | i + object Inner text object |
da(
将会连括号一起删除。
1 | w A word |
二、光标移动
强烈推荐阅读: https://github.com/iggredible/Learn-Vim/blob/master/ch05_moving_in_file.md
光标移动是很基础且重要的内容,一般我们退出编辑模式就是进行光标的移动。
2.1 字符移动
1 | h |
比如说5H
向左移动5个字符。
2.2 单词间移动
顾名思义,在单词间移动。
1 | w Move forward to the beginning of the next word |
一般命令都会有大写和小写两个版本,或者代表着两个方向,或者代表着两个不同的意思。
1 | W Move forward to the beginning of the next WORD |
那么大写的单词和小写的单词有什么区别呢?单词都是被空白字符分隔的字符串。
- 小写单词只包括字母和数字
- 大写单词包括任何字符除了空格、制表符和 EOL
2.3 行间移动
或者叫行内水平移动更佳。
1 | 0 Go to the first character in the current line |
值得说是n|
,在代码的报警信息中经常能看到第几行第几列报错,使用这个命令能快速定位到出错列。n代表任意数字。
快捷的操作:行内搜索。我认为这是vim的第二个必杀技。
1 | f Search forward for a match in the same line |
利用f可以快速到达你想要的字符面前。比如说fa
,快速将光标定位到第一个a的位置。
快速记住f和t的区别:f代表find,找到。t代表till,直到。
同样大小写两个版本代表着两个方向。
1 | F Search backward for a match in the same line |
使用;
和.
能避免重复劳动。记住上次的 行内查找操作。
2.4 行号移动
这才是名副其实的行间移动。比如说你想到第7行,命令7G
1 | gg Go to the first line |
2.5 搜索与替换
终于来了,全文搜索与替换。
1 | / Search forward for a match |
比如说,现在我们有这样一段文本:
1 | const int a = 1; |
现在我们想要将所有的int都替换为float:
\int<Enter>
- 这时你将定位到第一个int
cwfloat<Esc>
- change word改变一个单词,然后输入float
n.
- 继续下一个搜索,然后用点命令重复改变
这时你就能发现vim的快捷了。
还有一些快捷命令:
1 | * Search for whole word under cursor forward |
g*
和*
的作用,客观自行搜索。
2.6 窗口与浏览
To scroll, you have 3 speed increments: full-screen (Ctrl-F/Ctrl-B
), half-screen (Ctrl-D/Ctrl-U
), and line (Ctrl-E/Ctrl-Y
).
1 | * Ctrl-E Scroll down a line |
You can also scroll relatively to the current line (zoom screen sight):
1 | zt Bring the current line near the top of your screen |
这里留下作者的话:
Finally, realize that you do not need to know every single Vim command to be productive. Most Vim users don’t. I don’t. Learn the commands that will help you accomplish your task at that moment.
Take your time. Navigation skill is a very important skill in Vim. Learn one small thing every day and learn it well.
三、Vimrc
3.1 是什么?
vimrc是vim的配置文件。
3.2 有什么用?
它能将某些设置永久保存。什么意思呢?比如说,你现在打开vim设置了行号:set number
,当你下一次打开vim时,这个设置就失效了。通过vimrc就能永久保存设置。
一般vimrc在用户目录下, ~/.vimrc
.
3.3 它有哪些内容?
一般来说,vimrc主要配置以下内容:
- Plugins
- Settings
- Custom Funcitons
- Custom Commands
- Mappings
我们只挑常用的讲,设置settings和映射mappings。
当你改变vimrc时,记得source it。 Save it (:w
), then source it (:source %
).
3.4 设置
你可以准备一些常用的设置:
1 | set number |
Since we are learning about Vim and not Vi, a setting that you must have is the nocompatible
option. Add set nocompatible
in your vimrc.
Many Vim-specific features are disabled when it is running on compatible
option.
3.5 映射
你可以将一些键位映射成一系列命令的组合。这是个非常有用的功能。比方说,你如果不习惯vim的hjkl你可以映射为类似方向键布局的jkli。
语法为:
1 | nnoremap <key> <key> |
- n意味着normal模式
- nore意味着non-recursive,不递归的
- map就是映射
如何理解non-recursive呢?让我们来看一个例子:
你现在想要实现这样一个功能:按B就能在每一行的末尾加一个分号,然后退回到上一个单词。你写出这样:
1 | nmap B A;<esc>B |
注意,A行末尾插入,分号,esc退回到normal模式,B回退一个单词。
这看起来很美好,但实际上这个命令会加无限多的分号。除非你按Ctrl-C
停止。
为什么?因为没有设置不递归,最后一个B也被解释为映射后的B,而不是映射前的B(回退单词)。
所以,最好在平常中都使用不递归的映射。
好了,现在你可以实现一些快捷的功能了。
1 | inoremap jk <esc> |
这个命令在插入模式下,同时按住jk就能退出插入模式。
map命令的首字母对应不同的模式,这里留给大家探索。
四、后序
多用,多折腾。
这里留下作者的话:
Vimrc is an important component of Vim customization.
A good way to start building your vimrc is by reading other people’s vimrcs and gradually build it over time.
The best vimrc is not the one that developer X uses, but the one that is tailored exactly to fit your thinking framework and editing style.
Learn Vim Efficiently 2