Vim技巧之四大模式_可视模式
在前面的两篇文章《Vim技巧之四大模式_插入模式》和《 Vim技巧之四大模式_普通模式》我们已经介绍了插入模式
和普通模式
里面的技巧,下面我们将继续介绍四大模式之一的可视模式
什么是可视模式?
可视模式简单来说就是选中一块编辑区域,然后在上面执行一些操作,比如删除,替换,改变大小写等。
如何选中一块区域?
在Vim
里面有三种激活可视模式,并选择一块区域的方法,他们分别是:
模式类型 | 激活方式 | 选择效果 |
---|---|---|
字符文本 | v (小写) | 逐个字符选择文本 |
行文本 | V (大写) | 逐行选择文本 |
块文本 | <C-v> | 按照块的方式选择文本 |
这上面说的什么字符文本
,行文本
,块文本
指的是什么意思啊?其实就是一种控制选择粒度的方案,字符文本
的选择粒度是一个字符,行文本
的选择粒度是一行文本,如果你想只选中一行里面的几个连续字符,那么使用行文本
就不太适合了,因为行文本
的选择粒度是以行为最小单位的,每次最少都要选中一行内容,如果你想选中多行文本,那么使用字符文本
明显是不合适的,因为太低效了。而块文本
就是功能最强大的选择模式了,它可以完全无视行的存在,可以在文本中按照需要的区域自由选择。
举个栗子:注意左下角的不同选择模式的提示
字符文本的选择,移动到
H
,点击v
开始选择,我们选中Hello World
这几个字符
行文本的选择,点击
V
开始,我们选中头两行文本
块文本的选择,点击
<C-v>
开始,我们选中一块文本
如何快速选中目标区域
我们在普通模式
博客中已经介绍了许多快速移动光标的命令,比如h
,j
,k
,l
,可以在四个方向移动光标,也可以用f{char}
来跳转到某个字符上面,之后再用;,
来重复跳转,或者用查找命令/target
来进行光标的快速移动,再用n/N
进行重复,还有许多这样的移动光标的命令,幸运的是,在可视模式下面,这些快速移动光标的命令我们都可以用
举个栗子:
比如在下面的栗子里面,我们要从
25
行字符c
开始,一直选中直到行尾首先点击
v
切换到字符模式,键入fc
,接着可以直接按$
,这时光标会跳到行尾,字符c
到行尾之间的内容就被选中了
如果我们要选择
Hello World
这个字符串呢?我们可以直接
fH
,然后vi"
就可以选中双引号"
里面的内容了
这样的用法还有很多,读者可以自我领会
大家有没有发现在使用可视模式的时候,一旦切换到可视模式以后,选中的区域是由两个端点来界定的(一个在左上角,一个在右下角),我们在默认情况下只可以控制右下角的端点,但是有些时候发现我们需要调整左上角的端点,这时我们可以使用o
按键来在左上角和右下角之间进行切换。
举个栗子:
假如我们在块选择模式下面已经选中了下面的区域
现在我们需要将选择区域向左再扩充一点,可以点击
o
按键,再用移动光标的命令进行移动
如何重复选择目标区域
我们可以使用gv
命令来重新选中之前可视模式选中的目标区域,但是如果之前的选中的区域文本被删除,那么gv
命令就会表现的有点神经了
举个栗子:
假如我们选中字符串
"Hello World"
,然后再将"Hello World"
删除,如果我们再次调用gv
命令,那么选中的区域不再是之前的"Hello World"
,而是相同字符宽度的内容
删除
"Hello World"
,gv
选中的区域
不仅如此,就算这行文本的列数有所偏移,比如将文本多缩进了几行,再次
gv
发现也是不对的
所以,博主个人估计
Vim
底层的实现可能是记住目标区域的起始行和行数
和起始列和列数
,键入gv
以后就根据之前保存行列信息进行还原于是博主再次做实验,将上下两行进行调换,再次
gv
发现和预期的一样。
如何在选中中切换选择模式
可视模式有一个好处就是我们可以在三种选择模式之间进行随意的切换,比如在行文本
模式下面希望进行更加细粒度的选择,我们可以直接按v
切换到字符模式
,同理可以得到在某一选择模式中切换到任意其他两种模式的方法。博主不再这里赘述
如何对选中的区域进行操作?
我们选中一块区域,最直接的目的就是对这块区域进行操作,比如删除,调换大小写,改变文本等等。那么要如何对选中的区域进行操作呢?在文章的上一节中我们提到可以在可视模式
中使用普通模式
的跳转命令,没错,在可视模式
中也可以使用普通模式
模式下的修改命令。
命令 | 命令效果 |
---|---|
d | 删除选中文本 |
c | 修改选中文本 |
r | 替换选中文本 |
I | 在选中文本前插入 |
A | 在选中文本后插入 |
gu | 选中区域转为小写 |
gU | 选中区域转为大写 |
g~ | 大小写互调 |
> | 向右缩进一个单位 |
< | 向左缩进一个单位 |
比较常用的就是上面的几个。
下面我们来举几个栗子:
栗子一:
假设现在我们有下面一个C++文件
main
函数的头三行代码忘了加;
号了,现在我们要用可视模式为这三行代码加上分号首先
<C-v>
开启块选择模式,然后点击jj$
号选择到行末尾,选中区域如下所示
再用
A
在选中的区域后面添加文本;
,虽然在编辑的过程中只有一行文本看上去添加了分号,如下图
但是只用按下
<Esc>
,剩下的其余选中行也会自动添加分号,这里与其他编辑器稍有不同,新手应注意
栗子二:
下面是一个打开四个文件标识符的栗子
如果我们已经将四个文件
file1
,file2
,file3
,file4
移动到了新的目录/tmp/fileDir
里面,于是我们要将testDir
目录改为fileDir
目录
<C-v>
进入块选择
模式,并选中testDir
区域,如下图
点击
c
对选中区域进行替换,并输入fileDir
跟之前的栗子一样,只有一行文本发生改变,点击
<Esc>
使改变作用于全部选中区域
可视命令的重复
说到重复,首先想到的肯定是.
命令啦,可是这个重复命令可不一般,首先来看几个栗子:
字符文本模式栗子:
首先在
字符文本
模式下选中27
行的open
单词,并用g~
命令来将open
转为大写
注意这里我们选中的是四个字符,之后我们将光标向右移动几位,移动到单词
fileDir
的开头,我们点击.
重复上一个可视命令得到下面的结果:
我们惊奇的发现
OPEN
并没有转为预期的转为小写,而是fileDir
的前四个字符变成了大写
行文本模式栗子:
用
V
将27
行选中,并用g~
进行大小写转换
现在跳转到
31
行,单击.
重复命令
发现
31
行的全部文本全都进行大小写互换
块文本模式栗子:
点击
<C-v>
进入块文本
选择模式,随便选中一块区域,如下图
g~
进行大小写互换
现在我们将光标下移一行,并将光标移到图示位置
此时点击
.
,发现有下面的效果
我们发现从光标开始的右下角的一个矩形范围被调换了大小写,该矩形范围的大小与上次可视模式选中的区域大小一样
于是博主总结了一下,不同的选择模式有不同的重复效果
选择模式 | 重复效果 |
---|---|
字符文本选择模式(Visual ) | 从当前光标开始,作用范围是上次操作的字符数 |
行文本选择模式(Visual line ) | 从当前行开始,作用范围是上次操作的行数 |
块文本选择模式(Visual Block ) | 从当前光标开始,作用范围是以当前光标为左上端点的上次操作的块范围 |
最好使用操作符命令而不是可视命令
为什么这么讲呢?比如在字符文本
选择模式里面,如果我们要进行重复,那么重复的范围是通过上一次操作的字符数决定的,其中与上一次操作相同的字符数
就是一个很大的限制条件,必须这次操作的字符数与上次操作的字符数相同我们才可以放心的使用重复操作。
举个栗子:
我们要将
27-29
的printf
打印的内容全都转为大写
在
27
行,我们采用vi"
选中引号内的东西,U
将选中的内容转化为大写如果我们下移一行,用
.
重复上次操作,得到
发现只作用了前两个字符,后面的
llo
还是小写
不能重复上次的操作,难道还需要手动再来一遍?其实并不需要,我们只用使用普通模式
下面的操作符命令就可以啦
上面的栗子我们可以用操作符命令更好的实现需求
使用
gUi"
,将"
内的内容转化为大写,然后j.
就可以重复上一行的操作啦