Contents

if_pyth - vimdoc

Home
*if_pyth.txt*   For Vim バージョン 7.3.  Last change: 2012 Feb 04


                  VIM REFERENCE MANUAL    by Paul Moore


VimのPythonインターフェイス                             *python* *Python*

1. コマンド                     |python-commands|
2. vimモジュール                |python-vim|
3. バッファオブジェクト         |python-buffer|
4. レンジオブジェクト           |python-range|
5. ウィンドウオブジェクト       |python-window|
6. 動的ローディング             |python-dynamic|
7. Python 3                     |python3|

{Vi にはこれらのコマンドはない}

Python 2.x インターフェイスは Vim が |+python| 機能付きでコンパイルされたとき
のみ利用できます。
Python 3 インターフェイスは Vim が |+python3| 機能付きでコンパイルされたときの
み利用できます。

==============================================================================
1. コマンド                                             *python-commands*

                                                        *:python* *:py*
:[range]py[thon] {stmt}
                        Pythonのステートメント{stmt}を実行します。

:[range]py[thon] << {endmarker}
{script}
{endmarker}
                        Pythonのスクリプト{script}を実行します。
                        Note: このコマンドはPython用の機能を含めてコンパイルさ
                        れていないときは機能しません。エラーを抑制するには
                        |script-here|を参照してください。

{endmarker}の前に空白を置かないでください。"<<"の後に{endmarker}省略した時は
|:append||:insert|のように'.'が使われます。
この形の|:python|コマンドはVimスクリプトにPythonコードを埋め込むのに特に便利で
す。

例:
        function! IcecreamInitialize()
        python << EOF
        class StrawberryIcecreame:
                def __call__(self):
                        print 'EAT ME'
        EOF
        endfunction

Note: Pythonはインデントに関して非常に繊細です。"class"の行と"EOF"の行はまった
くインデントしないでください。

                                                        *:pyfile* *:pyf*
:[range]pyf[ile] {file}
                        {file}内のPythonスクリプトを実行します。引数はそのまま
                        一つのファイル名として使われます。{Vi にはない}

これら2つのコマンドは、本質的には同じことを行います - つまり、Pythonのコード
を、与えられた"現在の範囲"|python-range|に対して実行します。

:pythonの場合には、実行されるコードはコマンドラインで与えられたものです。
:pyfileの場合には、実行されるコードは与えられたファイルの中身です。

Pythonのコマンドは|sandbox|の中では使えません。

引数を渡すためには明示的に sys.argv[] を使って設定してください。例:

        :python import sys
        :python sys.argv = ["foo", "bar"]
        :pyfile myscript.py

いくつか例を挙げます                                    *python-examples* 

        :python from vim import *
        :python from string import upper
        :python current.line = upper(current.line)
        :python print "Hello"
        :python str = current.buffer[42]

(変更 - importsなど - は、Pythonインタープリタと同様に、次のコマンドに引き
継がれます。)

==============================================================================
2. vimモジュール                                        *python-vim*

Pythonコードは、vimモジュールを通して、vimに自由にアクセスすることができます
(ただひとつの例外を除いて - 以下の|python-output|を参照)。vimモジュールは2つ
のメソッド、3つの定数、そして1つのエラーオブジェクトを実装しています。これを
使うにはvimモジュールをimportする必要があります。
        :python import vim

概要
        :py print "Hello"               # メッセージを表示
        :py vim.command(cmd)            # exコマンドを実行
        :py w = vim.windows[n]          # ウィンドウ"n"を得る
        :py cw = vim.current.window     # 現在のウィンドウを得る
        :py b = vim.buffers[n]          # バッファ"n"を得る
        :py cb = vim.current.buffer     # 現在のバッファを得る
        :py w.height = lines            # ウィンドウの高さを設定する
        :py w.cursor = (row, col)       # ウィンドウのカーソル位置を設定する
        :py pos = w.cursor              # (row, col)の組を得る
        :py name = b.name               # バッファのファイル名を得る
        :py line = b[n]                 # バッファから1行を得る
        :py lines = b[n:m]              # バッファから一連の行を得る
        :py num = len(b)                # 行数を得る
        :py b[n] = str                  # バッファ内の1行を設定する
        :py b[n:m] = [str1, str2, str3] # 1度に数行を設定する
        :py del b[n]                    # 1行を削除する
        :py del b[n:m]                  # 数行を削除する


"vim"モジュールのメソッド

