107.02.07 如何寫 vim plugin

<注意>
本篇只會紀錄大致需要的架構和一些注意事項、建議以及參考資料
讓以後的我或是想寫一個自己 plugin 的人快速入手或是方便查找相關資料
本篇並不會真的教你寫出一個 plugin 喔

檔案架構

yourplugin/
    doc/
        yourplugin.txt
    plugin/
        yourplugin.vim
    ...
    README
    LICENSE

使用此架構主要是可以使其與 Pathogen 相容
關於 yourplugin 要不要取成 vim-yourplugin 或是 yourplugin.vim 我覺得都可以也都有人用
主要加上 vim- 或 .vim 可以一眼看出是 vim 相關的
但是也有有名的 plugin 是沒加的 e.g. w0rp/ale

注意事項

使用 normal!

一般在 plugin 內會使用 normal 來模擬按鍵,但應該使用 normal!
例如:模擬按下 Shift + ^ 可以把光標移到該行第一個字元
execute "normal! \<S-^>"
normal! 和  normal 差不多,但是會忽略使用者自行設定的按鍵映射
若不加 ! 可能會有其他無法預料的動作
例如:使用者將它映射到其他功能
nmap <S-^> dd
plugin 執行這行時就會變成按 dd 了
execute "normal \<S-^>"
" 變成 execute "normal dd"

使用 noremap

原因其實類似 normal!
主要是避免映射遞迴呼叫
例如:下方映射等同於 map c b
map a b
map c a
所以如果只是想要設定 map c a 但不希望使用者自己定義的 map a xxx 干擾就使用:
noremap c a

可選擇是否使用預設映射

應該要有個全域變數(e.g. g:yourplugin_use_default_mapping) 供使用者設定
這樣也可避免使用者自行設定其他映射時發生問題
使用:以我自己寫的為範例OuO
function! s:setUpKeyMap()
    execute "nnoremap <silent> ".g:commenter_n_key." :<C-u>call <SID>comment()<CR>"
    execute "inoremap <silent> ".g:commenter_i_key." <ESC>:<C-u>call <SID>comment()<CR>hi"
    execute "vnoremap <silent> ".g:commenter_v_key." :<C-u>call <SID>commentV(visualmode())<CR>"
endfunction
if g:commenter_use_default_mapping
    call s:setUpKeyMap()
endif

一些知識

變數


(nothing)
  In a function: local to a function; otherwise: global
b:
  Local to the current buffer.
w:
  Local to the current window.
t:
  Local to the current tab page.
g:
  Global.
l:
  Local to a function.
s:
  Local to a |:source|'ed Vim script.
a:
  Function argument (only inside a function).
v:
  Global, predefined by Vim.

判斷等於

建議不要使用 == 或 !=,應該加上 # 或 ? 表示大小寫是否影響判斷
use 'ignorecase'
match case
ignore case
equal
==
==#
==?
not equal
!=
!=#
!=?

coding style

Google Vimscript Style Guide
參考用但是還不錯,其他 style 就自己點進去看吧,我只記錄命名規則OuO
plugin-names-like-this
FunctionNamesLikeThis
CommandNamesLikeThis
variable_names_like_this


還不錯的寫法紀錄

初始化全域變數

來源:NERD_commenter
function! s:initVariable(var, value)
    if !exists(a:var)
        execute 'let ' . a:var . ' = ' . "'" . a:value . "'"
        return 1
    endif
    return 0
endfunction
call s:initVariable("g:commenter_use_default_mapping",  1)

好玩OuO

ASCII art:輸入英文轉成用符號代替


參考資料

Writing Vim Plugins
Learn Vimscript the Hard Way
Vim documentation: usr_41
Vim documentation: function-list:紀錄一堆 vim 裡可以被呼叫的函式
Vim scripting cheatsheet
另外可以去看我寫的 vim-commentervim-surrounder 都是偏簡單的,所以比較能看得懂(?

沒有留言:

張貼留言

^ Top