vim 从嫌弃到依赖(9)——命令模式进阶
上一篇文章更新还是在51前,最近发生了很多事情了,全国各地的疫情又有蔓延的趋势,北京朝阳区都已经开始实施居家办公。各位小伙伴请注意安全,安全平安的度过这个疫情。
废话不多说了,接着上次的内容往下写。
在上一个篇章中,我们介绍了命令模式的使用,也通过一些例子理解了在需要大范围操作文本或者进行光标跳转的情况下,相比于使用普通模式中的operator + motion
来说,使用范围加命令的方式更快速而且也更方便。同时也以copy
和 move
操作,介绍了操作文本命令的一搬用法。接下来就要继续往前走,介绍命令模式的其他用法了。
命令行模式下使用普通模式的命令
当初在第一次介绍.
命令的时候相信各位小伙伴应该有一个遗憾,怎么没有介绍.
命令类似数字 + .
以达到重复执行目的的操作呢。如果有这么一个操作那岂不是如虎添翼。甚至可能有小伙伴自己亲自去尝试过,发现失败了。vim并没有提供类似的操作。那么要完成这件任务该如何来操作呢,之前的例子只有3行,每次使用.
之后使用j
来移动然后再使用.
也没几次,这个成本是可以接受的,但是如果是将文件中所有代码行的尾部都加分号,而且这个文件有上百行甚至上千行代码呢。
之前针对这个例子给出了不同的解决方案,在学习.
命令的时候,是使用.
命令,在学习可视模式的时候使用处理列的可视模式。现在再介绍一种新的方式,通过在命令行模式中使用normal
关键字来告诉vim,我们将要使用普通模式的命令。
它使用的方式为:range + normal + operator
,它支持范围操作,表示我们将要针对某个范围来执行普通模式的操作
针对这个例子,首先要构造一个可以使用.
命令的操作,即我们在首行使用A;
在行尾添加分号,接着配合命令模式的范围,加上2,$normal.
表示我们将要从第二行到尾行来执行.
命令
这个在使用.
的时候,我们相当于在重复执行A;
的普通模式的命令,那么是不是可以做这样的猜想,使用:normal
也可以执行 A;
这样的命令做到同时切换输入模式并且自动输入字符,而不仅仅局限于执行operator
呢?我们可以将上述修改使用2u
回退,然后针对这个猜想做验证,输入:%moral A;
我们发现它确实成功完成了这样的操作。也就是说normal后是可以跟一些改变当前模式的命令并且可以指定输入的内容的。
这样我们在快速删除一个文件的所有内容上,又有一种新办法了:$normal dd
但是相比起 :%d
来说要输入的字符更多罢了。他们的区别相信看到现在的小伙伴应该很熟悉了。这里就不再解释了,感兴趣的小伙伴也可以在评论区给出自己的答案。
重复上次的ex命令
在普通模式下.
可以重复上一次的修改,但是某些ex命令并没有对其进行修改,如果我想重复通过.
来重复上次的ex命令则无能为力了。而且通过实验也可以发现,它也无法重复由ex命令造成的修改。
可以使用@:
重复上一次的命令。如果执行过 @:
进行重复,那么可以使用@@
再次执行上次重复的命令,例如在编写代码时经常会一到的一个问题就是将当前行代码下移一行,但是也不是所有的行都会这么干,那么就可以先使用 .m.+1
将当前位置的代码移动到光标的下一行,然后移动光标,在下一个需要次操作的位置执行 @:
,后面就可以直接使用 @@
来重复上一次的操作了。这里就不再针对它来做演示了。各位小伙伴可以自己来尝试一下
自动补全ex命令
在使用shell
命令的时候,使用tab
可以很方便的进行补全,而在使用命令模式的时候也有这个功能
vim在使用tab时会自动检索之前输入的历史进行匹配。例如,使用 :%n<tab>
。它会匹配到一堆符合要求的命令。多次按下 <tab>
键则会依次按从上到下的顺序进行匹配。也可以使用 <Ctrl n>
和 <Ctrl p>
跳转到下一次匹配和上一次匹配。同样的也可以使用 <Shift Tab>
来跳转到上一次匹配
默认情况下,会按照上述例子中的样式来展示匹配项,但是你也可以自定义匹配项,使用wildmode
来修改补全行为。但是需要事先打开 wildmenu
选项。
可以使用 :h wildmode
和 :h wildmenu
来查看对应的帮助文档。这里我给出我习惯使用的配置
vim.o.wildmenu = true
vim.o.wildmode="full"
set wildmenu
set wildmode=full
当然你不进行这样的配置也行,neovim
模式的补全模式就是这种
回溯命令历史
在 shell
中,可以使用上下键直接输入上次输入的命令或者在 bash_history
中记录了之前执行过的命令,vim也有同样的设计
按下 :
进入到命令模式之后,可以使用方向键向上或者向下查找历史命令。
除了使用 方向键以外,还可以使用 <Ctrl p>
和 <Ctrl n>
来遍历,但是使用方向键有一个好处是他们可以针对之前已经输入的内容对匹配的内容进行过滤。坏处在于,手指的移动幅度大,我们可以使用映射的方式将<Ctrl p>
和 <Ctrl n>
进行映射。这里我们仍然等到讲述快捷键映射的时候给出代码
运行shell 命令
在vim的命令模式中也可以执行shell命令。只需要在shell命令前面加上 !
即可,例如执行 :!ls
将会执行ls
这个命令
在vim的命令模式中,%
代表的是当前文件名,在运行某些可以传入文件名作为参数的命令时,可以使用它,例如我要执行当前的Python代码时可以使用 :!python %
我们也可以将vim命令模式中的范围配合shell命令使用,这个时候范围中包含的内容将会作为shell命令的输入, 例如现在有这么一个文件,记录了一个文件列表,现在我想要按照文件名排序
files:
a.txt
ccc.txt
b.txt
d.txt
z.txt
t.txt
可以配合sort
使用 :2,$!sort
,由于第一行是表头的文字不进行排序,所这里从第2行开始参与排序
使用 write 和read 命令重定向vim缓冲区内容
在vim配合shell命令使用的时候有时候shell会产生大量是输入或者需要一定的输出,那么就可以使用 write 和 read 来配合shell使用。
- read:vim从shell产生的输出中读取内容写入缓冲区
- write: vim将缓冲区的内容写入到shell中,作为shell的输入
例如某个文件中有大量的Python代码,但是我只想执行部分,那么可以配合write使用,例如3,5write !python
执行文件中3-5行的Python代码,或者配合可视模式,执行选中的代码
再比如,我现在需要获取当前目录下有多少个文件和目录,并且按照文件名顺序排列,就可以使用 :read !ls|sort
。
甚至配合键绑定,完成ide那种一件自动编译运行的效果。例如
vim.api.nvim_set_keymap('n', '<F5>', ':write | !python %<CR>', {noremap = true, silent = true})
配合文件类型识别可以做到一键执行其他类型的代码,将vim 打造成IDE不是梦想
除了手工填写范围配合shell命令之外,vim提供了一种简便的方式来完成这一工作,可以使用 !{motion}
来快速形成范围,后面只需要输入命令即可,针对前面排序文件的例子,假设光标在文件的第二行,可以使用在普通模式下输入!G
来快速选中整行,vim为我们在右下角填充了:.,$!
后面只需要写上sort
之后就可以了
到此为止,我们已经通过介绍不同的模式,将vim编辑文本的功能大致给展示了一下,相信各位小伙伴看到这里已经了解到了vim在编辑文本的强大。但是这并不是vim的全部,后面将详细介绍如何通过vim来组织文件、项目工程等功能。请各位敬请期待