vim.command(str)                                        *python-command*
        vim(exモード)のコマンドstrを実行します。戻り値はありません。
        例:
            :py vim.command("set tw=72")
            :py vim.command("%s/aaa/bbb/g")
        ノーマルモードのコマンドを実行するには、次の定義が使われます:
                def normal(str):
                        vim.command("normal "+str)
                # '...'は、2重引用符を含む文字列の境界に使われることに注意。
                normal('"a2dd"aP')
                                                        *E659*
        ":python"コマンドは、Python 2.2かそれより古いものでは再帰的に使えませ
        ん。Python 2.3 かそれより新しものを使ってください。
            :py vim.command("python print 'Hello again Python'")

vim.eval(str)                                           *python-eval*
        vim内の式評価を使って、式を評価します(|expression|を参照)。戻り値は、
        次の通り:
        - Vimの式を評価した結果が文字列か数値ならば文字列
        - Vimの式を評価した結果がリストならばリスト
        - Vimの式を評価した結果がVimの辞書ならば辞書
        辞書とリストは再帰的に展開されます。
        例:
            :py text_width = vim.eval("&tw")
            :py str = vim.eval("12+12")         # 結果は文字列であることに注意!
                                                # 数に変換するには、
                                                # string.atoi()を使うこと。

            :py tagList = vim.eval('taglist("eval_expr")')
        最後のコマンドはPython辞書のPythonリストを返します。例:
        [{'cmd': '/^eval_expr(arg, nextcmd)$/', 'static': 0, 'name':
        'eval_expr', 'kind': 'f', 'filename': './src/eval.c'}]

"vim"モジュールのエラーオブジェクト

vim.error                                               *python-error*
        vimのエラーに遭遇したとき、Pythonは型vim.errorの例外を発生させます。
        例:
                try:
                        vim.command("put a")
                except vim.error:
                        # レジスタaが空

モジュール"vim"の定数
        モジュール"vim"の定数は、実際には定数ではありません。よって代入し直す
        ことができます。しかし、それは馬鹿げたことです。その変数が参照している
        vimオブジェクトへのアクセスができなくなってしまうからです。

vim.buffers                                             *python-buffers*
        一連のvimバッファへのアクセスを提供するシーケンスオブジェクト。
        次の操作がサポートされています:
            :py b = vim.buffers[i]      # インデックス化する (読取り専用)
            :py b in vim.buffers        # メンバかどうか調べる
            :py n = len(vim.buffers)    # 要素の個数
            :py for b in vim.buffers:   # シーケンシャルアクセス

vim.windows                                             *python-windows*
        一連のvimウィンドウへのアクセスを提供するシーケンスオブジェクト。
        このオブジェクトは次の操作をサポートしています:
            :py w = vim.windows[i]      # インデックス化する (読取り専用)
            :py w in vim.windows        # メンバかどうか調べる
            :py n = len(vim.windows)    # 要素の個数
            :py for w in vim.windows:   # シーケンシャルアクセス

vim.current                                             *python-current*
        vim内で使える様々な"現在の"オブジェクトへの、(特定の属性を通した)
        アクセスを提供するオブジェクト:
                vim.current.line        現在の行 (RW)                   String
                vim.current.buffer      現在のバッファ (RO)             Buffer
                vim.current.window      現在のウィンドウ (RO)           Window
                vim.current.range       現在の行の範囲 (RO)             Range

        最後のものに関しては、若干の説明が必要でしょう。:python、:pyfileコマン
        ドで、範囲が指定された場合、この行の範囲は、"現在の範囲"として扱われま
        す。範囲はバッファに少し似ていますが、全てのアクセスは行のサブセットに
        制限されます。詳細は|python-range|を参照してください。


Pythonからの出力                                        *python-output*
        Pythonコードからの全ての出力は、Vimのメッセージエリアに表示されます。
        標準出力はインフォメーションメッセージとして、エラー出力はエラーメッ
        セージとして表示されます。

        実装のレベルでいうと、sys.stdout(printステートメントによる出力も含む)
        に向けられる全ての出力が、インフォメーションメッセージとしてvimに表示
        され、sys.stderr(エラートレースバックを含む)に向けられる全ての出力が、
        エラーメッセージとしてvimに表示されています。

                                                        *python-input*
        入力(sys.stdinを通した入力、input()、raw_input()を含む)はサポートされ
        ず、プログラムをクラッシュさせる可能性があります。これはたぶん修正され
        るべき問題です。

==============================================================================
3. バッファオブジェクト                                 *python-buffer*

