-------------------------------------
README file for Ruby Readline-0.5.4
-------------------------------------

Ruby Realine モジュールとは，GNU Readline Libraryに頼らずに，Rubyプログラム自体に
よって，readline likeな行編集インターフェイスを実現するためのモジュールです．
ちょっとしたCUIのアプリケーションを開発したいが，Curses Library を使うほどではない
という場合，そうはいっても GNU Readline とそのカスタマイズでは実現が難しい，という
ような場合が，結構多いのではないでしょうか．このモジュールは，そうしたニーズに応え
るためのものです．

ついでに(というかこっちがメインですが)cshなどのディレクトリ名・ファイル名補完機能
を実装してみました．


利用条件について
----------------
未定．
Ruby本体のLisenceと同一の利用・配布条件とします．


ダウンロード
------------

最新版は
http://alex.mag.keio.ac.jp/~hiroya/ruby/rreadline/rreadline-current.tar.gz
からダウンロードできます．


動作環境
--------

 * Ruby-1.6.1 (これ以外のバージョンでの動作は未確認)

 * sttyコマンド，tputコマンドが，パス上に存在すること


機能
----

基本機能

 *GNU Readline互換的なAPI

  GNU Readlineモジュールを利用したRubyプログラムであれば，容易に移行が可能です．

 *柔軟で動的なカスタマイズ性

  それぞれの入力キー操作に対応した機能は，Rubyプログラムの関数として与えられており，
  入力キーと関数の対応関係はHash上で管理されているので，柔軟なカスタマイズが可能です．
  標準では，Emacs(tcsh)互換的なキー操作になっています．

 *連続的な複数のキーによる入力操作への対応

  連続的な複数のキーによる入力操作(Esc-ほげほげ など)を，単一のキーによる入力操作
  と内部的に同等のアクションとして処理することができます．

 *行編集機能

  基本的なカーソル移動に加えて，行ヒストリ，文字列のカット・コピー・ペースト，ヤン
  クバッファなど，通常必要であると思われるものについてはだいたい用意してあります．

その他

 *Ruby Shell

  この Ruby Realineモジュールを利用したサンプルプログラムとして，tcsh likeな
  ディレクトリ名・ファイル名の補完機能付きの簡易シェルを作ってみました．
  ただしこれは，シェルとしてコマンドを実行する機能は装備されていません．
  シェルの真似をするだけの，toy program です．

    cd $(rreadlineをインストールしたディレクトリ)
    sh rbsh

  で実行できます．pwd, cd, ls, cat などが装備されています．
  ディレクトリを移動しながら，補完機能の効き具合いを楽しんでください．


制限
----

 *動作環境について

  現段階では，この Ruby Readline モジュールを開発する作業の簡単化のために，
  cursesライブラリ等を利用せずに，sttyコマンド と tputコマンド と エスケープシーケ
  ンスを用いるという方針で作られています．このため，非UNIX環境上での動作は，サポー
  トされていません．
  とはいえ，こうした環境依存的部分は，class Terminal にカプセル化されているので，
  移植はそれほど難しくないと思われます．

 *vi互換モードについて

  現在のところ，viモードのキー配置は提供されていません．とはいえ，新しいkey bind表
  を作り足すだけで対応可能です．


キー操作
--------

現在のところ，コマンドライン上でのアクションとして，以下のような機能が用意されてい
ます．また標準では，これらは，Emacs互換的な配置で設定になっています．

C-@      -> set_mark_command
C-a      -> beginning_of_line
C-b      -> backward_char
C-c      -> tty_sigintr
C-d      -> delete_char_or_list_or_eof
C-e      -> end_of_line
C-f      -> forward_char
C-g      -> is_undefined
C-h      -> backward_delete_char
C-i      -> complete_word
C-j      -> newline
C-k      -> kill_line
C-l      -> clear_screen
C-m      -> newline
C-n      -> down_history
C-p      -> up_history
C-u      -> kill_whole_line
C-w      -> kill_region
C-x      -> sequence_read_in
C-y      -> yank
M-w      -> copy_region
delete   -> backward_delete_char
down     -> down_history
left     -> backward_char
right    -> forward_char
up       -> up_history


組み込みコマンド
----------------

組み込みコマンドとして，

	history: 過去の入力履歴を表示

	bindkey: キーバインドを表示

	resize: 端末画面の幅・高さの現在の値を再取得

	exit: 例外 ExitCommandLineEditor を発生

が装備されています．



大まかな使い方
--------------

  1. rreadlineパッケージをruby拡張ライブラリの検索パス上に置くか，
     rubyコマンドの -I オプションで指定してください．

  2. プログラムの中では，目的に応じて，
     それぞれ以下のようにして使用してください．
  
   (A) Readline的な使い方

       require "RReadline"
       r = RReadline.new

       def r.prompt
           _print("prompt> ")
       end

       line = r.readline()
       print line,"\n"

   (B) CommandLineEditor的な使い方

       require "CommandLineEditor"
       editor = CommandLineEditor.new

       def editor.prompt
           _print("prompt> ")
       end

       editor.executables={
          "print" => Proc.new{|argv| print argv.join(","),"\n" }
       }

       editor.loop


