view ChangeLog @ 62:5e44d3723fa9 v20080828-1

*** empty log message ***
author gongo
date Thu, 28 Aug 2008 18:23:27 +0900
parents 2dea55a8d0e4
children 0f7d2aab0e04
line wrap: on
line source

2008-08-28  Wataru MIYAGUNI  <gongo@cr.ie.u-ryukyu.ac.jp>

	* redit-client-sm.el (redit-client-process-filter)
	(redit-client-exec-insert-line, redit-client-exec-join)
	(redit-client-exec-put, redit-client-exec-delete-line): fix
	一斉大編集。
	今までは各関数内で (redit-get-*-from-pkt ) とかしてたんだけど
	それもなんかめんどくさくなったので、
	process-filter で予め cmd 〜 siz, text を取得し、
	各関数の引数に渡す感じにしました。

	redit-client-editor-id, redit-client-session-id なんかが
	バッファ毎に管理する必要がでて、普通の大域変数へのアクセスだけだと
	きつくなってきたのでこういう変更にしました。
	動いてるのは確認しました。

	* redit-client-sm.el (redit-client-after-change-function): fix
	前回(2008-08-27)の判定ルーチンを修正してみた。

	if (before-begin == after-end) {
	      // 行の削除による max-line の変化をチェック (max-line-diff)
	      // #1

	      // before-begin-line < line <= before-end-line まで delete

	      // prev-edit-line が 上の範囲に無ければ insert
	      // このとき、prev-edit-line が before-end-line より
	      // 大きければ (- prev-edit-line max-line-diff) の行に送る
	      // #2
	  } else {
	      // 行の追加による max-line の変化のチェック
	      // max-line に変化があれば line-feed-flg を t に
	      // #3

	      // before-begin <= line < after-end までを insert (flg)
	      // after-end を insert (改行コード無し)
	      // #4

	
	      // before-begin > previous-edited-line
	      // && after-end < previous-edited-line
	      // の時、previous-edited-line を insert
	      // このとき、prev-edit-line が before-begin-line より
	      // 大きければ (+ prev-edit-line max-line-diff) の行を送る	
	      // #2
	}

	- #1
	行の削除及び行の追加によって改行の追加/削除が行われると
	前回編集した行というのがずれてしまう可能性がある。
	before-change-function で送れば問題ないのだが、現在は
	after-change-function で判定しているのでそれはできない。
	つーことで、max-line に変化があれば、その差分を保持しておく(ずれた行)

	- #2
	#1 で求めた max-line を使って、prev-edit-line を編集後のずれた行を
	正確に参照するように max-line を prev-edit-line に加減する。
	加減する条件としては、編集によってずれる範囲にいる場合です。
	
	- #3, #4
	前回までは、「予め改行を送って領域確保」とかしてたんですが、
	要は行の始めの方から順に insert して、その文字列に改行コード入れれば
	問題ないなーと気づいたので。
	after-end までは flg によって改行コード入れるか入れないかを決め、
	after-end 自身は改行コードを入れないようにしている。
	こうすることで、ずれても大丈夫なようにしています(多分)

	=======

	こんな感じかなー。まだまだありそうです見落としバグ。
	
	* redit-client-sm.el (redit-client-after-change-function): fix
	add/remove-hook を、全てのバッファに対して引っ掛けるように
	したので(add-hook の 4つめの引数を省略(nil指定))、
	*Messages* とかその他いらんものの編集も拾ってしまうようになった。
	つーことで、最初に redit-sinfo-get-buf2sinfo で (buufer-name) して、
	編集されたバッファが Session Manager と繋がっているものかどうかを
	判定して、繋がっていれば以下の処理をするように変更。
	本当は
	
	  (if (nill sinfo) return)

	とかしたかったんだけど、emacs lisp ではできない。
	return ってのは Common Lisp のやつで、block から脱出するってやつ。
	Common Lisp だと、defun や defmacro は block 属性なんだけど
	emacs lisp では違うので、return を使っても抜けれない。
	・・・なんかあると思うんだけどなー

