W3Cschool
恭喜您成為首批注冊用戶
獲得88經(jīng)驗值獎勵
我們已經(jīng)為我們的Potion插件寫了大量的功能,覆蓋了本書所要講的內容。 在結束之前,我們將講到一些非常重要的方法,可以給我們的插件錦上添花。
第一項是使用自動加載讓我們的插件更有效率。
目前,當用戶加載我們的插件時(比如打開了一個Potion文件),所有的功能都會被加載。 我們的插件還很小,所以這大概不是什么大問題,但對于較大的插件,加載全部代碼將會導致可被察覺的卡頓。
Vim使用稱為"自動加載(autoload)"來解決這個問題。自動加載讓你直到需要時才加載某一部分代碼。 會有一些性能上的損失,但如果用戶不總是需要你的插件的每一行代碼,自動加載將帶來速度上的飛躍。
示范一下它是怎么工作的??纯聪旅娴拿睿?/p>
:call somefile#Hello()
當你執(zhí)行這個命令,Vim的行為與平常的函數(shù)調用有些許不同。
如果這個函數(shù)已經(jīng)加載了,Vim簡單地像平常一樣調用它。
否則Vim將在你的~/.vim
(或~/.vim/bundles/對應的插件/autoload
)下查找一個叫做autoload/somefile.vim
的文件。
如果文件存在,Vim將加載/source文件。接著Vim就會像平常一樣調用它。
在這個文件內,函數(shù)應該這樣定義:
function somefile#Hello()
" ...
endfunction
你可以在函數(shù)名中使用多個#
來表示子目錄。舉個例子:
:call myplugin#somefile#Hello()
這將在autoload/myplugin/somefile.vim
查找自動加載文件。 里面的函數(shù)需要使用自動加載的絕對路徑進行定義:
function myplugin#somefile#Hello()
" ...
endfunction
為了更好地理解自動加載,讓我們實驗一下。 創(chuàng)建一個~/.vim/autoload/example.vim
文件并加入下面的內容:
echom "Loading..."
function! example#Hello()
echom "Hello, world!"
endfunction
echom "Done loading."
保存文件并執(zhí)行:call example#Hello()
。Vim將輸出下面內容:
Loading...
Done loading.
Hello, world!
這個小演示證明了幾件事:
example.vim
文件。當我們打開Vim的時候它并不存在,所以不可能是在啟動時加載的。先不要關閉Vim,修改函數(shù)的定義成這樣:
echom "Loading..."
function! example#Hello()
echom "Hello AGAIN, world!"
endfunction
echom "Done loading."
保存文件并不要關閉Vim,執(zhí)行:call example#Hello()
。Vim將簡單地輸出:
Hello, world!
Vim已經(jīng)有了example#Hello
的一個定義,所以它不再需要重新加載文件,這意味著:
現(xiàn)在執(zhí)行:call example#BadFunction()
。你將再一次看到加載信息,伴隨著一個函數(shù)不存在的錯誤。 但現(xiàn)在嘗試再次執(zhí)行:call example#Hello()
。這次你將看到更新后的信息!
目前為止你應該清晰地了解到Vim會怎么處理一個自動加載類型的函數(shù)調用吧:
如果你還是沒有完成弄懂,回到前面重新過一遍演示,注意觀察每條規(guī)則生效的地方。
自動加載不是沒有缺陷的。 設置了自動加載后,會有一些(小的)運行開銷,更別說你不得不在你的代碼里容忍丑陋的函數(shù)名了。
正因為如此,如果你不是寫一個用戶會在_每次_打開Vim對話時都用到的插件,最好盡量把功能代碼都挪到autoload文件中去。 這將減少你的插件在用戶啟動Vim時的影響,尤其是在人們安裝了越來越多的插件的今天。
所以有什么是可以安全地自動加載?那些不由你的用戶直接調用的部分。 映射和自定義命令不能自動加載(因為它們需要由用戶調用),但別的許多東西都可以。
讓我們看看Potion插件里有什么可以自動加載的。
我們將從編譯和執(zhí)行功能開始下手。 在前一章的最后,我們的ftplugin/potion/running.vim
文件大概是這樣:
if !exists("g:potion_command")
let g:potion_command = "/Users/sjl/src/potion/potion"
endif
function! PotionCompileAndRunFile()
silent !clear
execute "!" . g:potion_command . " " . bufname("%")
endfunction
function! PotionShowBytecode()
" Get the bytecode.
let bytecode = system(g:potion_command . " -c -V " . bufname("%"))
" Open a new split and set it up.
vsplit __Potion_Bytecode__
normal! ggdG
setlocal filetype=potionbytecode
setlocal buftype=nofile
" Insert the bytecode.
call append(0, split(bytecode, '\v\n'))
endfunction
nnoremap <buffer> <localleader>r :call PotionCompileAndRunFile()<cr>
nnoremap <buffer> <localleader>b :call PotionShowBytecode()<cr>
這個文件僅僅當Potion文件加載時才會調用,所以它通常不會影響Vim的啟動時間。 但可能會有一些用戶就是不想要這些功能,所以如果我們可以自動加載某些部分, 每次打開Potion文件時可以省下他們以毫秒記的時間。
是的,這種情況下我們不會節(jié)省多少。 但你可以想象到可能有那么一個插件包括了數(shù)千行可以通過自動加載來減少每次的加載時間的代碼。
讓我們開始吧。在你的插件repo中創(chuàng)建一個autoload/potion/running.vim
文件。 然后移動兩個函數(shù)進去,并修改它們的名字,讓它們看上去像:
echom "Autoloading..."
function! potion#running#PotionCompileAndRunFile()
silent !clear
execute "!" . g:potion_command . " " . bufname("%")
endfunction
function! potion#running#PotionShowBytecode()
" Get the bytecode.
let bytecode = system(g:potion_command . " -c -V " . bufname("%"))
" Open a new split and set it up.
vsplit __Potion_Bytecode__
normal! ggdG
setlocal filetype=potionbytecode
setlocal buftype=nofile
" Insert the bytecode.
call append(0, split(bytecode, '\v\n'))
endfunction
注意potion#running
部分的函數(shù)名怎么匹配它們所在的路徑。 現(xiàn)在修改ftplugin/potion/running.vim
文件成這樣:
if !exists("g:potion_command")
let g:potion_command = "/Users/sjl/src/potion/potion"
endif
nnoremap <buffer> <localleader>r
\ :call potion#running#PotionCompileAndRunFile()<cr>
nnoremap <buffer> <localleader>b
\ :call potion#running#PotionShowBytecode()<cr>
保存文件,關閉Vim,然后打開你的factorial.pn
文件。嘗試這些映射,確保它們依然正常工作。
確保你僅僅在第一次執(zhí)行其中一個映射的時候才看到診斷信息Autoloading...
(你可能需要使用:message
來看到)。 一旦認為自動加載正常工作,你可以移除那些信息。
正如你看到的,我們保留nnoremap
映射部分不變。 我們不能自動加載它們,不然用戶就沒辦法引發(fā)自動加載了!
你將在Vim插件中普遍看到:大多數(shù)的功能將位于自動加載函數(shù)中,僅有nnoremap
和command
命令每次都被Vim加載。 每次你寫一個有用的Vim插件時,不要忘了這一點。
閱讀:help autoload
稍微測試一下并弄懂自動加載變量是怎么一回事。
假設你想要強制加載一個Vim已經(jīng)加載的自動加載文件,并不會驚擾到用戶。 你會怎么做?你可能想要閱讀:help silent!
(譯注:此處應該是:help :silent
)。不過在現(xiàn)實生活中請不要那么做。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網(wǎng)安備35020302033924號
違法和不良信息舉報電話:173-0602-2364|舉報郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯(lián)系方式:
更多建議: