darudaru

だるだるしてるエンジニア

初めてのvimプラグイン開発

vimrcの整理をしていたら、vimのプラグインを作ってみたくなりました。
ちなみに開発中のvimのプラグインは適当なディレクトリに設置しておいて、.vimrcのruntimepathにディレクトリパスを追加して動作確認してました。

まずプラグインの名前を決める

vimのコマンドを調べてもいざ使う時にすぐ忘れてしまうので、あらかじめメモしておいて、メモを開発中にチラ見できたらいいなと思っていました。それを実現してくれるプラグインを作ります。 プラグインは「cheat.vim」という名前にしました。cheatsheetからとりました。

プラグインの雛形を作成する

❯❯❯ tree cheat.vim 
cheat.vim
├── README.md
├── autoload
│   └── cheat.vim
└── plugin
    └── cheat.vim
  • plugin : vim起動時に読み込まれるスクリプトを置く
  • autoload:vim scriptから実行される関数のスクリプトを置く

pluginとautoloadでスクリプトを分けることで、必要になった時にだけ必要なスクリプトが読み込まれるようになり、vimの起動速度が速くなる。そうです。
今回自分が作ったプラグインは数行のスクリプトですが、重い処理があったり、スクリプト自体が重い場合はautoloadを使っていった方が良さそうです。

vim scriptを書く

実際に書いていきます。 各スクリプトで、最初に文字のエンコーディングの設定を入れておきます。
pluginにはメインの処理を、autoloadにはメインの処理から呼び出されるメソッドを書いていきますが、それ以外にグローバル変数を使ってスクリプトのロードを制御していきます。

文字のエンコーディングの設定

" pluginにもautoloadにも入れる
scriptencoding utf-8

ロードを制御する

ロードを制御するグローバル変数名はloaded_プラグイン名とするのがvim scriptのお作法らしいです。

plugin/cheat.vim
" g:cheat#loaded_cheatが存在していれば、既にpluginは読み込み済みなので、終了する
if exists('g:cheat#loaded_cheat')
    finish
endif
autoload/cheat.vim
" g:cheat#loaded_cheatが存在していなければ、pluginが読み込まれていないので終了する
if !exists('g:cheat#loaded_cheat')
    finish
endif
let g:cheat#loaded_cheat = 1

プラグインの処理を書く

plugin/cheat.vim
scriptencoding utf-8

if exists('g:cheat#loaded_cheat')
    finish
endif
let g:cheat#loaded_cheat = 1

command! -nargs=? Cheat call cheat#exec_cheat_sheet(<f-args>)
autoload/cheat.vim
scriptencoding utf-8

if !exists('g:cheat#loaded_cheat')
    finish
endif
let g:cheat#loaded_cheat = 1

function! cheat#exec_cheat_sheet(...)
    if exists('s:buf_cheat')
        call s:close_cheat_sheet()
        echo 'close cheatsheet.'
        return
    endif
    call s:open_cheat_sheet()
endfunction

function s:open_cheat_sheet()
    if !exists('g:cheat#cheat_sheet_path')
        echo 'Error: set g:cheat#cheat_sheet_path'
        return
    endif

    let l:path = expand(g:cheat#cheat_sheet_path)
    if !filereadable(l:path)
        echo 'Error: not found' l:path
        return
    endif

    execute 'split'
    execute 'view' g:cheat#cheat_sheet_path
    let s:buf_cheat =  bufnr("%")
    return
endfunction

function! s:close_cheat_sheet()
    execute 'bd' s:buf_cheat
    unlet s:buf_cheat
    return
endfunction

プラグインを実行する

:Cheatを実行すると、指定したパスのテキストファイルがバッファに表示される。もう1回:Cheatを実行するとバッファが閉じます。 f:id:skanoemon:20180210180921p:plain

最後にGithubで公開

READMEを書いたら、Githubに公開します。

github.com

deinでkanoemon/cheat.vimと記述するとプラグインがインストールされます。

感想

今までプラグインを入れた時の初期設定を言われるがままに書いていたけど、今回自分でvim scriptを書いてみてvimへの理解が深まりました。
vim scriptの書き方に少し手こずりましたが、ルールさえ分かれば簡単にプラグインを作ることができました。vimの良さはこのカスタマイズのしやすさですな。