やや詳細な使い方
----------------

大まかな使い方(A)もしくは(B)の後に…

* 一行入力を読み込む

  editor.readline(addHistory = true)

  addHistoryがtrueの場合，ヒストリに読み込んだ文字列を追加します．


* プロンプト表示をするメソッドの設定

  def editor.prompt
     @term.set('blue').print(Dir.pwd).reset.print(">")
  end

  プロンプトを表示するためのコマンド．画面状態保持の都合上，
  class Terminalのオブジェクトのインスタンス変数 @term を利用して
  表示を行ってください．Kernel::print などを使うと，表示が崩れるので，
  基本的には使わないこと!


* 実行コマンドの表の設定

  editor.setExecutables({ "command_name1" -> Proc.new{|argv| .... },
                          "command_name2" -> Proc.new{|argv| .... },
                          "command_name3" -> "function_name" },
                            .....  })

  command_name:String -> executable:Proc または，
  command_name:String -> method_name:String という内容のHashで，
  実行コマンドを設定してください．
  valueとして指定されたブロックは，引数として入力された結果の行の値を取ります．
  valueとして指定された文字列は，現在のCommandLineEditorオブジェクトのメソッド
  名として解釈され，実行されます．


* 補完候補を返すメソッドの設定

  def editor.getCompletingList(line)
    if(line == "")
      return ['a','b','c']
    else
      return nil
    end
  end

  引数に入力中の文字列を取り，
  補完候補文字列の配列を返すような関数として設定してください．
  補完候補が無い場合にはnilを返してください．


* ヒストリを返す

  array = editor.getHistory

  返されるヒストリオブジェクトは，配列(Array)のサブクラスである
  class LimitedArrayWithCursor のインスタンス．


* 各種設定
  
 *キーバインドの設定．

  editor.setKeyBind({ 21 -> Proc.new{ .... },
                      "\e[A" -> "function_name" },
                      .....  })

  ※KeyBind.rbを参照のこと．
  command_name:String -> executable:Proc または，
  command_name:String -> method_name:String という内容のHashで，
  キーとアクションの関係を設定してください．
  valueとして指定されたブロックは，そのまま実行されます．
  valueとして指定された文字列は，現在のCommandLineEditorオブジェクトの
  メソッド名として解釈され，実行されます．

 *ヤンクバッファのサイズ設定
  editor.getEditingContext.getYankHistory.setMaxSize(n)
  初期値は10

 *行編集ヒストリのサイズ設定．
  editor.getEditingContext.getEditingHistory.setMaxSize(n)
  初期値は100
 

ファイル構成
------------

 ****  rreadline library ****

LimitedArray.rb
	LimitedArray:           サイズ制限付きの配列
	LimitedArrayWithCursor: サイズ制限付き，通し番号付きの配列

Terminal.rb
	現在の行表示の状態に関する情報を保持し，
	現在の行に新しい文字を加えたり，現在の行を消したり，
	現在の行でカーソルを巻き戻したりする．
	機種依存的操作をラッピング．

EditingLine.rb
	カーソルやマークの位置情報を使って，
	文字列に対する操作を行う．
	行編集の実質的操作に対応．

EditingContext.rb
	行ヒストリ，ヤンク，複合キー入力に関する情報の保持と操作．

CommandLineActions.rb
	それぞれのキーに対応した行編集，表示更新に関するアクション

RReadline.rb
        行操作を抽象し，入出力を統括．
        カスタマイズのためのプロトタイプを提供．
        通常のReadline的な使い方であれば，このクラスを利用．  

CommandLineEditor.rb
	RReadlineをサブクラス化し，行エディタとしてのループを提供．
        コマンドラインエディタ的な使い方であれば，このクラスを利用．

KeyBind.rb
	エディタ組み込みのデフォルトのキー操作(Emacs互換)

BuiltInExecutables.rb
	エディタ組み込み機能(history,resize,bindkey,exitなど)

  ****  rbsh application  ****

RubyShell.rb
	CommandLineEditorをサブクラス化し，
	unix shellとして利用できるように拡張する．

ShellExecutables.rb
	シェル組み込み機能(cd, pwd, ls, cat など)

ContextualExecutables.rb
	コンテキストごとに利用可能なコマンド名群が変わる場合の
	コマンドの機能(reserved for future implementation)

UnixDirectoryClient.rb
	Unixファイルシステムへのアクセスを抽象化．

------------
バグについて

バグを発見された方は，hiroya@netcom.mag.keio.ac.jpまでメールでお知らせ下さい．

----
久保 裕也[KUBO Hiroya] 慶應義塾大学 政策・メディア研究科
hiroya@netcom.mag.keio.ac.jp
