与许多文本编辑器不同,Vim 会区分实际行与屏幕行。当 Vim 的 wrap 设置被启用时(缺省启用),每个超出窗口宽度的文本行都会被回绕显示(自动换行),来保证所有文本都能在当前窗口中完整展示出来。

因此,文件中的一行可能会被显示为屏幕上的若干行,从而出现了Vim 实际行与屏幕行的差异。

1. Vim光标移动实际行与屏幕行

当 Vim 启用 number 选项设置成显示行号后,以行号开头的行对应一个实际行,它们会占据着屏幕上的一行或几行;若某一行文本为适应窗口宽度而回绕时,回绕行的前面则不会显示行号。

Vim光标移动命令汇总一文介绍过,Vim普通模式下使用 jk 命令可向下及向上移动光标,注意:这里提到的行移动是指实际行

而如果需要按屏幕行向下、向上移动光标,则需要分别使用Vim命令 gjgk

如下面的Vim视频教程所示,假设想将当前光标向下移到单词 “watch” 上,如果直接按下 j 键,则会将当前光标往下移动到第5行的单词 “body”上,显然,这种往下移动一个实际行的操作并不是想要的结果。

而如果使用命令 gj,则会把当前光标往下移动一个屏幕行,正好将光标移动到单词 “watch” 上。如果不使用 gj 命令,可能你需要按下许多次 l 来右移光标,一步一步地移动到单词 “watch” 上,这是个多么低效的操作。

vim-line-downward

同样地,对于移动光标到行首、行尾等操作,Vim 也提供了对应以屏幕行为对象的命令。下表对操作实际行和屏幕行的命令进行了总结。

命令 光标动作
j 向下移动一个实际行
gj 向下移动一个屏幕行
k 向上移动一个实际行
gk 向上移动一个屏幕行
0 移动到实际行的行首
g0 移动到屏幕行的行首
^ 移动到实际行的第一个非空白字符
g^ 移动到屏幕行的第一个非空白字符
$ 移动到实际行的行尾
g$ 移动到屏幕行的行尾

观察上表,容易发现一个简单规律:jk0$ 都用于操作实际行,而如果在这些键前加上 g 前缀,就会让 Vim 对屏幕行进行操作。

自定义映射面向行的动作命令

如果想让 jk 命令操作屏幕行而不是实际行,可以通过Vim按键映射修改默认的 jk的功能。

把以下按键配置配置项加到 ~/.vimrc 文件中即可实现自定义面向屏幕行的动作命令。

1
2
3
4
nnoremap k gk
nnoremap gk k
nnoremap j gj
nnoremap gj j

:上述映射项使 jk 基于屏幕行向下或向上移动,而 gjgk 则基于实际行向下和向上移动,与 Vim 的缺省设置刚好相反。

嗯,扫一扫就可以找到小女子我啦~