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
2
3
y    Yank text (copy)
d Delete text and save to register
c Delete text, save to register, and start insert mode

1.2 名词

所谓名词就是motions,你用来在vim中移动的符号。这里是一些motions。

1
2
3
4
5
6
7
h    Left
j Down
k Up
l Right
w 移动到下一个单词
b 反向移动到下一个单词
$ 移动到本行末尾

1.3 动词+名词的语法体现

假设你有如下文本:

1
cosnt string learn = “vim”;

在正常模式下,你的光标在字母c上。

  • 复制一整行:y$

    • y是复制,$是移动到一行末尾
  • 删除const:dw

    • d删除w一个单词
  • 向左拷贝3个字母:y3h

  • 删除2个单词:d2w

所以vim的命令不需要刻意记忆,就像自然语言。

以行为单位的操作很频繁,所以vim将准备了一些行操作的快捷方式:yy,ddcc

1.4 更加快捷的操作

假设你有如下文本:

1
2
3
4
int print(){
console.log("hello vim");
int a[15];
}
  • 快速删除括号内的内容di(
  • 快速删除双引号里的内容di"
  • 快速删除中括号内的内容di[

这将是vim的必杀技di代表着delete inner。对于结构化的文本,特别是代码。

1
2
i + object    Inner text object
a + object Outer text object

da(将会连括号一起删除。

1
2
3
4
5
6
7
8
9
10
11
w         A word
p A paragraph
s A sentence
( or ) A pair of ( )
{ or } A pair of { }
[ or ] A pair of [ ]
< or > A pair of < >
t XML tags
" A pair of " "
' A Pair of ' '
` A pair of ` `

二、光标移动

强烈推荐阅读: https://github.com/iggredible/Learn-Vim/blob/master/ch05_moving_in_file.md

光标移动是很基础且重要的内容,一般我们退出编辑模式就是进行光标的移动。

2.1 字符移动

1
2
3
4
5
h
j
k
l
N + Motion

比如说5H向左移动5个字符。

2.2 单词间移动

顾名思义,在单词间移动。

1
2
3
4
5
w     Move forward to the beginning of the next word

e Move forward one word to the end of the next word

b Move backward to beginning of the previous word

一般命令都会有大写和小写两个版本,或者代表着两个方向,或者代表着两个不同的意思。

1
2
3
4
5
6
W     Move forward to the beginning of the next WORD
E Move forward one word to the end of the next WORD
B Move backward to beginning of the previous WORD

ge Move backward to end of the previous word
gE Move backward to end of the previous WORD

那么大写的单词和小写的单词有什么区别呢?单词都是被空白字符分隔的字符串。

  • 小写单词只包括字母和数字
  • 大写单词包括任何字符除了空格、制表符和 EOL

2.3 行间移动

或者叫行内水平移动更佳。

1
2
3
0     Go to the first character in the current line
$ Go to the last char in the current line
n| Go the column n in the current line

值得说是n|,在代码的报警信息中经常能看到第几行第几列报错,使用这个命令能快速定位到出错列。n代表任意数字。

快捷的操作:行内搜索。我认为这是vim的第二个必杀技。

1
2
f    Search forward for a match in the same line
t Search forward for a match in the same line, stopping before match

利用f可以快速到达你想要的字符面前。比如说fa,快速将光标定位到第一个a的位置。

快速记住f和t的区别:f代表find,找到。t代表till,直到。

同样大小写两个版本代表着两个方向。

1
2
3
4
5
F    Search backward for a match in the same line
T Search backward for a match in the same line, stopping before match

; Repeat the last search in the same line using the same direction
, Repeat the last search in the same line using the opposite direction

使用;.能避免重复劳动。记住上次的 行内查找操作。

2.4 行号移动

这才是名副其实的行间移动。比如说你想到第7行,命令7G

1
2
3
4
gg    Go to the first line
G Go to the last line
nG Go to line n
n% Go to n% in file

2.5 搜索与替换

终于来了,全文搜索与替换。

1
2
3
4
/    Search forward for a match
? Search backward for a match
n Repeat last search in same direction of previous search
N Repeat last search in opposite direction of previous search

比如说,现在我们有这样一段文本:

1
2
3
const int a = 1;
const int b = 2;
int c = 3;

现在我们想要将所有的int都替换为float:

  • \int<Enter>
    • 这时你将定位到第一个int
  • cwfloat<Esc>
    • change word改变一个单词,然后输入float
  • n.
    • 继续下一个搜索,然后用点命令重复改变

这时你就能发现vim的快捷了。


还有一些快捷命令:

1
2
3
4
*     Search for whole word under cursor forward
# Search for whole word under cursor backward
g* Search for word under cursor forward
g# Search for word under cursor backward

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
2
3
4
5
6
* Ctrl-E    Scroll down a line
Ctrl-D Scroll down half screen
Ctrl-F Scroll down whole screen
* Ctrl-Y Scroll up a line
Ctrl-U Scroll up half screen
Ctrl-B Scroll up whole screen

You can also scroll relatively to the current line (zoom screen sight):

1
2
3
zt    Bring the current line near the top of your screen
* zz Bring the current line to the middle of your screen
zb Bring the current line near the bottom 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
2
set number
set nocompatible

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.

作者

Desirer

发布于

2023-11-22

更新于

2023-11-24

许可协议