#
A. 対話入力編集とヒストリ置換

あるバージョンの Python インタプリタでは、Korn シェルや GNU Bash シェルに見られる機能に似た、現在の入力行に対する編集機能や ヒストリ置換機能をサポートしています。 この機能は GNU Readline ライブラリを使って実装されています。 このライブラリは Emacs スタイルと vi スタイルの編集をサポート しています。ライブラリには独自のドキュメントがあり、ここでそれを 繰り返すつもりはありません; とはいえ、基本について簡単に解説する ことにします。ここで述べる対話的な編集とヒストリについては、 Unix 版と CygWin 版のインタプリタでオプションとして利用 することができます。

この章では、Mark Hammond の PythonWin パッケージや、 Python とともに配布される Tk ベースの環境である IDLE にある 編集機能については解説しません。 NT 上の DOS ボックスやその他の DOS および Windows 類で働く コマンド行ヒストリ呼出しもまた別のものです。

#
1 行編集

入力行の編集がサポートされている場合、インタプリタが一次または二次 プロンプトを出力している際にはいつでも有効になっています。現在の行は、 慣例的な Emacs 制御文字を使って編集することができます。 そのうち最も重要なものとして、以下のようなキーがあります: `C-A` (Control-A) はカーソルを行の先頭へ移動させます。 `C-E` は末尾へ移動させます。 `C-B` は逆方向へ一つ移動させます。 `C-F` は順方向へ移動させます。 Backspace は逆方向に向かって文字を消します。 `C-D` は順方向に向かって消します。 `C-K` は順方向に向かって行の残りを kill し (消し) ます 、 `C-Y` は最後に kill された文字列を再び yank し (取り出し) ます。 `C-underscore` 最後の変更を元に戻します; これは、繰り返して どんどんさかのぼることができます。

#
2 ヒストリ置換

ヒストリ置換は次のように働きます。入力された行のうち、空行でない 実行された行はすべてヒストリバッファに保存されます。そして、プロンプト が呈示されるときには、ヒストリバッファの最も下の新たな行に移動 します。`C-P` はヒストリバッファの中を一行だけ上に移動し (戻し) ます。`C-N` は 1 行だけ下に移動します。ヒストリバッファの どの行も編集することができます。行が編集されると、それを示すために プロンプトの前にアスタリスクが表示されます 7。 `Return` キーを押すと現在行がインタプリタへ渡されます。 `C-R` はインクリメンタルな逆方向サーチ (reverse search) を開始し、 `C-S` は順方向サーチ (forward search) を開始します。

#
3 キー割り当て

Readline ライブラリのキー割り当て (key binding) やその他のパラメタ は、~/.inputrc という初期化ファイル8にコマンドを置くことでカスタマイズできます。 キー割り当ての形式は

    key-name: function-name

または

    "string": function-name

で、オプションの設定方法は

    set option-name value

です。例えば、以下のように設定します:

    # vi スタイルの編集を選択する:
    set editing-mode vi

    # 一行だけを使って編集する:
    set horizontal-scroll-mode On

    # いくつかのキーを再束縛する:
    Meta-h: backward-kill-word
    "\C-u": universal-argument
    "\C-x\C-r": re-read-init-file

Python では、`Tab` に対するデフォルトの割り当ては TAB の挿入です。 Readline のデフォルトであるファイル名補完関数ではないので注意して ください。 もし、どうしても Readline のデフォルトを割り当てたいのなら、 ~/.inputrc に

    Tab: complete

を入れれば設定を上書きすることができます。 (もちろん、`Tab` を使って補完を行うのに慣れている場合、この設定を行うと インデントされた継続行を入力しにくくなります。)

変数名とモジュール名の自動的な補完がオプションとして利用できます。 補完をインタプリタの対話モードで有効にするには、 以下の設定をスタートアップファイルに追加します: 9

    import rlcompleter, readline
    readline.parse_and_bind('tab: complete')

この設定は、`Tab` キーを補完関数に束縛します。従って、 `Tab` キーを二回たたくと補完候補が示されます; 補完機能は Python の文の名前、現在のローカル変数、および利用可能なモジュール名を 検索します。`string.a` のようなドットで区切られた式については、 最後の "`.`" までの式を評価し、結果として得られたオブジェクトの 属性から補完候補を示します。 `__getattr__()` メソッドを持ったオブジェクトが式に含まれている 場合、`__getattr__()` がアプリケーション定義のコードを実行する かもしれないので注意してください。

より良くできたスタートアップファイルは以下例のようになります。 この例では、作成した名前が不要になると削除されるので気をつけてください; これは、スタートアップファイルが対話コマンドと同じ名前空間で実行され ているので、不要な名前を除去して対話環境に副作用を生まないように するためです。import されたモジュールのうち、`os` のような インタプリタのほとんどのセッションで必要なものについては、残しておくと 便利に思うかもしれません。

    # Add auto-completion and a stored history file of commands to your Python
    # interactive interpreter. Requires Python 2.0+, readline. Autocomplete is
    # bound to the Esc key by default (you can change it - see readline docs).
    #
    # Store the file in ~/.pystartup, and set an environment variable to point
    # to it, e.g. "export PYTHONSTARTUP=/max/home/itamar/.pystartup" in bash.
    #
    # Note that PYTHONSTARTUP does *not* expand "~", so you have to put in the
    # full path to your home directory.

    import atexit
    import os
    import readline
    import rlcompleter

    historyPath = os.path.expanduser("~/.pyhistory")

    def save_history(historyPath=historyPath):
        import readline
        readline.write_history_file(historyPath)

    if os.path.exists(historyPath):
        readline.read_history_file(historyPath)

    atexit.register(save_history)
    del os, atexit, readline, rlcompleter, save_history, historyPath

#
4 解説

この機能は、初期の版のインタプリタに比べれば大きな進歩です; とはいえ、まだいくつかの要望が残されています: 例えば、 行を継続するときに正しいインデントが呈示されたら快適でしょう (パーサは 次の行でインデントトークンが必要かどうかを知っています)。 補完機構がインタプリタのシンボルテーブルを使ってもよいかもしれません。 かっこやクォートなどの対応をチェックする (あるいは指示する) コマンドも 有用でしょう。

#### Footnotes

... プロンプトの前にアスタリスクが表示されます 7
  訳注: これはデフォルト設定の Readline では現れません。 `set mark-modified-lines on` という行を ~/.inputrc または 環境変数 INPUTRC が指定するファイルに置くことによって 現れるようになります。
... という初期化ファイル 8
  訳注: このファイル名は 環境変数 INPUTRC がもしあればその指定が優先されます。
... 以下の設定をスタートアップファイルに追加します:9
  Python は、対話インタプリタを開始する時に PYTHONSTARTUP 環境変数が指定するファイルの内容を実行します。