NeoBundle 是什麼
NeoBundle 的開發者是 neocomplcache 和 unite.vim 的作者 Shougo,他的 Vundle fork 改了太多東西,就獨立出來了。
使用上除了 :BundleInstall
的花俏畫面不見外,其他沒什麼損失;
新增功能(部份是實驗性的)則包括:
-
鎖定 plugin 版本,有新版也不更新
不想一直踩地雷的話,這個會很實用:
NeoBundle 'Shougo/vimshell', '3787e5'
-
支援 svn 和 Mercurial (hg) repository
使用 type
參數指定 svn 或 hg,也能從 URL 自動判斷:
NeoBundle 'some.hg.repo.url', {'type': 'hg'}
其實 Vundle 也有實作,但目前未採用,理由參考
Pull Request #134: Adding more DVCS support by ralesi · gmarik/vundle,
比較傾向將來以 Vundle plugin 的方式實現。
-
自動使用 vimproc
如果有裝 vimproc,就會用 vimproc 執行外部指令。(這個我沒用過)
-
unite.vim 介面
用途類似 Vundle 的 interactive mode,另開 window 瀏覽 plugin,可以各別按 i 進行 Install 等操作。
我認為 unite.vim 介面比較親切,因為不必學特殊 key mapping。
註::Unite neobundle
基本上需要裝 vimproc,否則只有 neobundle/log、neobundle/lazy 和 neobundle/search 可用。
-
base 和 nosync 選項
base
可以把特定 plugin 安裝在不一樣的目錄,nosync
可以讓 plugin 不自動更新,變成很例外的處理。
NeoBundle 'muttator', {'type': 'nosync', 'base': '~/.vim/bundle'}
我發現測試 local plugin 的時候很好用,後述。
-
build 選項
安裝時可以自動執行指定的 script,如果 plugin 需要編譯就會有用:
NeoBundle 'Shougo/vimproc', {
\ 'build': {
\ 'windows': 'echo "Sorry, cannot update vimproc binary file in Windows."',
\ 'cygwin': 'make -f make_cygwin.mak',
\ 'mac': 'make -f make_mac.mak',
\ 'unix': 'make -f make_unix.mak',
\ },
\ }
Vundle 作法是提供 callback 介面,不過目前還放在 events branch。
-
Lazy Load
少用的 plugin,可以先不加進 runtimepath 以縮短啟動時間。
NeoBundleLazy 'klen/python-mode'
需要的時候再用 :NeoBundleSource
讀進來:
autocmd FileType python NeoBundleSource python-mode
或許可以用 autocommand FuncUndefined 達成自動 source 的功能。
-
其他看不見的變更
相信 NeoBundle 還重寫了很多東西,比如「改善 :NeoBundle
的效率」。
不過這些東西在 doc 甚至 commit log 都不很清楚,其實也是個問題。
忘掉安裝程序
從 Vundle 轉換到 NeoBundle,大致上把一些目錄、指令改名即可,安裝過程幾乎沒變。
不過整個流程還是太特殊/脫序了,我不想每次查文件,所以乾脆把檢查寫進 .vimrc,若有問題,直接提示我該怎麼做。
-
設定一個目錄放所有 plugin,通常是 ~/.vim(我會視環境調整)下的 bundle 目錄。
(之後我會把預設的 runtimepath (~/.vim) 砍掉,讓 Vim 只吃 bundle 目錄裡的 script)
然後把 neobundle.vim 加進 runtimepath,才能繼續安裝。
if has("gui_win32")
if exists('g:gvim_rtp') && isdirectory(fnamemodify(g:gvim_rtp, ':p'))
let s:rtp = g:gvim_rtp
else
echoerr "You must set runtimepath (for plugin bundling) manually."
finish
endif
else
let s:rtp = "~/.vim"
endif
if !isdirectory(fnamemodify(s:rtp, ':p'))
try
call mkdir(fnamemodify(s:rtp, ':p'), "p")
catch /^Vim\%((\a\+)\)\=:E739/
echoerr "Error detected while processing: " . v:throwpoint . ":\n " . v:exception .
\ "\nCan't make runtime directory. Skipped sourcing vimrc.\n"
finish
endtry
endif
execute "set runtimepath+=" . fnamemodify(s:rtp, ':p') . "bundle/neobundle.vim"
-
呼叫
neobundle#rc
。
失敗的話就是沒裝 NeoBundle,請提示我 git clone
到剛設定的目錄。
try
call neobundle#rc(fnamemodify(s:rtp, ':p') . "bundle")
catch /^Vim\%((\a\+)\)\=:E117/
echoerr "Error detected while processing: " . v:throwpoint . ":\n " . v:exception .
\ "\n\nNo 'Bundle plugin' installed for this vimrc. Skipped sourcing plugins." .
\ "\n\nTo install one:\n " .
\ "git clone http://github.com/Shougo/neobundle.vim.git " . fnamemodify(s:rtp, ":p") . "bundle/neobundle.vim\n"
finish
endtry
註:步驟 1、2 要包進 if has('vim_starting') ... endif
才不會每次讀 .vimrc 時都做。
-
filetype off
。
這個步驟我沒研究為什麼 doc 說必須做(而且要在一開始做?),拿掉好像也沒事。
接著移除預設 runtimepath。
filetype off
set runtimepath-=~/.vim
-
列出要裝的 plugin,最後再把 filetype 開回來。
NeoBundle 'Shougo/neobundle.vim'
NeoBundle 'nginx.vim'
NeoBundle '有幾個 plugin,這裡就加幾行'
filetype plugin indent on
註:實際上我不在這做 :NeoBundle
,而是用後述 s:bundles 處理。
-
這樣就完成 NeoBundle 設定了。
進入 Vim 執行 :NeoBundleInstall
把 plugin 都裝起來。
安裝後 :NeoBundleLog
可以看 log,個人感覺比 Vundle 的輸出有用。
自己控制 bundle 列表
把舊的 :Bundle
全部換成 :NeoBundle
也是很空虛的動作,所以我把 plugin 列表寫成陣列,這樣即使回鍋 Vundle 也比較好改。
-
建立 s:bundles 變數,就可以自訂選項,減少對 bundle plugin 的依賴。
let s:bundles = [
\ ['Shougo/neobundle.vim'],
\ ['L9'],
\ ]
let s:bundles += [
\ ['bootleq/vim-gitdiffall', {":prefer_local": 1}],
\ ['nginx.vim'],
\ ]
-
此處的自訂選項有 :skip 和 :prefer_local。
:skip 就是不要裝,因為寫成陣列就不能直接註解掉一行了……
:prefer_local 則是為了測試 plugin 方便,如果這個 plugin 有一份 repository 裝在 ~/repository,那就是我自己亂改的版本,請 NeoBundle 還是要讀它,但更新的時候要跳過。
for bundle in s:bundles
let s:tmp_options = get(bundle, 1, {})
if get(s:tmp_options, ":skip")
continue
elseif get(s:tmp_options, ":prefer_local")
if isdirectory(fnamemodify('~/repository/' . split(bundle[0], '/')[-1], ':p'))
let s:tmp_options = {"base": '~/repository', "type": "nosync"}
endif
endif
call filter(s:tmp_options, "v:key[0] != ':'")
execute "NeoBundle " . string(bundle[0]) . (empty(s:tmp_options) ? '' : ', ' . string(s:tmp_options))
endfor
unlet! s:bundles s:tmp_options
Windows 沒有 git 怎麼辦
其實這次整理 plugin 最想做的是更新 Windows 上的 bundle,結果沒什麼進展。
最後做法是:
- 從有 git 的環境複製 .vimrc 和整個 bundle 目錄。
- gVim 的 vimrc 去
:source
真正使用的 .vimrc。