バッファオブジェクトは、vimのバッファを表します。バッファオブジェクトを取得す
るはいくつかの方法があります:
        - vim.current.bufferを介して (|python-current|)
        - vim.buffersのインデックス化から (|python-buffers|)
        - ウィンドウの"buffer"属性から (|python-window|)

バッファオブジェクトは二つの読み取り専用属性を持っています。name はバッファの
フルファイル名です。number はバッファ番号です。バッファオブジェクトは 3 つのメ
ソッドを持っています (append、mark、range。以下参照)。

バッファオブジェクトは、シークエンスオブジェクトとして扱うこともできます。この
文脈では、バッファオブジェクトは文字列のリスト(そう、これはmutableです)のよう
に振舞います。各要素はバッファの行です。有用なシークエンス操作の全て、つまり、
インデックス操作、インデックスによる代入、スライシング、スライスへの代入が期待
通りに機能します。バッファのインデックス操作(スライシング)の結果は、文字列(文
字列のリスト)であることを注意しておきます。これはひとつの例外的な結果をもたら
します - b[:]はbとは異なるのです。特に、"b[:] = None"はバッファの全てを削除す
るが、"b = None"は変数bを更新するだけで、バッファには何の影響も与えません。

バッファのインデックスは、Pythonでは普通はゼロから始まります。これは、1から始
まるvimの行番号と異なります。これは、特にvimの行番号を使うmarks(以下を参照)を
扱う際に問題となります。

