vim-users.jp

Hack #132: Pythonインタフェースを使う(1)

Posted at 2010/03/17
このエントリーをはてなブックマークに追加

VimにはRubyやPython、Perl、SchemeなどのVimScript以外の言語のインタフェースがあります.これらの言語にはVimScriptにはない強力なライブラリを持っているものも多く、ネットワーク通信やファイルシステムの操作など、VimScript単体では難しい処理を行う際に便利です。今回はその中でPythonインタフェースの使い方について簡単に解説したいと思います。

そもそもPythonインタフェースを使うには?

Vimを --enable-pythoninterp 付きでconfigureしてビルドする!だけではあんまりなので、それ以外の方法を一部紹介します。

  • Mac
    • MacVim-KaoriYaにはデフォルトでPythonインタフェースが組み込まれているので、これを使うのが一番簡単です。
    • MacPortsで+python(または+python26)でインストールするのでもOKです。
  • Windows
    • KaoriYa VimPythonのDLLが存在するとPythonインタフェースが使えます。詳しくは:help python-dynamicを参照してください。
  • Linuxなど
    • UbuntuとDebianではvim-pythonパッケージでPythonインタフェースを有効にできるそうです
    • 残念ながら筆者はその他の環境で簡単にPythonインタフェースを使う方法を知りません。Linuxの各ディストリビューションに含まれているVimの状況などご存知の方は、コメント欄などでお知らせいただけると幸いです。

Pythonインタフェースが使えるか確認する

以下のコマンドで1が返ればOKです。

:echo has('python')

VimScriptからPythonを呼ぶ

:pythonコマンドを使います。

" VimScript
:python print "hoge"; print "hoge"

:python <<EOM
print "fuga"
print "fuga"
EOM

といった感じで,そのまま引数にPythonスクリプトを渡すか,複数行のスクリプトを渡すときは2番目のようにヒアドキュメント風にすることでPythonを実行できます。Pythonはインデントが重要なので2番目の呼び方を用いるときには注意が必要です。ちなみに、print文などPythonからの標準出力は:echomsgで出力するのと同じ扱いで、エラーは:echoerrしたのと同じ扱いになります。また、input()やraw_input()などの標準入力からのインプットはサポートされていません。

" VimScript
function Hoge()
    python <<EOM
    print "hoge"
    EOM
enfcuntion " エラー!

上記のようについつい書きたくなりますが、これはエラーになります。Pythonは必ずインデントなしの状態で書き始めないといけませんし、EOMの前に空白があるとPythonブロックの終了と見なされません。正しくは、以下のように書きます。

" VimScript
function Fuga()
    python <<EOM
print "fuga"
EOM
endfunction

そのほか、Pythonの書かれたファイルを読み込んで実行する:pyfileコマンドもあります。

PythonからVimScriptを呼ぶ

Pythonからはvimモジュールを利用することで、VimScriptを呼ぶことができます。importしないと使えないので注意してください。

# Python
import vim

vimモジュールにはvim.command()とvim.eval()の二つの関数が用意されています。vim.command()は引数に渡されたVimのコマンドを実行します。例えば以下のように使います。

# Python
vim.command('echo "hoge"')
vim.command('let val = "fuga"')

vim.eval()は与えられたVimの式を評価して返します。配列もちゃんとPythonの配列にして返してくれます。ただし、数値であっても全て文字列として返されるので注意してください。例えば以下のような感じになります。

# Python
color_name = vim.eval('g:color_name')
bufnum, lnum, col, off = vim.eval('getpos(".")') # 例えば、("0", "3", "10", "0")のようになる

また,Vimのバッファを表すオブジェクトとしてvim.bufferが提供されています。vim.buffersが全てのバッファが入った配列で、vim.current.bufferが現在表示しているバッファになります。:help pythonにもありますが、おおよその使い方は以下の通りです。

# Python
import vim
b = vim.current.buffer # 現在のバッファ
print b.name           # バッファ名
print b.number         # bufnr()で得られる値,vim.buffersのインデックスはbufnr()とは異なるので注意
b[0] = "hoge"          # 1行目を変更する
b[:] = None            # バッファを空にする
b = vim.buffers[1]     # 1番目のバッファ(bufnr()が1というわけではない)
del b[:]               # これもバッファを空にする
b[0:0] = ["fuga"]      # 一番上に行を挿入
del b[2]               # 3行目を削除
b.append("hoge")       # 末尾に行を追加
print len(b)           # バッファの行数を表示

vim.buffersで全てのバッファを得られることからわかるように、VimScript単体では難しい表示していない(アクティブでない)バッファの内容を取得したり、その中身を編集したりすることができます。また、vim.bufferを用いた編集もVimの'modifiable'などの影響を受けるので、set nomodifiableされたバッファに書き込もうとすると、vim.error例外が発生し編集できません。

その他vim.window,vim.rangeなどが提供されていますが、今回はこれらの詳細は省略します。詳しくは:help pythonを参照してください。

今回は主に:help pythonにも書かれている内容について説明しましたが、次の「Pythonインタフェースを使う」では、もう少し突っ込んだ内容について説明したいと思います。

tsukkee

もどる
blog comments powered by Disqus