Quantcast
Channel: Vimタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 5608

Pythonでvim pluginを書く

$
0
0

やりたいこと

  • vimのプラグイン作りたい

  • でもvimscriptわからん!!

  • Pythonで書きたい!!!!

つくるもの

  • MyNameIs <name>と入力すると、Hello <name>と表示される

  • 実装はpythonに逃がして、vimscriptはpythonラッパーのような形で使う

VimScriptでのPython

よく使うのは、pythonpyfile

pythonとpyfileは本質的には同じで、ソースが直書きされているかファイルに分離されているかの違い。たとえば、次の2つのコードは同じ

python:

pythonprint('Hello')

pyfile

pyfile hello.py
hello.py
print('Hello')

pythonと書いたらその行は既にPythonの世界であることに注意する。次のように書いて随分と悩んだ。

function! hello#hello(name)pythonhello(a:name)
endfuncion

これが間違いであることは、次のように書き換えてみるとわかりやすい

function! hello#hello(name)python<< endpytohnhello(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とか気にせずに、関数を作る

src/hello.py
defhello(name):print('Hello {0}'.format(name))

autoload/hello.vim

ここが肝

やることは3つ。

  1. 作ったpythonスクリプトを読み込む。
  2. pythonないでvimをインポートする
  3. pluginから呼び出される関数を作り、関数内でpythonの関数を叩く

まず、作ったpythonスクリプトを読み込む。スクリプトのパスの取得方法に注意。

autoload/hello.vim
pyfile<sfile>:h:h/src/hello.py

次に、vimをインポートする。これをやらないと値のやり取りができない。

autoload/hello.vim
pythonimportvim

最後に、plugin側から呼び出される関数を作り、関数内でpythonの関数を叩く。pythonと欠いた行は既にpythonの世界なので、vimモジュールを通して引数を渡す。

autoload/hello.vim
function! hello#hello(name)pythonhello(vim.eval('a:name'))endfunction

plugin/hello.vim

ここは普通のプラグインとなにも変わらず。autoloadに記述した関数と、コマンドの橋渡し

plugin/hello.vim
command!-nargs=1 MyNameIs call hello#hello(<f-args>)

完成形

src/hello.py
defhello(name):print('Hello {0}'.format(name))
autoload/hello.vim
lets:save_cpo =&cposetcpo&vimpyfile<sfile>:h:h/httpstatus.pypythonimportvimfunction! hello#hello(name)pythonhello(vim.eval('a:name'))endfunctionlet&cpo=s:save_cpo
unlet s:save_cpo
plugin/hello.vim
if exists("g:loaded_hello")finishendifletg:loaded_hello =1lets:save_cpo =&cposetcpo&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さんが既に作っていたらしい。さらに、今回作ったものよりも高機能っぽい(ステータスコードだけじゃなくてメッセージでも調べられる)けど、どうせ私はステータスコードからしか調べないので十分なのでした。


Viewing all articles
Browse latest Browse all 5608

Trending Articles