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

vimscriptからpythonするのを補助するpycallを作る

$
0
0

ええと、 vimpythonを書く記事ではありません。

vimscriptpy3もしくは 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}")

変数名を固定すれば vimpythonでやりとりできそうではある。

vim.bindevalnvimには無かったのでスルー。

python関数を呼び出すラッパー関数を作る

Pythonでvim pluginを書く

を見て関数を経由することで引数名を固定する方法を知る。

# 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


Viewing all articles
Browse latest Browse all 5608

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>