Execute
execute
可以把一个字符串当做Vim的命令来执行。
1 2 |
:execute "echom 'Hello, world!'" " 相当于直接执行 echom 'Hello, world!' |
这个命令的强大之处在于,可以通过字符串来构造不同需要的命令,然后进一步执行。
实验:创建file.txt
并使用Vim打开,然后在Vim中执行 :edit foo.txt
,当前buffer会被foo.txt
覆盖。最后执行下面的命令:
1 |
:execute "rightbelow vsplit " . bufname("#") |
你会发现,窗口被分割成两个, 右边的窗口重新打开了file.txt
。
这个过程是:首先"rightbelow vsplit "
字符串先和bufname("#")
(这个命令的作用是,返回上一个buffer的路径)的结果进行连接。得到的字符串被执行。
Vim的Execute
命令危险吗?
通常来说,一个语言的类似eval
的命令都是比较危险的。因为这可能执行用户输入的代码,从而带来安全隐患。但是Vim不存在这个问题,原因有二:
第一,一般来说Vim只会接受一个人的输入,就是它的用户。如果用户想要输入一些危险的代码,也不是不可以,毕竟电脑是他们自己的。所以不存在什么安全隐患。
第二,VimScript有一些很奇怪的语法。这是execute
可能是最简单的方式。况且,Vim可以在一行中写很多代码。
Normal
有一些命令是在Normal模式下有用的,比如说跳到最后一行的G
。但是,通过normal
命令,我们可以模拟这个键是在normal
模式下按下的。
1 2 3 4 5 |
:normal G " 跳到最后一行 :normal ggdd " 跳到第一行并且删除这一行 |
有时候,一些键映射到了别的功能。比如
1 2 3 4 5 6 |
:nnoremap G dd :normal G " 将会删除当前行 :normal! G " map将不会起作用,G会跳到最后一行 |
我们使用normal!
,将会忽略定义的映射。在vimrc
文件中,就像我们应该永远使用noremap
一样,我们也应该永远使用normal!
。
normal
不会处理特殊字符。比如:normal! /foo<cr>
,乍一看是搜索foo
然后回车。但实际上,它会搜索foo左尖括号cr右尖括号
的字符串,而没有按下回车。
要解决这个问题,就结合execute
命令。
Execute Normal!
1 2 |
:execute "normal! gg/foo\<cr>dd" " 跳到第一行,然后跳到foo第一次出现的那行,删除那一行 |
由于execute
命令可以根据字符串执行命令,利用这个我们就可以使用Vim的字符串转义输入一些不可打印的字符。从而解决这个问题。
例子,下面的这个命令,可以在代码末尾添加一个分号,然后回到之前的位置。如果你看不懂,参考这里。
1 |
:execute "normal! mqA;\<esc>`q" |