基于开源的Vim学习教程learn-vim
1. 字符导航
在Vim中最基本的移动单元是上下左右移动一个字符。
h 左
j 下
k 上
l 右
当然也可以通过键盘的方向键进行移动。
为什么Vim用这几个键来当作方向键,这是因为Vi的作者Bill Joy写Vi时用的Lear-Siegler ADM-3A终端没有方向键,而是把 hjkl 当作方向键。
2. 对移动记数
与我们在Vim教程1 语法所讲的Vim语法类似,移动也有其语法:
[记数] + 移动字符
比如用 9l 来表示向右移动9个字符。
3. 单词导航
如果只能以字符为单位进行移动,并不能高效的在文件中移动光标。Vim提供了更长的单位:单词(word)。可以通过 w 移动到下一个单词的开始,通过 e 移动到下一个单词的结尾,通过 b 移动到上一个单词的开始,而通过 ge 移动到前一个单词的结尾。
除了上述的 单词 单位,还有一种单位为 词组 (WORD)。单词与词组有什么不同呢?一个单词是指一个只包含 a-zA-Z0-9 的字符串,而一个词组是指包含除了空字符(包含空格,Tab,EOL)以外的字符的字符串。可以通过 :h word 和 :h WORD 了解更多。
以下是 单词 与 词组 的相关键:
w 移动到下一个单词的开头
W 移动到下一个词组的开头
e 移动到下一个单词的结尾
E 移动到下一个词组的结尾
b 移动到前一个单词的开头
B 移动到前一个词组的开头
ge 移动到前一个单词的结尾
gE 移动到前一个词组的结尾
具体而言,以以下的Rust代码为例:
let mut a = "Hello Vim!";
当光标位于该行的开头时,可以通过按25次 l 移动到该行尾,又或者使用25l 。也可以使用8次 w 移动至该行尾,而使用 W 只需要使用6次就可以移动到行尾。大家用Vim分别使用下w 或W 即可明白单词和词组的区别。
当然,根据后面几个章节可知,可以通过$ 直接跳转至改行的行尾。
4. 当前行导航
0 跳转到本行的第一个字符
^ 跳到本行第一个非空字符
g_ 跳转到本行最后一个非空字符
$ 跳转到本行最后一个字符
n| 跳转到本行的第n列
以上是针对当前行移动的键。
当然对于当前行,也有搜索的相关键:
f 在同一行向后搜索第一个匹配
F 在同一行向前搜索第一个匹配
t 在同一行向后搜索的一个匹配,并停留在匹配前
T 在同一行向前搜索第一个匹配,并停在匹配前
; 在同一行重复搜索最近一次搜索
, 在同一行向反方向重复最近一次搜索
回到上面的例子:
let mut a = "Hello Vim!";
当光标位于行的开头时,可以通过按一次 $ 去往行尾的最后一个字符";",如果想去往 “world"中的"w”,则可以使用 fw 。
5. 句子和段落的导航
接下来的两个移动的单位是 句子 和 段落 。
在Vim中什么是句子?一个句子的定义是以.!? 和跟着的一个换行符或空格,tab结尾的。可以通过( 和) 分别跳转到上一个和下一个句子。
( 跳转到前一个句子
) 跳转到下一个句子
让我们来看一个例子,来感受那些字段是句子哪些不是?
I am a sentence. I am another sentence because I end with a period. I am still a sentence when ending with an exclamation point! What about question mark? I am not quite a sentence because of the hyphen - and neither semicolon ; nor colon :
There is an empty line above me.
我不是一个句子。我也不是个句子!我不是个句子;仍然不是句子:
注意,中文标点符号结尾的都不算是一个句子。
那什么是段落呢?段落可以从一个空行之后开始,也可以从段落选项(paragraphs )中“字符对”所指定的段落宏的每个集合开始。
{ 跳转到上一个段落
} 跳转到下一个段落
我们来看一个例子。可以试着分别用{} 与 () 进行对比,查看两种移动单元的区别:
Hello. How are you? I am great, thanks!
Vim is awesome.
It may not easy to learn it at first...- but we are in this together. Good luck!
Hello again.
Try to move around with ), (, }, and {. Feel how they work.
You got this.
可以通过 :h sentence 和 :h paragraph 了解更多。
6. 匹配导航
许多编程语言都用到了小括号,中括号和大括号。如果你在他们中的一对括号中,可以通过 % 跳到其中的一个括号或另一个上(如果存在)。可以通过这种方法弄清各个括号是否都成对匹配了。
% Navigate to another match, usually works for (), [], {}
再看一段Schema代码实例,可以试着在括号中用 % 移动:
(define (fib n)
(cond ((= n 0) 0)
((= n 1) 1)
(else
(+ (fib (- n 1)) (fib (- n 2)))
)))
7. 行号导航
可以通过 nG 跳转到行号为 n 的行,例如想要跳转到第7行,可以使用 7G ;跳转到第一行可以使用 gg 或1G ,跳转到最后一行可以使用 G 。
当不知道具体的行号时,但是知道其大体在文件的70%左右的位置,则可以使用 70% 跳过去。
gg 跳转到第一行
G 跳转到最后一行
nG 跳转到第n行
n% 跳到文件的n%
另外,可以使用 CTRL-g 查看文件总行数。
8. 窗格导航
为了移动当前窗格的顶部,中间或是底部,可以使用H ,M 和L 。
也可以根据Vim的语法,在 H 或 L 前传一个数字前缀。比如,输入 10H 可以跳转到窗格顶部往下数10行的位置。
H 跳转到屏幕的顶部
M 跳转到屏幕的中间
L 跳转到屏幕的底部
nH 跳转到距离顶部n行的位置
nL 跳转到距离底部n行的位置
9. 滚动
在文件中滚动,有三种速度可以选择:滚动一整页(CTRL-F / CTRL-B),滚动半页(CTRL-D / CTRL-U),滚动一行(CTRL-E / CTRL-Y)。
Ctrl-e 向下滚动一行
Ctrl-d 向下滚动半屏
Ctrl-f 向下滚动一屏
Ctrl-y 向上滚动一行
Ctrl-u 向上滚动半屏
Ctrl-b 向上滚动一屏
也可以相对于当前行进行滚动:
zt 将当前行置于屏幕顶部附近
zz 将当前行置于屏幕中央
zb 将当前行置于屏幕底部
10. 搜索导航
可以通过搜索导航非常快速的定位你的目标。 你可以通过/ 向下搜索,也可以通过? 向上搜索一个字段。 你可以通过n 重复最近一次搜索,N 向反方向重复最近一次搜索。
/ 向后搜索一个匹配
? 向前搜索一个匹配
n 重复上一次的搜索
N 反向重复上一次的搜索
假设有以下的文本:
let mut one = "1";
let two = 2;
one = "01";
one = "one";
let one_two = 12;
可以通过 /let 搜索"let",再通过 n 快速的重复搜索下一个"let",如想要向反方向搜索,可以使用 N 。使用 ? 也是相同的道理。
你可以通过* 快速的向前搜索光标下的文本,通过# 快速向后搜索光标下的文本。 如果你的光标位于一个字符串"one"上,按下* 相当于/\<one\> 。 /\<one\> 中的\< 和\> 表示整词匹配,使得一个更长的包含"one"的单词不会被匹配上,也就是说它会匹配"one",但不会匹配"onetwo"。 如果你的光标在"one"上并且你想向后搜索完全或部分匹配的单词,例如"one"和"onetwo",你可以用g* 替代* 。
* 向后查找光标所在的完整单词
# 向前查找光标所在的完整单词
g* 向后搜索光标所在的单词
g# 向前搜索光标所在的单词
11. 位置标记
可以通过标记保存光标当前所在的位置,之后可以再返回到这个位置。可以通过 mx 设置一个标记,其中 x 可以是 a-zA-Z 。有两种办法能回到标记的位置:用 `x 精确回到标记位置(行与列),或者用 'x 回到行级位置。
ma 用a标签标记一个位置
`a 精确回到a标签的位置(行和列)
'a 跳转到a标签的行
a-z 的标签和A-Z 的标签存在一个区别,小写字母是局部标签,大写字母是全局标签(也称文件标记)。
可以用 : marks 看更多的标记指令。
12. 跳转
并不是所有移动都被认为是一个跳转。使用j 向下移动一行就不被看做一个跳转,即使你使用10j 向下移动10行,也不是一个跳转。 但是你通过10G 去往第10行被算作一个跳转。
以下是部分跳转的指令:
' 跳转到标记的行
` 跳转到标记的位置(行和列)
G 跳转到行
/ 向后搜索
? 向前搜索
n 重复上一次搜索,相同方向
N 重复上一次搜索,相反方向
% 查找匹配
( 跳转上一个句子
) 跳转下一个句子
{ 跳转上一个段落
} 跳转下一个段落
L 跳转到当前屏幕的最后一行
M 跳转到当前屏幕的中间
H 跳转到当前屏幕的第一行
[[ 跳转到上一个小节
]] 跳转到下一个小节
:s 替换
:tag 跳转到tag定义
一个大致的规则是,任何大于一个单词或超过当前行导航的移动都可能是一个跳转。 Vim保留了你移动前位置的记录,你可以通过:jumps 查看这个列表,如果想了解更多,可以查看:h jump-motions 。
为什么跳转有用呢? 因为你可以在跳转列表中通过Ctrl-o 和Ctrl-i 在记录之间向上或向下跳转到对应位置。 你可以在不同文件中进行跳转。
|