ええと、 vim
で python
を書く記事ではありません。
vimscript
の py3
もしくは py3file
で定義した python
関数を、 vimscript
から楽に呼び出せるようにする記事です。
作成中
https://github.com/ousttrue/vim-pycall
vimscript の py3 コマンド
https://vim-jp.org/vimdoc-ja/if_pyth.html
例
:python print(sys.version)
短い python
文を投げっぱなしにして、副作用は python
側でがんばれーという感じですね。引数を渡すことも、結果をもらうこともできなくなくないか。
pydo
はわいの目的には合わないのでスルー。
引数を渡すためには明示的に sys.argv[] を使って設定してください。例:
:python sys.argv =["foo","bar"]:pyfile myscript.py
・・・python側に最初から書いておけばいいのでは・・・
既存のコマンドラインのpythonスクリプトを無変更で呼び出すことを想定している?
python 側で vim モジュールを使うのだ
importvim
# pythonにvim変数を渡すfoo=vim.eval("g:foo")
# pythonからvim変数を変えるvalue=1vim.command(f"let g:ret = {value}")
変数名を固定すれば vim
と python
でやりとりできそうではある。
vim.bindeval
は nvim
には無かったのでスルー。
python関数を呼び出すラッパー関数を作る
を見て関数を経由することで引数名を固定する方法を知る。
# py3 か py3file で定義されたことにするdefhello(name):print('Hello {0}'.format(name))
function! pycall_hello(name)" python定義済みの関数呼び出しpy3 hello(vim.eval('a:name'))endfunction
a:name
であって g:name
でないのが素敵。なるほど。
返り値の名前を python 関数の引数に追加しよう
# python側でprintするのをやめて let で vim側に値を渡すdefhello(name,ret_name):vim.command(f"let {ret_name} = '{name}'")
function! pycall_hello(name)" python定義済みの関数呼び出しpy3 hello(vim.eval('a:name','l:ret'))if exists('l:ret')returnl:retendifendfunction
返り値も同様に名前を固定。g:ret
でなく l:ret
にできたので、vimscript
のグローバル変数が python
関数毎に必要になるということは無くなった。
任意のpython関数を呼び出せる汎用の呼び出し関数にする
python関数に2つの拡張が必要
- 関数名を受ける引数の追加
- vim関数の可変長引数をpythonに渡す
pythonの関数名を受けて間接的に関数を呼び出す py_dispatcher
を作った。
defpy_dispatch(name,ret_name,args):'''
name: python関数名
ret_name: 返り値を格納するvim変数名
args: 引数
'''# dispatch functionvalue=globals()[name](*args)ifvalue:# return to vim by letvalue=to_vim(value)command=f'let {ret_name} = {value}'# ここで ret_name に値をセットすることでvimに値を返すtry:vim.command(command)exceptvim.errorase:print('error',command)print('error',e)
function! PyCall(name,...)py3 py_dispatch(vim.eval('a:name'),'l:ret',vim.eval('a:000'))if exists('l:ret')returnl:retendifendfunction
globalスコープの任意のpython関数を呼び出せるようになった。
使い方
# 他のところで定義defhello2(hello1,hello2):returnf'hello {hello1} and {hello2}!'
hello
関数を探して、引数を渡して呼び出し、返り値を echo
する。:echo PycCall('hello', 'hoge', 'fuga')
使ってみる
ToDo