2008-08-27  Wataru MIYAGUNI  <gongo@cr.ie.u-ryukyu.ac.jp>

	* redit-client-sm.el (redit-debug-message): add
	message ラッパー。redit-debug-flag を見て message するか否か

	* thinking:
	テスト用SMGUIを使って、二つのSessionを立ち上げてみた。
            
	  / B (test.c)
  	A 
	  \ C (hoge.c)

	B と C がそれぞれ Session を立ち上げ、A が両方に join した。
	A が test.c バッファを開いている時に C が入力しても、
	ちゃんと A の hoge.c バッファ に書き込まれているのは確認した。
	と思ったけど、やっぱり少し問題があった。

	process-filter 内で、remove-hook している。
	これは、before/after-change-functions を呼ばれないように、
	つまりは受け取ったパケットの処理でバッファが編集されても
	その編集に対しては REPcommand を生成しないようにするためです。

	それはいいんだけど、問題が少しあります。

	1. A が B のバッファを開いている
	2. C が送信した
	3. A が受け取って remove-hook をかける (しかし、B のバッファのみ)
	4. REPcommand 解析により、C のバッファに書き込む
	5. C のバッファには remove-hook が掛かっていないため、
	   その編集が REPcommand 生成され、C に送られる
	6. C はポカーン

	ってことだ。add-hook,remove-hook の 4つめの引数に nil 以外を設定すると
	「この hook はカレントバッファにのみ適用されるYO」って意味なわけだ。
	だから上の問題が起きたわけ。
	じゃあどうすればいいかって、nil を設定(省略)すればいいわけ。
	しかしそうなると全てのバッファに対して hook がかかる。
	まあこれでいいんじゃないかってのもあるけどね。

	SessionManager に接続しているバッファ(上でいうhoge.cとかtest.c)の確認は
	redit-sinfo-get-buf2sinfo で nil 以外が返ってくればいい。
	nil が来るってことは、そのバッファ(名)は登録されていないわけで。
	なので、before/after-change-function の時は、
	現在の buffer が登録されているかを確認して、そうでなければ
	何もしないってコードをいれるだけでおk。だと思う。
	全てのバッファに対してこの確認が入るので、そこらへんのコストが
	どれだけの物かわからないけど、あるバッファへの hook の管理をするよりは
	楽だし、案外軽いかもしれない。わからんけどね。
	
	* redit-client-sm.el (redit-client-after-change-function): 
	下の変更により、ここでは SessionInfo から prev を取得している

	* redit-client-sm.el (defstruct SessionInfo):
	Session 毎(つまりバッファ毎)に previous-edited-line の保持が必要
	ってことで SessionInfo に追加

	* redit-client-sm.el (redit-client-after-change-function): memo
	insert/delete 発行判別の説明

	バッファで編集が行われたとき、次の二つの hook が反応します。

	- before-change-functions
	  バッファが変更される『直前』に呼ばれる。
	  引数には変更される予定の範囲の begin point と end point を受け取る。

	- after-change-functions
	  バッファが変更された『直後』に呼ばれる。
	  引数には変更された範囲の begin point と end point 、
	  そして二つの間にあった文字列の長さ length を受け取る。

	例えば

	  1: hoge (n: は n行目 を表す)

	というバッファがあったとする。そこで、hoge の後ろで改行を入れてみると

	  1: hoge
	  2: 

	となる。この時の before, after が受け取る begin と end の行数は

	  before: begin=1 end=1
	  after : begin=1 end=2

	また、hoge の後ろに文字を追加すると

	  1: hogea

	この時は以下のようになる。

	  before: begin=1 end=1
	  after : begin=1 end=1

	次に、以下のようなバッファがあるとする

	  1: huge
	  2: sanma

	この時、2行目の先頭で backspace (DEL) をすると

	  1: hugesanma

	となる。この時の begin/end は以下のようになる。

	  before: begin=1 end=2
	  after : begin=1 end=1

	以上の動作を複数行でやってみる。

	  1: a
	  2: b
	  3: c

	というバッファで、1〜3を C-Space, M-w, C-y というカット&ペーストで
	3行目の c の直後で行う。

	  1: a
	  2: b
	  3: ca
	  4: b
	  5: c

	  before: begin=3 end=3
	  after : begin=3 end=5
	  before: begin=3 end=5
	  after : begin=3 end=5
	  before: begin=5 end=5
	  after : begin=5 end=5

	C-y (yank) を行うと、何故か 3回呼ばれる。(要ソース読み)
	次に

	  1: a
	  2: b
	  3: ca
	  4: b
	  5: c

	というバッファがあるとして、5行目 から 2行目のbの直後までを
	C-Space,C-W でカットする。すると

	  1: a
	  2: b

	  before: begin=2 end=5
	  after : begin=2 end=2

	となる。

	以上のことをふまえて、以下の法則を見つけた(気がする)

	if (before-begin == after-end) {
	    (before-begin == before-end) {
	        if (previous-edited-line == before-end) {
	            // 前回と違う行を編集しているので
	            // previous-edited-line を insert
                    // before-end を次の previous-edited-line にする。
	        } else {
     	            // 同じ行での編集なので何もしない
	        }
	    } else {
	        // before-begin < line <= before-end を delete (改行コードも)
	        // before-begin を insert
	        // #1
	    }
	} else {
	    // 1. 編集前と後でバッファの最終行が変更されていれば、
	    //    その差だけ改行を insert で before-begin に送る
	    // #2

	
	    // 2. 1. で得られた差の数値を、
	    //     previous-edited-line が before-begin より下であれば
	    //     previous-edited-line に 加える。
	    // #3
	
	    // 3. before-begin > previous-edited-line
	    //    && after-end < previous-edited-line
	    //    の時、previous-edited-line を insert
	
	    // 4. before-begin <= line <= after-end までを insert
	}

	- #1
	before-begin を delete でない理由ですが、
	例えばこんな感じ。まあ上にもあるけど

	  1: a
	  2: b

	ってあって、b の先頭で DEL すると

	  1: ab

	になる。このとき、before-end である 2 行目は削除されるわけですが
	before-begin である 1 行目は 変更されている。
	なので、before-begin だけは insert を行っているというわけ。

	  1:
	  2:

	で、2行目で DEL だと

	  1:

	になるわけで、この場合は変更してないので送る必要はないが、
	そこまで判別するのもアレなので、今は同じく送るようにしている。
	実害ないし。無駄なのが送られるってのはアレだが。
	
	- #2
	改行を入れる必要性について。
	例えば

	  1: a
	  2: b
	  3: c
	  4: d

	ってあったとき、1〜3をカットし、3の直後にペースとしたとすると

	  1: a
	  2: b
	  3: ca
	  4: b
	  5: c
	  6: d

	ってなるのが理想的なわけです。しかし、改行を入れてないと

	  1: a
	  2: b
	  3: ca
	  4: b
	  5: c

	と、もともと 4 行目にあった d が上書きされてしまう。
	exec-insert-line では、バッファ範囲外の line number に
	insert 命令が来ると、自動的にその行まで改行を入れるように
	記述してあります。なので、この場合だと、変更があったのは 3〜5なので
	相手側では 5 行目までは行が確保されるわけ。しかし、insert そのものは、
	line number の文字列を消去して書き直す、
	上書きみたいなものなので、こんなことがおこったと。
	ですから、予め改行しておいて下の行をずらしておき、
	書く予定の行を確保しておく。
	イメージ的には、改行いれた後は以下の感じ。
	最終行が 4 から 6 に変更されてるので、受け取り側には
	改行を 2 個送って、そのあと変更部分 (3〜5) を送る

	改行のみ
	  1: a
	  2: b
	  3: c
	  4: 
	  5: 
	  6: d
	insert
	  1: a
	  2: b
	  3: ca
	  4: b
	  5: c
	  6: d

	#3
	差の分を previous-edited-line に加えているのは、
	改行によって行数がずれているからです。
	before-begin より上の行であれば影響されないので無視。

	=======

	以上。
	これでいいんじゃないかと思いました。
	現在この感じで実装していますが、今のところちゃんと動いてます(きっと)
	yank で before/after が 3回も呼ばれているのは謎です。
	ちらっとソース読んでみたんですが。。。。ふーんみたいな(何
	今のままだと無駄に3回 insert が呼ばれてしまうので
	optimize 的な意味では、ちゃんと yank を理解すべき。
	今は、正確に適切な行が insert/delete されているかを
	確かめる状況なので、ひとまず置いておく。

	上の条件式で、「もっとコンパクトにできる」「意味不明」ってのがあるかも
	誰かヘルプみー
	
2008-08-26  Wataru MIYAGUNI  <gongo@cr.ie.u-ryukyu.ac.jp>

	* redit-client-sm.el (redit-client-delete-line): TODO
	REP_project/JavaSessionManager/export にある
	テスト用の GUI だと、text size が 0 だと
	向こうでスルーするらしい。
	
	delete-line-command だとテキストを送る必要がないので
	今まで 0 にしてたんだけど、上の問題で delete が反応しなかった。
	なので、今は "55555" とかテキストに追加してます。
	テスト用GUIが修正されたらこっちも直します。
	
	* redit-client-sm.el (redit-client-after-change-function): fix,TODO
	insert/delete の条件判定変更。
	before-change-function と after-change-function の
	それぞれの begin line, end line を見て判定する事にした。
	Cで書くと

	  if ((before-begin == after-end) && (before-begin != before-end)) {
	      int endl = before-end;
	      while (endl > before-begin) {
	          delete-line(endl);
	      }
	      insert-line(before-begin);
          } else {
	      int endl = after-end;
	      while (endl >= before-begin) { // 注意
	          insert-line(endl);
	      }
	  }

	こんな感じ。詳しい説明聞きたい人は俺に直で。
	もしくは後ほど詳しく書きます。

	- 注意
	>= だと、1文字ずつ編集しても command が送信されてしまう。
	> だと全く送信されなくなるので、そこは要修正

	* redit-client-sm.el (redit-client-before-change-function): fix
	insert/delete の条件判定変更のため、
	ここでは、beginl と endl を取得するのみ

	* redit-client-sm.el (redit-client-exec-insert-line): fix
	指定したバッファの指定した行に、指定した文字列を
	挿入できるように変更。
	詳しくは test/buffer-edit に書いてます。

2008-08-23  Wataru MIYAGUNI  <gongo@cr.ie.u-ryukyu.ac.jp>

	* memo: 文字列の長さ、バイト数
	UTF-8環境で

	(length "あいうえお") => 5
	(string-bytes "あいうえお") => 15

	なわけです。こういうとき、文字数での文字の分割はともかく、
	バイト数での分割ってのがなくて、どうしようかと悩んでたんだが、

	(setq str (encode-coding-string "あいうえお" 'binary))
	=> "\222\244\242\222\244\244\222\244\246\222\244\250\222\244\252"

	だと、

	(length str2) => 15
	(string-bytes str2) => 15

	となるわけだ。つまりそういうことだ(何
	length ってのは文字コードとかふまえた上での文字数なのねーまあそうか
	
	* redit-client-sm.el (redit-client-process-filter): 
	process-filter で受け取る文字列に
	複数の REP command が連結された状態になってて
	それをどうやって読んでいくかっていうのを追加。多分動いてる。

	詳しい変更は test/packet を見ればわかると思う。多分。

	test 書いてて思ったけど、やっぱり pack/unpack とか
	そういうのは redit-client-sm.el に置くんじゃなくて
	redit-util.el とかに置いた方が test でも使いやすい気がする。知らんけど

2008-08-19  Wataru MIYAGUNI  <gongo@cr.ie.u-ryukyu.ac.jp>

	* thinking: buffer と session の関連性
	とりあえずバッファとSessionを関連づけるために
	SessionInfo なるものを作ってあるんだけど
	その切り替えをいつするかって話。2007-12-23 に書いてるね。
	先生からの助言で、

	- Session の情報が必要になるのは
	  SessionManager に送るときだけなので
	  before-change-functions/after-change-functions の時に
	  切り替えればいいんじゃないか
	- 表に出てないバッファに対しても変更は効くはずなので、
	  SessionManager から受け取った REP コマンドによる変更は
	  バッファを指定してバックグラウンドで行う

	こんな感じになりました。なるほどなるへそ。

	で、SessionInfo はハッシュテーブルで管理してて、
	キーとして SessionID と その Session に対応するバッファ名
	にしようかと思ってる。思ってた。思い続けてた。
	で、バッファ名は基本ファイル名なので、重複する恐れがある云々で
	いろいろ考えてたんだけど、よくよく考えて
	通常の emacs でもディレクトリが違ってファイル名同じだったら、
	下のファイル名の横に

	hoge.c<2>

	みたいな表示が出来る事を思い出した。
	つーことでこれでいいんじゃね?
	ということでこの方法とテストプログラム書いてみる
	
2008-08-05  Wataru MIYAGUNI  <gongo@cr.ie.u-ryukyu.ac.jp>

	* thinking: delete,replace
	SessionManager で、delete や replace に対する undo には
	編集前の文字列をコマンドに付けないと、
	SessionManager が変更できない。

	delete: 編集前の文字列
	replace: 編集前と後

	そんな感じ

2007-12-23  Wataru MIYAGUNI  <gongo@cr.ie.u-ryukyu.ac.jp>

	* thinking:
	buffer に対しての replace は (replace-string FROM TO) がある。
	けど、先輩と一緒に探してみたけど、変数に対しての replace がない。
	デフォルトでは実装されてない string.el ってのにありそうで。
	まあ、デフォルトである関数を駆使すると

	FROM で文字列を分割 リストに変換される。: (split-string FROM) 
	TO を間に挟んで文字列に変換 : 関数不明

	てかないとは思えないんだよな replace 。

	
	* 日本語関係:
	昔のゼミの資料に載ってるしね!!

	(decode-coding-string "\201\202" 'utf-8)

	* thining:
	eid は sid から、sid は bufname からってことにした。
	で、global な変数の redit-client-session-id とか editor-id が
	要らなくなってしまうが、本当は使いたい。
	get-eid-from-session-info みたいなことはできるけど
	送る度に毎回呼ぶのはちょっと。どこまで高い負荷かはわからんけど。
	で、理想としては

	バッファ(ファイル)を切り替える度に、bufname->sid を呼んで
	editor-id に設定してってのがよい。これだと get-* を呼ぶのは
	バッファ切る変える時だけですむ。
	けど、「バッファを切り替えたとき」の hook が無いみたい。
	探し方が悪いのか。見つからない。てか無い?

	いろいろやり方はあるみたい(buffer-list のソートがほげほげ)だが
	よくわからん。難しい。
	「バッファが変更されたとき」はあるけど、これは文字を
	打つだけで呼び出されるので余計悪化する。

	当分は

	* redit-client-sm.el: Session Info struct, hash table
	Session ID から取得できる Session Info 構造体を作成。
	これで Session 毎に情報を保持できると信じる。
	あとは、bufname => sid => session inf o を作る
	hash table を2つ(以下のhashのキーについてぐらいを参照)。

	こんどは実際に格納したり取り出したりのテストかな
	
	* thinking: hash のキーについて
	今まで、(buffer-name) をキーにしてコマンドリストをほげほげと
	思ってたけど、受け取る command には Session ID があるので
	それをキーにした方がいいのではと思い始める。
	そして、バッファ毎に Session ID は覚えとかないといけないので、
	(buffer-name) から Session ID を取得するハッシュテーブルも
	必要ではないかと思う。
	そして、Session ID 毎に editor ID や seq-no も保持すべき?

	================
	put-ack, select-ack で Session ID, file name が来るので
	
	bufname-to-sid-table => key = bufname, value = sid;
	sid-to-session-table => key = sid, value = session;

	// C 風に
	struct session {
	   int eid;
	   int seq-no;
	   CmdListPtr recv_cmdlist;
	   CmdListPtr send_cmdlist;
	}
	================
	
	こんな二つの hash table を作る方がいいのかな。
	bufname はグローバルだし、sid も確か
	ローカルなSession Managerでは一意に決まるはずだし。
	送信受信(insert,delete,replace)の流れ的には

	- cmd 送信
	現在の (buffer-name) をキーとして、
	bufname-to-sid-table から Session ID (以下sid) を取得。
	sid をキーとして、sid-to-session-table から
	Editor ID , Seq-no を取得し command を作成。
	その command は、sid-to-session-table から取った
	send_cmdlist に放り込む

	- cmd 受信
	cmd 内の sid で、sid-to-session-table から取得した 
	recv_cmdlist に cmd を放り込む。こんなところか。
	put-ack, select-ack の場合、text にファイル名があるはずなので
	bufname-to-sid-table に file と sid を登録する。


	こんなところでしょう。今から実装してみる
	
	

2007-12-22  Wataru MIYAGUNI  <gongo@cr.ie.u-ryukyu.ac.jp>

	* gethash():
	キーが (gethash "hoge" hash) じゃ使えない。
	(gethash 'hoge hash)ならできる。
	前は出来たと思ったけど、(buffer-name) は
	厳密には文字列じゃなかったってことかなあ
	さてどうしようか・・・

2007-12-21  Wataru MIYAGUNI  <gongo@cr.ie.u-ryukyu.ac.jp>

	* thinking: hash の扱い(解答)
	解答っつーか・・・

	(gethash '(buffer-name) hash)

	じゃなくて

	(gethash (buffer-name) hash)

	だよ。' 要らなかったね!!これでおk。

	あと、キーとして (buffer-name) か (current-buffer) が使える。
	バッファの名前か、もしくはバッファのオブジェクト?か。
	名前も、ファイル名@ホスト名だから(だっけ?)、
	一意に決まるので重複しないし。オブジェクトもしかり。
	ま、ループ回して速い方を選ぶとするか。
	
	* thinking: hash の扱い
	join or put command からの流れ
	
	1-1. join command を発行する
	1-2. join-ack 内の Session Name の buffer を作成する(そして入る)
	1-3. Session Name をキーとして、値には、対応コマンドリストかな

	2-1. put command を発行する
	2-2. current buffer の名前をキーとして、値は上に同じ。

	current buffer の名前は (buffer-name) で取れるわ。

	(setf (gethash '(buffer-name) hash) command-list) 

	こんな感じ?ってやってみたらだめだった。
	文字列じゃなくて オブジェクト でやらないと?俺もわからん。
	まあ、適当に文字列をオブジェクトにすれば、ってできんのか。
	
	* fix: 文字コード
	研究室の方針で

	## 漢字コードは utfで!! ##

	ってことで、このプロジェクトも utf に変更しました。
	参考として

	% nkf --overwrite -w *.el 
	これで *.el のファイルは UTF8 (-w) に変換できました。

	* TODO:
	- ファイル毎に buffer を用意し、コマンドが来たら
	  対応する buffer に書き込む。
	  buffer は buffer name をハッシュ値として、テーブルで持てばいいかな。
	  確か lisp ではハッシュテーブルを作れた気がする。
	  と思って調べてみたら、Emacs 21 以上からか hash 実装は。
	  でも 「Emacs 20 以前でもシンボル表を用いればできる」そうだ。
	  (参考->http://www.mew.org/~kazu/doc/elisp/hash.html)
	
	- 通信テストは、Session Manager 待ちではあるが、
	  今のうちに、ある程度のテストルーチンを作ってた方が
	  あとあと楽になりそうな気がしないでもなくも(ry

	- 受け取ったコマンドは、どのタイミングで適用しようか。
	  来た瞬間でいいのかなやっぱり。
	  それとも、貯めて、自分が更新したら?そりゃちがうわな。

	- 逆に自分が送る時はどうするんだろう。
		1. コマンド発行
		2. 適用前のコマンドリストとマージ
		3. マージ後のコマンドを送りつつ、適用
	  こんな感じかなあ。
	  でも、「適用前のコマンドリスト」ってのがわからん。
	  それなりの時間貯めとかないと重なるってことないんじゃない?
	  そのためのマージなのか。それともやっぱり貯めたりほげほげするのか
	  
	
2007-11-11  Wataru MIYAGUNI  <gongo@cr.ie.u-ryukyu.ac.jp>

	* redit-client-sm.el: redit-unpack-int
	256 以上を取得できなかったのを修正。4バイトぐらい。

	* redit-client-sm.el: redit-*-command
	REPcommand では 「insert」 なのに
	ここでは 「write」 なので、時々混乱する。insert に変更。
	それに総じて、write-* 関数を insert-* 関数にリネーム。
	あと、redit-*-command を使うときに、文字列で定義されてるので

	(string-to-number redit-read-command)

	とかやらないといけない。今日の話し合いで
	「別に文字列である必要はないぜ」ってことで
	全て数値に変更。こっちの方が楽だし、きっと速い。

2007-11-10  Wataru MIYAGUNI  <gongo@cr.ie.u-ryukyu.ac.jp>

	* redit-client-sm.el: set-process-coding-system
	送受信するパケットは binary の方が良いと指摘。
	そう言われれば確かにそうでした。pack/unpackの意味なす
	ってことで 'utf-8 から 'binary に変更しました。

	* redit-client-sm.el: process-send-string 関連
	process-send-string で、以前までは、送るコマンドを

	(format "%10d%10d" sid eid)

	って感じの文字列を生成して出力してましたが、
	これは、通信用の Perl スクリプトに送るためのものでした。
	今は既に、lispから直接 SessionManager にコマンドを送るので、これではだめ。
	前々から使ってたけど、(redit-pack sid eid...) ってのに変更しました。
	引数を何にするかって参考で、一応 obsolete な記述も残してはいますが。
	
	* redit-client-sm.el: redit-select-command (obsolete)
	editor側では select 要らないってことで。
	これで、editor側で必要なのは join, put, quit, その他編集コマンド。

	* add: translate.el
	translate のテストルーチン。使い方は

	M-x load-file RET [translate.el]
	M-x translate-test

	ってやると、*Message* バッファに、
	translateの結果が出力されます。きっと。

	* redit-client-sm.el:unpack-int
	< (setq num (* byte 4))
	<   (string-to-char (substring pkt num (+ num 1)))))
	----------
	> (setq num (* byte 4))
	>   (string-to-char (substring pkt (- num 1) num))))
	通りで、SMからのACKにある
	eid や sid を取得できない訳だ。
	
	* error: redit-put-command
	cmd(redit-put-command, 0, 0, 0, 0, str-length, str)
	みたいに送ると、GUI SessionManager で受け取る文字列が化ける。

	emacs || GUI SessionManager
	------++-------------------
	gongo -> 杯湧

	どっちが原因なのか・・・
	
	* TODO
	送信文字数がバイトとかになるんで

	(length str)

	ぐらいでいけると思ったけど、SMで文字化け。ずれてるんだろうか、
	もしくは単に文字コードの問題?でも送ったの "hoge" なんだわ。
	ま、それは明日にして寝よう (現在AM2:16)

2007-11-09  Wataru MIYAGUNI  <gongo@cr.ie.u-ryukyu.ac.jp>

	* redit-client-sm.el: TCP/IP通信の実装、それに伴うpack/unpack
	久々の更新ですわ。

	open-network-stream を追加してみた。

	redit-join-command()
	< (setq redit-client-process
	<   (start-process "reditclient" nil redit-client-program host))
	-----
	> (setq redit-client-process (open-network-stream
        >                             "redit-client"
	>                             nil
	>                             "localhost"
        >                             8766))

	nil は buffer なんだけど、よくわからんので nil 。多分使わない。きっと。
	localhost/8766 は、何か仕様変更で SM はデーモンで持つらしいので、
	ホスト名/ポート番号 決めうちで。
	ここ変えるだけで、後はプロセスを同じように使えます。


	Perlスクリプトを使わなくなったので、変更点としては
	以前:lisp からREPコマンド"っぽい文字列" -> Perl で文字列受け取って
	      ここでpack->SessionManager へ
	現在:lisp から直接 REPコマンドを -> SessionManagerへ

	ってことで lisp 内で pack/unpack を実装。
	(defun pack-int) (defun pack-int-loop) (defun unpack-int) です。
	もう少しちゃんとやるべきなんだろうか。
	ちゃんと SessionManager で反映されてるので 成功はしてるみたい。偶然?

	
2006-12-26  Wataru MIYAGUNI  <gongo@cr.ie.u-ryukyu.ac.jp>

	* 独り言
	うん、やっぱりpack/unpackの処理はアホだな。
	暫定版で出したんだからしょうがない、って言い訳をしておこう。
	今のところ0〜255までしかできないので、以下のように変更

	;; num   : packする整数
	;; count : byte length
	(defun pack-int-loop (num count)
	  (if (> count 0)
	      (concat
	       (pack-int-loop (/ num 256) (- count 1))
	       (char-to-string (% num 256)))))

	(defun pack-int (num)
	  (pack-int-loop num 4))

	ex. num が 30000、byte length が4(32bit)の時 ('X'=不定)
	;; loop start
	count 4 -> (% num 256) => 48  を1バイト目
	           (/ num 256) => 117 を2バイト目
	XXXXXXXX XXXXXXXX XXXXXXXX 00110000 (0 0   0 48)
	count 3 -> (% num 256) => 117 を2バイト目
	           (/ num 256) =>   0 を3バイト目
	XXXXXXXX XXXXXXXX 01110101 00110000 (0 0 117 48)
	count 2 -> (% num 256) =>   0 を3バイト目
	           (/ num 256) =>   0 を4バイト目
	XXXXXXXX 00000000 01110101 00110000 (0 0   0 48)
	count 1 -> (% num 256) =>   0 を4バイト目
	           (/ num 256) =>   0 を5バイト目
	00000000 00000000 01110101 00110000 (0 0 117 48)
	;; loop end

	これでおkでした。Perl側の unpack でデータ取得できました
	こんな感じでいいのかな。packソース見たい。
	あ〜あとはunpackか。まあ簡単かなpackと同じことすればいいのか。
	int だけでいいのかな。浮動小数とかいやですね。

	
2006-12-24  Wataru MIYAGUNI  <gongo@cr.ie.u-ryukyu.ac.jp>

	* redit-client-sm.el - redit-client-after-change-function ()
	< (progn (redit-client-write-line beginl nil)	;; t)
	-----
	> (progn (redit-client-write-line currline nil)	;; t)
	while でループしてるのに
	ずっとbeginlってのはおかしいかな〜と思った
	
	* 独り言
	pack/unpackもどきができた。まだ使用段階なので組み込んでません。
	- pack
	(defun pack (num) ;; num=42
	    (concat (char-to-string 0)     ;; 4バイト目
	            (char-to-string 0)     ;; 3バイト目
	            (char-to-string 0)     ;; 2バイト目
	            (char-to-string num))) ;; 1バイト目
	=> 00000000 00000000 00000000 00101010

	lispでバイト列を扱うやりかたがよくわからなかったけど
	これでなんとかrep_manager.plが unpack できてました。
	エンディアンとか考える必要あるかな。

	- unpack
	受け取ったデータから、各値(command、eid 、etc...)を取り出す。

	1〜4、5〜8、9〜12、13〜16、17〜20、21〜24
	cmd    sid   eid     seq    line    t_siz

	下位1バイト目(?)に値が入ってるので
	(substring pkt 3 4) => "*" ;; (char-to-string 42) => "*" なので
	(string-to-char "*") => 42 ・・・ 値取得成功!!

	まだまだ見直す所ありそうだけど、
	うまくいけば完全に lisp だけで REP できますね
	
2006-12-15  Wataru MIYAGUNI  <gongo@cr.ie.u-ryukyu.ac.jp>

	* 独り言
	open-network-stream で rep_manager.pl に接続できた。
	だけど、lisp 側で送信データがうまく作れてない。
	(format "%4d%4d%4d%4d%4d%4d" 41 0 0 1 0 0)
	だと、なんかうまくいかない。
	pack/unpackないかな・・・
	
2006-12-14  Wataru MIYAGUNI  <gongo@cr.ie.u-ryukyu.ac.jp>

	* 独り言
	なんか lisp から network に TCP 接続する方法があるっぽい
	(open-network-stream NAME BUFFER HOST SERVICE)
	まだ実証してませんが、なんか使えるっぽいです。(ex. navi-2ch)
	うまくいけば、redit_client.pl はいらなくなるかも。
	文字コード関係はどうしよう。decode-coding-* ぐらいで
	どうにかならないかな。ならないかも。無駄なヘッダ付加される・・・
	
	* redit-client-sm.el - redit-client-close ()
	linenum が定義されてなかったので、 0 にしました。
	別に0で大丈夫ですよね?close だし。多分。。。
	
	* redit-client-sm.el - redit-client-exec-write-line (string)
	なんか Warning でてたので
	< (end-of-buffer)
	-----
	> (call-interactively 'end-of-buffer)

	end-of-buffer は interactive 関数以外で
	呼び出したら駄目らしいです。
	いろいろ調べてたらこれで Warning 出ないので落ち着きました。
	いいのかなこれで。。。
	
2006-12-12  Wataru MIYAGUNI  <gongo@cr.ie.u-ryukyu.ac.jp>

	* redit-client-sm.el
	obsolete function を変更

	since Emacs 22.1
	< (process-kill-without-query redit-client-process)
	-----
	> (set-process-query-on-exit-flag redit-client-process nil)
	第2引数が non-nil だと、emacs終了時に
	「`Active processes exist; kill them and exit anyway?' 」
	って聞いてきます。process は redit_client.pl のことです。
	多分いらないので nil を入れました。

	since Emacs 21.1
	< (make-local-hook 'before-change-functions) ;; afterも
	-----
	> ;; (make-local-hook 'before-change-functions)
	not necessary らしいです。21.1以前だと必須みたいですが。


	* 独り言
	defstruct を使うときは
	(eval-when-compile (require 'cl)) を加えた後に
	byte-compile-file してからやると使える。