Vim插件开发实例
-
查看你的
runtimepath
在vim里输入:echo &runtimepath
, 一般windows的话, 有两处我们比较关心:C:\Users\yourusrname\vimfiles
C:\yourviminstalldir\vimfiles这样, 我们就可以在上面任一位置新建
autoload
目录, vim载入时(或者需要时)可以自动调用. -
一个
vimrc
文件
为了测试方便, 我给出一个简单的vimrc文件(放入vimfiles/
)set nocp filetype plugin indent on syntax on set st=2 set acd set wildmenu set wildmode=longest,list,full vnoremap ;x "*y vnoremap ;p "*p function! ToggleVerbose() if !&verbose set verbosefile=~/desktop/vimtex.log set verbose=15 else set verbose=0 set verbosefile= endif endfunction
-
第一个插件
现在我们来写第一个插件"myfirst plugin for vim "put it in $VIM/vimfiles/autoload/myfirstplug.vim fu! Initial() echom "Initializing the plugin" endfu echom 'Loading myfirstplug.vim' fu! myfirstplug#internal() echom "This is a autoload function" endfu echom 'Loading done!'
这样, 我们可以尝试调用
call Initial()
, 发现错误没有定义:E117: Unknown function: Initial
再次尝试调用
call myfirstplug#internal()
, 此时正常, 且返回:Loading myfirstplug.vim
Loading done!
This is a autoload function可见, vim的autoload机制是先根据
#
前部分找到autoload
下对应的文件, 并载入(source myfirstplug.vim
), 然后执行#
后面的函数internal()
. 由于此时myfirstplug.vim
已经载入, 故此时我们可以正常调用call Initial()
了. -
局部变量修饰的函数: 将我们的函数脚本改为
"myfirst plugin for vim "put it in $VIM/vimfiles/autoload/myfirstplug.vim fu! Initial() echom "Initializing the plugin" endfu fu! s:initial() echom "Another initializing function, local to this script" endfu echom 'Loading myfirstplug.vim' fu! myfirstplug#internal() echom "This is a autoload function" call s:initial() endfu echom 'Loading done!'
这里, 我们用到了一个变量前缀:
s:
, 表示只在当前脚本中有定义. 具体参考
:h internal-variables
前缀 含义 g:varname 变量为全局变量 s:varname 变量的范围为当前的脚本文件 w:varname 变量的范围为当前的编辑器窗口 t:varname 变量的范围为当前的编辑器选项卡 b:varname 变量的范围为当前的编辑器缓冲区 l:varname 变量的范围为当前的函数 a:varname 变量是当前函数的一个参数 v:varname 变量是 Vim 的预定义变量 &varname 一个 Vim 选项(如果指定的话,则为本地选项,否则为全局选项) &l:varname 本地 Vim 选项 &g:varname 全局 Vim 选项 @varname 一个 Vim 注册器 $varname 一个环境变量 即使我们通过
so %
来重载myfirstplug.vim
, 我们也不能通过:call s:internal()
来调用函数. 但是你发现在该脚本内部, 我们是可以正常调用的. 请运行:call myfirstplug#internal()
, 查看结果. -
函数的
abort
与dict
关键字, 我们增加如下函数fu! Callback(count) dict let thecounter=a:count while thecounter>0 echom "call for " . self.name . "at the ". thecounter "times" let thecounter -=1 endwhile endfu let context={"name": "dictfun"} let Func =function('Callback', [3], context)
通过
:call Func()
我们得到三次输出, 注意到self.name
被替换成dictfun
. -
断点调试
我们可以通过设置文件断点和函数断点来调试脚本: 例如:breakadd func Callback :breakadd file 20 */myfirstplug.vim
则在执行
:so myfirstplug.vim
时会停在第20行, 回车继续执行. 在执行:call Func()
时, 会自动停在函数Callback
开始处, 此时你可以通过echo a:count
查看count
值. 你甚至可以echo a:
看看. 此外s/n/c
表示step/next/continue.