やりたいこと
-
vimのプラグイン作りたい
-
でもvimscriptわからん!!
-
Pythonで書きたい!!!!
つくるもの
-
MyNameIs <name>
と入力すると、Hello <name>
と表示される -
実装はpythonに逃がして、vimscriptはpythonラッパーのような形で使う
VimScriptでのPython
よく使うのは、python
と pyfile
pythonとpyfileは本質的には同じで、ソースが直書きされているかファイルに分離されているかの違い。たとえば、次の2つのコードは同じ
python:
python print('Hello')
pyfile
pyfile hello.py
print('Hello')
pythonと書いたらその行は既にPythonの世界であることに注意する。次のように書いて随分と悩んだ。
function! hello#hello(name)
python hello_hello(a:name)
endfuncion
これが間違いであることは、次のように書き換えてみるとわかりやすい
function! hello#hello(name)
python << endpython
hello(a:name)
endpython
endfuncion
また、pydo
ものもある。pydo <body>
と書くと、
def _vim_pydo(line, linenr):
<body>
という関数が作られ、選択範囲に対して1行ごとに、lineに行の内容が、linenrに行番号が渡されて呼び出される。値を返すとその値で行が置換されるが、関数なので当然returnと書かなければいけない。なのでちょっと長くなってダサい。こういうのはrubyのほうが綺麗に書けそう。
例えば、下のコードを実行すれば選択範囲の行頭に行番号が挿入される
pydo return str(linenr) + line
実装
ディレクトリ構成
plugin/
hello.vim
autoload/
hello.vim
src/
hello.py
hello.py
vimとか気にせずに、関数を作る。
1/25 追記:
名前が衝突する可能性について@thnkaさんにご指摘いただきました。グローバル空間を汚染するため、プレフィックスをつけたりクラスの中に入れたりする必要があります。
def hello_hello(name):
print('Hello {0}'.format(name))
autoload/hello.vim
ここが肝
やることは3つ。
- 作ったpythonスクリプトを読み込む。
- pythonないでvimをインポートする
- pluginから呼び出される関数を作り、関数内でpythonの関数を叩く
まず、作ったpythonスクリプトを読み込む。スクリプトのパスの取得方法に注意。
pyfile <sfile>:h:h/src/hello.py
次に、vimをインポートする。これをやらないと値のやり取りができない。
python import vim
最後に、plugin側から呼び出される関数を作り、関数内でpythonの関数を叩く。pythonと欠いた行は既にpythonの世界なので、vimモジュールを通して引数を渡す。
function! hello#hello(name)
python hello(vim.eval('a:name'))
endfunction
plugin/hello.vim
ここは普通のプラグインとなにも変わらず。autoloadに記述した関数と、コマンドの橋渡し
command! -nargs=1 MyNameIs call hello#hello(<f-args>)
完成形
def hello_hello(name):
print('Hello {0}'.format(name))
let s:save_cpo = &cpo
set cpo&vim
pyfile <sfile>:h:h/src/hello.py
python import vim
function! hello#hello(name)
python hello_hello(vim.eval('a:name'))
endfunction
let &cpo = s:save_cpo
unlet s:save_cpo
if exists("g:loaded_hello")
finish
endif
let g:loaded_hello = 1
let s:save_cpo = &cpo
set cpo&vim
command! -nargs=1 MyNameIs call hello#hello(<f-args>)
let &cpo = s:save_cpo
unlet s:save_cpo
参考
その他
実際に作ったのはhttpstatus.vimというプラグイン。VimからHTTPステータスコードがどんな意味だったか確認できる。テキストはPythonのBaseHTTPServer.BaseHTTPRequestHandler.responses
を使用している。
意気揚々と作ってしまったが、どうやらmattnさんが既に作っていたらしい。さらに、今回作ったものよりも高機能っぽい(ステータスコードだけじゃなくてメッセージでも調べられる)けど、どうせ私はステータスコードからしか調べないので十分なのでした。