13. 対話入力編集とヒストリ置換
******************************

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

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


13.1. 行編集
============

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


13.2. ヒストリ置換
==================

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


13.3. キー割り当て
==================

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

   key-name: function-name

もしくは

   "string": function-name

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

   set option-name value

例えば:

   # I prefer vi-style editing:
   set editing-mode vi

   # Edit using a single line:
   set horizontal-scroll-mode On

   # Rebind some keys:
   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" を使って
インデントするのに慣れている場合、この設定を行うとインデントされた継続
行を入力しにくくなります。)

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

   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:  "export PYTHONSTARTUP=~/.pystartup" in bash.

   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


13.4. インタラクティブインタプタの代替
======================================

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

より優れたインタラクティブインタプリタの代替の一つに IPython がありま
す。このインタプリタは、様々なところで使われていて、タブ補完、オブジェ
クト探索や先進的な履歴管理といった機能を持っています。他のアプリケーシ
ョンにカスタマイズされたり、組込まれこともあります。別の優れたインタラ
クティブ環境としては bpython があります。

-[ 注記 ]-

[1] Python は、対話インタプリタを開始する時に "PYTHONSTARTUP" 環境
    変数 が指定するファイルの内容を実行します。非対話モードでも Pytohn
    をカ スタマイズするには、 カスタマイズ用モジュール を参照してくだ
    さい。
