rob*_*csi 2 vim plugins vim-plugin
我正在编写一个小的vim插件和:source %-vim文件,因为我进行了增量更改.
在每次更改和:source命令之后,似乎没有加载/应用最新的更改,因此我想以:source某种方式取消/卸载文件而不关闭并重新打开VIm.
有一个更好的方法吗?编写VIm插件并尝试新功能时,正确的工作流程应该是什么?
谢谢
为了总结评论.
功能和命令需要定义为banged - > function!,command!
需要清除自动命令.我通常这样做:
augroup MyPluginNameOrFeature
au! " <- this clears all autocommands defined in the group MyPluginNameOrFeature
au Event pattern action
aug END
Run Code Online (Sandbox Code Playgroud)
需要绕过反重建人员.例如,我的插件通常以这种方式定义:
" plugin/foobar.vim
let s:k_version = '100'
if &cp || (exists("g:loaded_foobar")
\ && (g:loaded_foobar>= s:k_version)
\ && !exists('g:force_reload_foobar'))
finish
endif
let g:loaded_foobar= s:k_version
let s:cpo_save=&cpo
set cpo&vim
... plugin definitions (mappings, commands, autocommand, abbreviation)
... understand that functions are in autoload-plugin which don't have anti-reinclusion guards
let &cpo=s:cpo_save
Run Code Online (Sandbox Code Playgroud)
这意味着您必须在保存和重新加载之前增加版本号,或者g:force_reload_foobar在重新加载脚本之前需要设置为1.因此我的:Reload命令(它与其他两个答案中提供的命令相同 - 这个支持相对于'runtimepath'选项的命令行自动完成)
对于我们可以创建的对象:
function! namespace#make_my_object(args)
let res = {}
" don't write the following if you want to be able
" to override the member function definitions when reloading the script
" and if you want to be able to decode which function appears in
" the callstack
" :function! res.foo() abort
" code
" :endfunction
" Instead write:
let res.foo = function('s:foo') " with later vim versions
let res.foo = function(s:getSNR('s:foo')) " with older vim versions
return res
endfunction
function! s:foo() dict abort
code
endfunction
function! s:getSNR(...) abort
" needed to assure compatibility with old vim versions
if !exists("s:SNR")
let s:SNR=matchstr(expand('<sfile>'), '<SNR>\d\+_\zegetSNR$')
endif
return s:SNR . (a:0>0 ? (a:1) : '')
endfunction
Run Code Online (Sandbox Code Playgroud)
否则,如果您已经解压缩:let o = namespace#make_my_object(42),则重新获取脚本将不会更新对象方法的定义.:Reload plugin/foobar.vim | :call o.foo()
覆盖/重新初始化变量非常简单.只要给它一个新的价值.但是,如果您的vim版本不够新,您将无法更改数据类型.很容易检查vim在你身边的行为:
let s:foo = 'bar'
let s:foo = {}
Run Code Online (Sandbox Code Playgroud)
如果最终出现错误,您可能需要添加一个明确的:silent! unlet s:foo.但是,如果您打算通过vim-client-server功能和vimrunner在tracis-CI中测试它,请不要将它留在脚本中.相反,测试if exists('s:foo') |unlet s:foo | endif- :silent在redirvimrunner中使用时不是那么沉默.
有时我们不想重新初始化变量但保留先前的值.在这种情况下,写下类似的东西:
let s:foo = get(s:, 'foo', default_value)
let g:foo = get(g:, 'foo', another_default_value)
Run Code Online (Sandbox Code Playgroud)
在他们的情况下没有太多事情可做,因为它们会被新定义自动覆盖.要注意的主要事情是当您提供<Plug>mappings默认和唯一键绑定来触发它们时.
例如:
nnoremap <silent> <Plug>(some-feature) TheActionToExecute
if !hasmapto('<Plug>(some-feature)', 'n')
nmap <silent> <unique> <leader>default-keybinding <Plug>(some-feature)
endif
Run Code Online (Sandbox Code Playgroud)
<unique> 对于检测歧义/太多想要绑定到同一个键序列的动作非常有用.
菜单也是如此:提供新定义会覆盖前一个定义.但是将操作绑定到新的菜单条目(名称和优先级)就像将映射绑定到新的键序列:旧的键序列不会被删除.最好是暂时(在你的vim会话期间)语义上重载一些触发器 - >动作定义:有几种方法可以触发语义相同的动作.它通常不那么重要.
我没有具体说明ftplugins的情况,也没有其他脚本类型.我看到的唯一区别是反重新保护,以及在ftplugin的情况下映射,命令和缩写是缓冲本地的事实.