Vim 自定义命令是 Vim 编辑器的一个强大功能,它可以让用户根据自己的需求创建自定义的命令,从而提高编辑效率。
Vim 自定义命令的使用方法很简单,可以通过在 Vim 的命令行中输入“:command”来创建一个新的命令。例如,如果要创建一个名为“mycommand”的新命令,可以在 Vim 命令行中输入:
:command mycommand :echo "Hello World!"
上面这条命令会创建一个名为“mycommand”的新命令,当执行该命令时会显示 “Hello World!” 字样。
此外,Vim 还支持将多条命令封装成一个函数(function)来执行。例如,可以将上面的 mycommand 命令封装成一个函数:
function! MyCommand() echo "Hello World!" endfunction :command MyCommand call MyCommand()
上面这条代码会首先定义一个名为 MyCommand 的函数,然后再使用 :command 命令将该函数封装成一个新的 Vim 命令。当执行该命令时会显示 “Hello World!” 字样。
Vim 还支持将外部 shell 命令封装成 Vim 命令。例如可将 ls -l 命令封装成 listfiles 命令来执行:
:command listfiles !ls -l
上面这条代码会首先使用 ! 标志将 ls -l 命令封装成 listfiles 命
前面几章我们学习了自动命令。执行下面命令:
:autocmd BufWrite * :echom "Writing buffer!"
现在使用:write
命令将当前缓冲区写入文件,然后执行:messages
命令查看消息日志。你会看到Writing buffer!
在消息列表中。
然后将当前缓冲区写入文件,执行:messages
查看消息日志。你会看到Writing buffer!
在消息列表中出现了两次。
现在再次执行上面的自动命令:
:autocmd BufWrite * :echom "Writing buffer!"
再次将当前缓冲区写入文件并执行:messages
命令。你会看到Writing buffer!
在消息列表中出现了_4_次,这是怎么回事?
这是因为当你以上面的方式创建第二个自动命令的时候,Vim没办法知道你是想替换第一个自动命令。在上面的示例中,Vim创建了两个_不同_的自动命令,并且这两个命令刚好做同样的事情。
既然你现在知道了Vim可能创建两个完全一样的自动命令,你可能会想:“有什么大不了?只要别这么干就可以!”。
问题是当你加载你的~/.vimrc
文件的时候,Vim会重新读取整个文件,包括你所定义的任何自动命令!这就意味着每次你加载你的~/.vimrc
文件的时候,Vim都会复制之前的自动命令,这会降低Vim的运行速度,因为它会一次又一次地执行相同的命令。
你可以执行下面的命令模拟这种情况:
:autocmd BufWrite * :sleep 200m
现在将当前缓冲区写入文件。你可能注意到Vim在写入文件的时候有点缓慢,当然也你可能注意不到。现在执行上面的自动命令三次:
:autocmd BufWrite * :sleep 200m
:autocmd BufWrite * :sleep 200m
:autocmd BufWrite * :sleep 200m
再次写文件。这次会更明显。
当然你不会创建任何只是进行sleep而不做任何事情的自动命令,不过一个使用Vim的老鸟的~/.vimrc
文件可以轻易达到1000行,其中会有很多自动命令。再加上安装的插件中的自动命令,这肯定会影响Vim的速度。
对于这个问题,Vim有一个解决方案。这个解决方案的第一步是将相关的自动命令收集起来放到一个已命名的组(groups)中。
新开一个Vim实例,这样可以清除之前所创建的自动命令。然后运行下面的命令:
:augroup testgroup
: autocmd BufWrite * :echom "Foo"
: autocmd BufWrite * :echom "Bar"
:augroup END
中间两行的缩进没有什么含义,如果你不想输入的话可以不输。
将一个缓冲区写入文件然后执行:messages
。你应该可以在消息日志列表中看到Foo
和Bar
。现在执行下面的命令:
:augroup testgroup
: autocmd BufWrite * :echom "Baz"
:augroup END
当你再次将缓冲区写入文件的时候猜猜会发生什么。ok,你也许已经有结果了,重新写入缓冲区,然后执行:messages
命令,看看你猜对了没。
当你写入文件的时候发生什么了?猜对了么?
如果你认为Vim会替换那个组,那么你猜错了。不要紧,很多人刚开始的时候都会这么想(我也是)。
当你多次使用augroup
的时候,Vim每次都会组合那些组。
如果你想清除一个组,你可以把autocmd!
这个命令包含在组里面。执行下面的命令:
:augroup testgroup
: autocmd!
: autocmd BufWrite * :echom "Cats"
:augroup END
现在试试写入文件然后执行:messages
查看消息日志。这次Vim只会输出Cats
在消息列表中。
既然我们现在知道了怎么把自动命令放到一个组里面以及怎么清除这些组,我们可以使用这种方式将自动命令添加到~/.vimrc
中,这样每次加载它的时候就不会复制自动命令了。
添加下面的命令到你的~/.vimrc
文件中:
augroup filetype_html
autocmd!
autocmd FileType html nnoremap <buffer> <localleader>f Vatzf
augroup END
当进入filetype_html
这个组的时候,我们会立即清除这个组,然后定义一个自动命令,然后退出这个组。当我们再次加载~/.vimrc
文件的时候,清除组命令会阻止Vim添加一个一模一样的自动命令。
查看你的~/.vimrc
文件,然后把所有的自动命令用上面组的方式包裹起来。如果你觉得有必要,可以把多个自动命令放到一个组里面。
想想上一节的示例中的自动命令是干啥的。
阅读:help autocmd-groups
。
XSLT xsl:value-of 元素XSLTxsl:value-of元素有两个作用,你可以通过本节的内容对其进行了解。 XSLT 元素参考手册定义和用法 xsl...
JavaScript RegExp ^ 量词 JavaSript RegExp 对象定义和用法 ^n量词匹配任何开头为 n 的字符串。 语法new RegExp("^n")或者/^n/...
XML 元素 XML 元素是 XML 文档中必不可缺的部分,我们可以将 XML 元素看成一个容器,其中存放了文本,元素,属性,媒体对象或所...
Anchor hreflang 属性 Anchor对象定义和用法 hreflang 属性可设置或返回链接中 hreflang 属性的值。hreflang 属性可设置或返回被...
Video preload 属性 Video 对象实例查看页面一旦加载是否开始加载视频:var x = document.getElementById(myVideo).preload;x输...
Video duration 属性 Video 对象实例获得当前视频的长度:var x = document.getElementById(myVideo).duration;x 输出结果为:12....
Select type 属性 Select 对象定义和用法type 属性可返回下拉列表的表单类型。对于下拉列表,类型总是 select-one 或 select-mul...
HTML canvas shadowOffsetX 属性 Canvas 对象实例绘制一个矩形,带有向右偏移 20 像素的阴影(从矩形的 left 位置):Yourbrowse...
ul.toc { padding: 5px 20px; border-top: 1px solid #FFF; background-color: #F2FBF7; font-size: 86%; } ul.toc li { display...