バッファオブジェクトのメソッドは次の通りです:
        b.append(str)   バッファに行を追加
        b.append(str, nr)  バッファの "nr" 行目の下に行を追加。
        b.append(list)  バッファに一連の行を追加
                        appendメソッドに文字列のリストを与えるオプションは、
                        Python組込みのリストオブジェクトの等価なメソッド
                        とは違うことに注意してください
        b.append(list, nr)  バッファの "nr" 行目の下に一連の行を追加
        b.mark(name)    名前付きマークの位置を示す(row,col)の組を返す
                        (これは[]"<> marksでも得られる)
        b.range(s,e)    与えられたバッファのs行目からe行目(s行とe行も含む
                        |inclusive|)を示すレンジオブジェクト(|python-range|
                        参照)を返す

Note 行を追加するときは、その行に改行文字'\n'が含まれてはなりません。末尾の
'\n'は許されますが、無視されます。そのため次のようなことができます:
        :py b.append(f.readlines())

例 (bは現在のバッファに割り当てられているとします)
        :py print b.name                # バッファのファイル名を出力
        :py b[0] = "hello!!!"           # 先頭の行を置換
        :py b[:] = None                 # 全てのバッファを削除
        :py del b[:]                    # 全てのバッファを削除
        :py b[0:0] = "add a line"       # 先頭に行を追加
        :py del b[2]                    # 行を削除 (3番目)
        :py b.append("bottom")          # 最後に行を追加
        :py n = len(b)                  # 行数
        :py (row,col) = b.mark('a')     # 名前付きマーク
        :py r = b.range(1,5)            # バッファの部分範囲

==============================================================================
4. レンジオブジェクト                                   *python-range*

レンジオブジェクトは、vimバッファの一部分を表します。レンジオブジェクトを取得
するにはいくつかの方法があります:
        - vim.current.rangeを介して (|python-current|)
        - バッファのrange()メソッドから (|python-buffer|)

レンジオブジェクトの操作は、バッファオブジェクトのそれとほとんど同じです。
しかし、全ての操作は範囲内の行に制限されます(もちろん、行の範囲は部分の割当て、
行の削除、あるいはrange.append()メソッドによって変更できます)。

レンジオブジェクトの属性:
        r.start         選択範囲でのバッファ内の最初の行。
        r.end           選択範囲でのバッファ内の最後の行。

レンジオブジェクトのメソッド:
        r.append(str)   その範囲に行を追加する
        r.append(str, nr)  "nr" 行目の後に追加する
        r.append(list)  その範囲にリストで与えられた複数行を追加する。
                        これはPythonのリストオブジェクトに対する操作とは異な
                        ることに注意してください。
        r.append(list, nr)  "nr" 行目の後に追加する


バッファと違い、レンジは"name"属性を持たず、また、mark()、range()メソッドも持
ちません。そのかわり、レンジは範囲の最後に行を付け加えるappend()メソッドを持ち
ます。

==============================================================================
5. ウィンドウオブジェクト                               *python-window*

ウィンドウオブジェクトは、vimのウィンドウを表現します。ウィンドウオブジェクト
を取得するには、いくつかの方法があります:
        - vim.current.windowを介して (|python-current|)
        - vim.windowsのインデックス化から (|python-windows|)

ウィンドウオブジェクトは、それらの属性を通してのみ操作できます。これらはメソッ
ドを持たず、シークエンスも他のインターフェイスもありません。

ウィンドウの属性:
        buffer (読取り専用)     そのウィンドウに表示されているバッファ
        cursor (読み書き)       そのウィンドウの現在のカーソルの位置
                                これは(row,col)の組で表される
        height (読み書き)       ウィンドウの高さ、行の数で
        width (読み書き)        ウインドウの幅、列の数で
heightはスクリーンが水平方向に分割されているときのみ書き込み可能です。
widthはスクリーンが垂直方向に分割されているときのみ書き込み可能です。

==============================================================================
6. 動的ローディング                                     *python-dynamic*

MS-WindowsではPythonライブラリを動的に読み込むことが可能である。これを行うと
|:version|の出力に|+python/dyn|が含まれるようになる。

この場合、Vimは必要なときだけPythonのDLLファイルを検索する。Pythonインターフェ
イスを使わないときはDLLを必要としないので、DLLなしでVimを使うことができる。

Pythonインターフェイスを使うにはPythonのDLLが検索パス内に存在しなければならな
い。コンソールウィンドウで"path"とタイプすると、どのディレクトリが検索パスとな
るか表示することができる。

DLLの名前はVimをコンパイルした時のPythonのバージョンに一致しなければならない。
現在その名前は"python24.dll"である。これはPython2.4用である。これを確かめるに
は、"gvim.exe"を開き、"python\d*.dll\c"を検索する。

==============================================================================
7. Python 3                                             *python3*

                                                        *:py3* *:python3*
|:py3| コマンドと |:python3| コマンドは |:python| と同様に機能します。
                                                        *:py3file*
|:py3file| コマンドは |:pyfile| と同様に機能します。

Vim のビルドは 4 種類あります (:version の出力):
1. Python サポートなし      (-python, -python3)
2. Python 2 サポートのみ    (+python or +python/dyn, -python3)
3. Python 3 サポートのみ    (-python, +python3 or +python3/dyn)
4. Python 2 と 3 のサポート (+python/dyn, +python3/dyn)

特殊ケース 4 に付いてもう少し詳細に説明します:

Python 2 と Python 3 をサポートするにはそれらを動的ロードする必要があります。

Linux/Unix システムで動的ロード時にグローバルシンボルをインポートすると、 2 番
目にロードした Python が使われたときにクラッシュが発生します。そのため、グロー
バルシンボルをロードして一つの Python バージョンだけを使うか、グローバルシンボ
ルをロードしないかのどちらかしかありません。後者は特定のライブラリ (シンボルが
Vim から提供されていることを期待しているライブラリ) において Python の
"import" が失敗するようになります。
                                                        *E836* *E837*
Vim のコンフィグスクリプトはすべてのライブラリがある標準の Python ライブラリ
(termios) に基づいていると仮定します。このライブラリを両方の Python バージョン
でインポートできるなら、両方のバージョンを Vim の中で同時に利用できます。そう
でない場合は、どちらか最初に使われたもののみが利用可能になります。もう一方を使
おうとすると E836 か E837 のエラーメッセージが表示されるでしょう。

Vim の動作はコンフィグを実行したシステムに依存します。Python の両方のバージョ
ンが --enable-shared 付きでビルドされているなら、両方のバージョンを同時に使用
できます。ただし libPython にリンクしていないサードパーティライブラリに対して
はまだ問題は解決しません。

これらの問題に対する対処療法:
1. 問題のライブラリを libpython.so にリンクする形で再コンパイルする。
2. Vim を再コンパイルして一つの Python バージョンのみ有効にする。
3. コンフィグ実行後に auto/config.h の PY_NO_RTLD_GLOBAL の定義を削除する。こ
   れは Vim がクラッシュするようになるでしょう。

                                                        *has-python*
どのバージョンの Python が利用可能になっているかは次のコマンドで確認できます:

        if has('python')
          echo 'there is Python 2.x'
        elseif has('python3')
          echo 'there is Python 3.x'
        endif

Note: Python の 2 と 3 の両方が利用可能で、Python が動的ロードされるようになっ
ている場合、この has() 呼び出しによってそれらがロードされます。もし、同時に
ロードできるのがどちらか一方だけだった場合、Python の 2 と 3 のどちらが利用で
きるか調べるだけで、もう一方は利用できなくなります。

==============================================================================
 vim:tw=78:ts=8:ft=help:norl: