changeset 55:563a0c8c5706 v20080826

*** empty log message ***
author gongo
date Tue, 26 Aug 2008 18:54:39 +0900
parents 9620bf594a88
children 3bbcdd5060a6
files redit-client-sm.el
diffstat 1 files changed, 332 insertions(+), 266 deletions(-) [+]
line wrap: on
line diff
--- a/redit-client-sm.el	Tue Aug 26 18:26:39 2008 +0900
+++ b/redit-client-sm.el	Tue Aug 26 18:54:39 2008 +0900
@@ -63,14 +63,36 @@
   "String of the unprocessing in redit-client-process-filter")
 
 ;; REP が使用する文字コード
-(defconst redit-string-coding 'utf-8)
+(defconst redit-string-coding 'utf-8
+  "Default coding that REP use")
 
 ;; port
-(defconst redit-process-port 8766)
+(defconst redit-process-port 8766
+  "Default port that REP use")
+
+(defvar redit-client-begin-line-before-func nil
+  "Begin edited line of redit-client-before-change-function")
+(defvar redit-client-end-line-before-func nil
+  "End edited line of redit-client-before-change-function")
+(defvar redit-client-begin-line-after-func nil
+  "Begin edited line of redit-client-after-change-function")
+(defvar redit-client-end-line-after-func nil
+  "End edited line of redit-client-after-change-function")
+
 
 ;; REP command header size
 (defconst redit-command-header-size 24)
 
+(defconst redit-command-offset-cmd   0)
+(defconst redit-command-offset-sid   4)
+(defconst redit-command-offset-eid   8)
+(defconst redit-command-offset-seq  12)
+(defconst redit-command-offset-lno  16)
+(defconst redit-command-offset-siz  20)
+(defconst redit-command-offset-txt  24)
+
+
+
 (defconst redit-open-command           1)
 (defconst redit-open-ack               2)
 (defconst redit-read-command           3)
@@ -154,19 +176,22 @@
 ;; Session Info struct ;;
 ;;;;;;;;;;;;;;;;;;;;;;;;;
 
-;; eid: Editor ID corresponding to Session ID
-;; send_cmdlist:
-;;      rep_command list from user
-;; recv_cmdlist:
-;;      rep_command list from Session Manager
-(defstruct SessionInfo (eid nil) (send_cmdlist nil) (recv_cmdlist nil))
+;; sid: Session ID
+;; eid: Editor ID
+;; send_cmdlist: rep_command list from user to SessionManager
+;; recv_cmdlist: rep_command list from SessionManager to user
+(defstruct SessionInfo (sid nil) (eid nil)
+  (send_cmdlist nil) (recv_cmdlist nil))
 
 ;; create and initialize
-(defun redit-create-session-info (eid)
-  (make-SessionInfo :eid eid
+(defun redit-create-session-info (sid eid)
+  (make-SessionInfo :sid sid
+		    :eid eid
 		    :send_cmdlist (make-Queue)
 		    :recv_cmdlist (make-Queue)))
 
+(defun redit-get-session-id-from-session-info (sinfo)
+  (SessionInfo-sid sinfo))
 (defun redit-get-editor-id-from-session-info (sinfo)
   (SessionInfo-eid sinfo))
 (defun redit-get-sendqueue-from-session-info (sinfo)
@@ -174,22 +199,25 @@
 (defun redit-get-recvqueue-from-session-info (sinfo)
   (SessionInfo-recv_cmdlist sinfo))
 
-;;;;;;;;;;;;;;;;;
-;; hash table  ;;
-;;;;;;;;;;;;;;;;;
+;; hash table of SessionInfo
 
-(defvar bufname-to-sid-table (make-hash-table :test #'equal))
-(defvar sid-to-session-table (make-hash-table))
+(defvar htable-sid2bufname (make-hash-table))
+(defvar htable-bufname2sinfo (make-hash-table))
 
-(defun redit-set-sid-to-bufname-table (bufname sid)
-  (setf (gethash bufname bufname-to-sid-table) sid))
-(defun redit-get-sid-from-bufname-table (bufname)
-  (gethash bufname bufname-to-sid-table))
+(defun redit-sinfo-add-sid2buf (sid bufname)
+  (setf (gethash sid htable-sid2bufname) bufname))
+(defun redit-sinfo-get-sid2buf (sid)
+  (gethash sid htable-sid2bufname))
+(defun redit-sinfo-rm-sid2buf (sid)
+  (remhash sid htable-sid2bufname))
 
-(defun redit-set-session-info-to-sid-table (sid sinfo)
-  (setf (gethash sid sid-to-session-table) sinfo))
-(defun redit-get-session-info-from-sid-table (sid)
-  (gethash sid sid-to-session-table))
+(defun redit-sinfo-add-buf2sinfo (bufname sinfo)
+  (setf (gethash bufname htable-bufname2sinfo) sinfo))
+(defun redit-sinfo-get-buf2sinfo (bufname)
+  (gethash bufname htable-bufname2sinfo))
+(defun redit-sinfo-rm-buf2sinfo (bufname)
+  (remhash bufname htable-bufname2sinfo))
+
 
 ;;;;;;;;;;;;;;;;;;;
 ;; pack / unpack ;;
@@ -209,47 +237,39 @@
    (redit-pack-int seq) (redit-pack-int lno) (redit-pack-int siz)))
 
 (defun redit-unpack-int-loop (pkt pos count)
-  (if (> count 1)
+  (if (> count 0)
       (+
-       (* (redit-unpack-int-loop pkt (- pos 1) (- count 1)) 256)
-       (string-to-char (substring pkt (- pos 1) pos)))
+       (* (string-to-char (substring pkt pos (1+ pos))) (expt 256 (1- count)))
+       (redit-unpack-int-loop pkt (1+ pos) (1- count)))
     0
     ))
 
 (defun redit-unpack-int (pkt pos)
-  (redit-unpack-int-loop pkt (* pos 4) 4))
-
-
-;; binary この時点では、pkt は binary 形式なので
-;; substring でも抽出できる。。。ってことかな(何
-;; utf-8 とかで decode されていれば多分出来ないはず
-;; (length "あいうえお") => 5
-;; (string-bytes "あいうえお") => 15 (utf-8の場合)
-(defun redit-unpack-str (pkt pos length)
-  (substring pkt (* pos 4) (+ (* pos 4) length)))
+  (redit-unpack-int-loop pkt pos 4))
 
 (defun redit-make-packet (cmd sid eid seq lno siz text)
   (concat (redit-pack cmd sid eid seq lno siz) text))
 
 (defun redit-get-command-from-pkt (pkt)
-  (redit-unpack-int pkt 1))
+  (redit-unpack-int pkt redit-command-offset-cmd))
 (defun redit-get-session-id-from-pkt (pkt)
-  (redit-unpack-int pkt 2))
+  (redit-unpack-int pkt redit-command-offset-sid))
 (defun redit-get-editor-id-from-pkt (pkt)
-  (redit-unpack-int pkt 3))
+  (redit-unpack-int pkt redit-command-offset-eid))
 (defun redit-get-sequence-id-from-pkt (pkt)
-  (redit-unpack-int pkt 4))
+  (redit-unpack-int pkt redit-command-offset-seq))
 (defun redit-get-line-number-from-pkt (pkt)
-  (redit-unpack-int pkt 5))
+  (redit-unpack-int pkt redit-command-offset-lno))
 (defun redit-get-text-size-from-pkt (pkt)
-  (redit-unpack-int pkt 6))
+  (redit-unpack-int pkt redit-command-offset-siz))
 
 ;; text のサイズが指定されていればそれを使い、
-;; そうでなければ、get-text-size-from-pkt を実行する
+;; そうでなければ、redit-get-text-size-from-pkt を実行する
 (defun redit-get-text-from-pkt (pkt &optional _siz)
-  (let (size)
+  (let ((size) (text) (offset redit-command-offset-txt))
     (setq size (if (null _siz) (redit-get-text-size-from-pkt pkt) _siz))
-    (decode-coding-string (redit-unpack-str pkt 6 size) redit-string-coding)))
+    (setq text (substring pkt offset (+ offset size)))
+    (decode-coding-string text redit-string-coding)))
 
 ;;;;;;;;;;;;;;;;;;
 ;; User Command ;;
@@ -279,10 +299,7 @@
     ;; called when the process receive packet
     (set-process-filter redit-client-process 'redit-client-process-filter)
     
-    ;; //Code of the process input/output buffer is redit-string-coding
-    ;; //(set-process-coding-system redit-client-process redit-string-coding redit-string-coding)
-    ;; 送受信するデータはバイナリで貰わないといけない。
-    ;; utf-8 じゃなくてずれる可能性があるので
+    ;; 送受信するデータはバイナリで受け取る。
     (set-process-coding-system redit-client-process 'binary 'binary)
     
     ;; プロセスが生きてるとき、 emacs を終了しようとすると
@@ -298,34 +315,20 @@
     
     (if (string= "*scratch*" bufname) 
 	(progn
-	;; JOIN if buffer-name is "*scratch*"
-	  (process-send-string
-	   redit-client-process
-	   (concat
-	    (redit-pack
-	     redit-join-command
-	     0 0 0 0 (string-bytes bufname))
-	    (buffer-name)))
-	  (message (concat
-		    "join-command: "
-		    (number-to-string redit-join-command) " "
-		    (number-to-string 0) " "
-		    (number-to-string 0) " "
-		    (number-to-string 0) " "
-		    (number-to-string 0) " "
-		    (number-to-string (string-bytes bufname)) " " 
-		    "\"" bufname "\""
-		    )))
+	  ;; JOIN if buffer-name is "*scratch*"
+	  (process-send-string redit-client-process
+			       (redit-make-packet
+				redit-join-command 0 0 0 0 7 "bufname"))
+	  (message (format "join-command: %d 0 0 0 0 0" redit-join-command)))
       ;; PUT if buffer-name is not "*scratch*"
       (progn
-	(process-send-string
-	 redit-client-process
-	 (concat
-	  (redit-pack
-	   redit-put-command
-	   0 0 0 0 (string-bytes bufname))
-	  (buffer-name)))
-	(message "put-command"))
+	(process-send-string redit-client-process
+			     (redit-make-packet
+			      redit-put-command 0 0 0 0
+			      (string-bytes bufname) bufname))
+	(message (format
+		  "put-command: %d 0 0 0 0 %d %s"
+		  redit-put-command (string-bytes bufname) (buffer-name))))
       )))
 
 (defun redit-quit-command ()
@@ -336,19 +339,19 @@
 
 
 ;; obsolete
-(defun redit-client-open (file)
-  (interactive "P")
-  (if redit-client-process
-      (if (setq file (read-string "Filename: "))
-	  (progn
-	    ;; redit-client-process の input に文字列を送信する
-	    (process-send-string
-	     redit-client-process
-	     ;; redit-open-command (01) と file を連結させる
-	     (concat redit-open-command file))
-	    ;; redit-client-process から出力を得るまでループ
-	    (while (eq nil (accept-process-output redit-client-process)))))
-    (error "redit-client is not running.")))
+;;(defun redit-client-open (file)
+;;  (interactive "P")
+;;  (if redit-client-process
+;;      (if (setq file (read-string "Filename: "))
+;;	  (progn
+;;	    ;; redit-client-process の input に文字列を送信する
+;;	    (process-send-string
+;;	     redit-client-process
+;;	     ;; redit-open-command (01) と file を連結させる
+;;	     (concat redit-open-command file))
+;;	    ;; redit-client-process から出力を得るまでループ
+;;	    (while (eq nil (accept-process-output redit-client-process)))))
+;;    (error "redit-client is not running.")))
 
 ;; redit-client-process にreadコマンドとバッファ番号、行番号を送り、
 ;; サーバからの出力を得る
@@ -370,46 +373,35 @@
 (defun redit-client-insert-line (linenum isnewline)
   (if redit-client-process
       (save-excursion
-	(let ((beginp) (endp) (text) (length) (packet) (sinfo))
-	     (setq beginp
-		   (progn (goto-line linenum) (beginning-of-line) (point)))
-	     (setq endp
-		   (progn (goto-line linenum) (end-of-line) (point)))
-	     (setq text
-		   (encode-coding-string
-		    (buffer-substring beginp endp) redit-string-coding))
-	     (setq length (string-bytes text))
-	     
-	     ;;(setq packet (concat (redit-pack redit-insert-command
-		;;			      redit-client-session-id
-			;;		      redit-client-editor-id
-				;;	      (gen-seqno) linenum length)
-	     (setq redit-client-session-id
-		   (redit-get-sid-from-bufname-table "test.c"))
-	     (setq sinfo
-		   (redit-get-session-info-from-sid-table
-		    redit-client-session-id))
-	     (setq redit-client-editor-id
-		   (redit-get-editor-id-from-session-info sinfo))
+	(let ((beginp) (endp) (text) (text-size) (packet) (sinfo))
+	  (setq beginp
+		(progn (goto-line linenum) (beginning-of-line) (point)))
+	  (setq endp
+		(progn (goto-line linenum) (end-of-line) (point)))
+	  (setq text
+		(concat (encode-coding-string
+			 (buffer-substring beginp endp) redit-string-coding)
+			(if (eq isnewline t) "\n")))
+	  (setq text-size (string-bytes text))
 
-	     (message (concat
-		       "cmd = " (number-to-string redit-insert-command) ", "
-		       "sid = " (number-to-string redit-client-session-id) ", "
-		       "eid = " (number-to-string redit-client-editor-id) ", "
-		       "seq = " "0" ", "
-		       "lno = " (number-to-string linenum) ", "
-		       "siz = " (number-to-string length) "\n"
-		       "text= " text))
-	     (setq packet
-		   (concat
-		    (redit-pack
-		     redit-insert-command
-		     redit-client-session-id
-		     redit-client-editor-id
-		     (gen-seqno) linenum length)
-		    text
-		    (if (eq isnewline t) "\n")))	     
-	     (process-send-string redit-client-process packet)))
+	  (setq sinfo (redit-sinfo-get-buf2sinfo (buffer-name)))
+	  (if sinfo
+	      (progn
+		(setq redit-client-session-id (SessionInfo-sid sinfo))
+		(setq redit-client-editor-id (SessionInfo-eid sinfo))
+		
+		(setq packet (redit-make-packet
+			      redit-insert-command redit-client-session-id
+			      redit-client-editor-id (gen-seqno) linenum
+			      text-size text))
+		
+		(process-send-string redit-client-process packet)
+		
+		(message (format
+			  "insert-command: %d %d %d %d %d %d %s"
+			  redit-insert-command redit-client-session-id
+			  redit-client-editor-id 0 linenum text-size text))))
+	  ))
     (error "redit-client is not running.")))
 
 ;; linenum で指定した行の削除命令を redit-client-process に送信する
@@ -621,7 +613,7 @@
 	  (setq currline endl)
 	  ;; endlからbeginlまで行の削除命令を出す
 	  (while (> currline beginl) 
-	    (redit-client-delete-line endl)
+	    (redit-client-delete-line currline)
 	    (setq currline (- currline 1)))))))
 
 ;; after-change-functions に hook される
@@ -645,17 +637,39 @@
 
 ;; 引き数で与えられた string (line_num + text_data) から
 ;; 指定された行を削除し、そこに text_data を挿入する
-(defun redit-client-exec-insert-line (string)
-  (let ((linenum (redit-get-line-number-from-pkt string)) ;; 行番号
-	(text (redit-get-text-from-pkt string))) ;; テキストデータ
-    (if (< (real-count-lines (point-max)) linenum)
-	(progn
-	  (call-interactively 'end-of-buffer) (newline)))
-    (goto-line linenum)
-    (delete-region (progn (beginning-of-line) (point)) ;; 行の頭から
-		   (progn (end-of-line) (point))) ;; 行の末尾まで削除
-    (insert text) ;; テキストデータを挿入
-    ))
+(defun redit-client-exec-insert-line (pkt)
+  (let ((sid        (redit-get-session-id-from-pkt pkt))
+	(editlineno (redit-get-line-number-from-pkt pkt))
+	(text       (redit-get-text-from-pkt pkt))
+	(diff) (bufname) (sinfo))
+
+    ;; SessionID から、このテキストを挿入するべき
+    ;; バッファ名を取得する
+    (setq bufname (redit-sinfo-get-sid2buf sid))
+
+    (save-excursion
+      (set-buffer bufname)
+
+      ;; 指定行番号へ移動
+      ;; diff には、editlineno と 実際に移動した行番号の差が入る
+      ;; バッファの末尾の行が指定した行に足りない場合に diff > 0 になる
+      (setq diff (goto-line editlineno))
+
+      (if (> diff 0)
+	  ;; buffer の 最後の行番号が、editlineno に足りない場合、
+	  ;; その行数だけ改行し、その行へ移動する。
+	  ;; newline なので、下のようにテキストを削除する必要は無い
+	  (progn (end-of-line)
+		 (newline diff)
+		 (goto-line editlineno))
+	
+	;; 行頭から末尾までのテキストを削除
+	(delete-region (progn (beginning-of-line) (point))
+		       (progn (end-of-line) (point)))
+	)
+
+      ;; 新しい行を挿入
+      (insert text))))
 
 ;; 引き数 string (line_num + text_data) で指定された行を削除する
 (defun redit-client-exec-delete-line (string)
@@ -745,38 +759,56 @@
 
 ;; 引き数で与えられた string から Editor IDを取得する
 (defun redit-client-exec-join (string)
-  (let (sinfo)
+  (let ((filename) (bufname) (sinfo))
     (setq redit-client-editor-id (redit-get-editor-id-from-pkt string))
     (setq redit-client-session-id (redit-get-session-id-from-pkt string))
-  
-    (setq sinfo (redit-create-session-info redit-client-editor-id))
-    (redit-set-session-info-to-sid-table redit-client-session-id sinfo)
-    (redit-set-sid-to-bufname-table "test.c" redit-client-session-id)
+    (setq filename (redit-get-text-from-pkt string))
+
+    ;; SessionInfo の生成
+    (setq sinfo (redit-create-session-info redit-client-session-id
+					   redit-client-editor-id))
+
+    ;; SessionManager から受け取った、このセッションのファイル名を
+    ;; バッファ名とし、そのバッファを生成する。
+    (setq bufname (buffer-name (generate-new-buffer filename)))
+
+    ;; SessionID => BufferName => SessionInfo のテーブル生成
+    (redit-sinfo-add-sid2buf redit-client-session-id bufname)
+    (redit-sinfo-add-buf2sinfo bufname sinfo)
+
+    (switch-to-buffer bufname)
     
-    (message (concat "Session ["
-		     (number-to-string redit-client-session-id)
-		     "] "
-		     "test.c"))
-    (message (concat "Your editor id = " (number-to-string redit-client-editor-id)))
+    (message (format "join-ack: Session [%d] %s"
+		     redit-client-session-id bufname))
+    (message (format "Your editor id = %d" redit-client-editor-id))
 ))
 
 ;; //引き数で与えられた string から Session IDを取得する
 ;; 新仕様で、(put = ファイル有りjoin) ってことになって
 ;; editor id を返すことになったので、sid と共に eid もセーブする
 (defun redit-client-exec-put (string)
-  (let (sinfo)
+  (let ((sinfo) (bufname))
     (setq redit-client-editor-id (redit-get-editor-id-from-pkt string))
     (setq redit-client-session-id (redit-get-session-id-from-pkt string))
-
-    (setq sinfo (redit-create-session-info redit-client-editor-id))
-    (redit-set-session-info-to-sid-table redit-client-session-id sinfo)
-    (redit-set-sid-to-bufname-table "test.c" redit-client-session-id)
     
-    (message (concat "Session ["
-		     (number-to-string redit-client-session-id)
-		     "] "
-		     "test.c" "\n"))
-    (message (concat "Your editor id = " (number-to-string redit-client-editor-id) "\n"))))
+    ;; SessionInfo の生成
+    (setq sinfo (redit-create-session-info redit-client-session-id
+					   redit-client-editor-id))
+
+    ;; put (ファイル名付きjoin) を行ったバッファで
+    ;; すでにファイルが開かれている(はずな)ので、それをバッファ名とする
+    (setq bufname (buffer-name))
+
+    ;; SessionID => BufferName => SessionInfo のテーブル生成
+    (redit-sinfo-add-sid2buf redit-client-session-id bufname)
+    (redit-sinfo-add-buf2sinfo bufname sinfo)
+
+    (switch-to-buffer bufname)
+    
+    (message (format "put-ack Session [%d] %s"
+		     redit-client-session-id bufname))
+    (message (format "Your editor id = %d" redit-client-editor-id))
+))
   
 ;; SessionIDを名前とした、新しいバッファを開く
 ;; FIXME
@@ -797,113 +829,114 @@
   "generate editor local sequence number."
   (setq redit-client-seqno (+ redit-client-seqno 1)))
 
-(defun redit-line-translate-out (cque rque)
-  "redit line translate for output"
-  (let ((cc) (rc) (xcc) (xrc) (ccc) (crc) (cignore 0) (rignore 0))
-    (setq xcc 0)
-    (setq xrc 0)
-    (setq cignore 0)
-    (setq rignore 0)
-    (while cque
-      (setq cc (car cque))
-      (while rque
-	(setq rc (car rque))
-	;; -------- translation ------------
 
-	(if (< (+ (redit-get-line-from-queue cc) xcc) (+ (redit-get-line-from-queue rc) xrc))
-	    (if (= (redit-get-command-from-queue cc) redit-insert-command) (setq xrc (- xrc 1)))
-	  (if (= (redit-get-command-from-queue cc) redit-delete-line-command) (setq xrc (- xrc 1))))
-
-	(if (> (+ (redit-get-line-from-queue cc) xcc) (+ (redit-get-line-from-queue rc) xrc))
-	    (if (= (redit-get-command-from-queue rc) redit-insert-command) (setq xcc (+ xcc 1)))
-	  (if (= (redit-get-command-from-queue rc) redit-delete-line-command) (setq xcc (- xcc 1))))
-
-	(if (= (+ (redit-get-line-from-queue cc) xcc) (+ (redit-get-line-from-queue rc) xrc))
-	    (if (= (redit-get-command-from-queue rc) redit-insert-command) (setq xcc (+ xcc 1)))
-	  (if (= (redit-get-command-from-queue rc) redit-replace-command)
-	      (if (= (redit-get-command-from-queue cc) redit-insert-command) (setq xrc (+ xrc 1)))
-	    (if (= (redit-get-command-from-queue cc) redit-replace-command) (setq cignore 1))
-	    (if (= (redit-get-command-from-queue cc) redit-delete-line-command) (setq crc redit-insert-command) (setq cignore 1))))
-
-	(if (= (redit-get-command-from-queue rc) redit-delete-line-command)
-	    (if (= (redit-get-command-from-queue cc) redit-insert-command) (setq xrc (+ (redit-get-line-from-queue rc) 1)))
-	  (if (= (redit-get-command-from-queue cc) redit-replace-command) (setq cignore 1))
-	  (if (= (redit-get-command-from-queue cc) redit-delete-line-command) (setq cignore 1) (setq rignore 1)))
-
-	;; -------- translation ------------
-
-	(setq rque (cdr rque)))	;; while rque
-
-      ;; ignore
-      (if (= cignore 1)
-	  ;; xxx
-	  (setq cignore 0))
-      (if (= rignore 1)
-	  ;; xxx
-	  (setq cignore 0))
-
-      ;; -------- add after que ------------
-      (enqueue after-CQ (concat (format "%2d%2d%9d" (redit-get-command-from-queue cc) (redit-get-uid-from-queue cc) (+ (redit-get-line-from-queue cc) xcc)) (redit-get-text-from-queue cc)))
-      ;; -------- add after que ------------
-
-      (setq cque (cdr cque))) ;; while cque
-    )			      ;; let
-  )			      ;; defun
-
-(defun redit-line-translate-in (cque rque)
-  "redit line translate for input"
-  (let ((cc) (rc) (xcc) (xrc) (ccc) (crc) (cignore 0) (rignore 0))
-    (setq xcc 0)
-    (setq xrc 0)
-    (setq cignore 0)
-    (setq rignore 0)
-    (while rque
-      (setq rc (car rque))
-      (setq cignore 0)
-      (setq rignore 0)
-      (while cque
-	(setq cc (car cque))
-	;; -------- translation ------------
-
-	(if (and (= cignore 1) (= rignore 1))
-	    (if (< (+ (redit-get-line-from-queue rc) xrc) (+ (redit-get-line-from-queue cc) xcc))
-		(if (= (redit-get-command-from-queue rc) redit-insert-command) (setq xcc (+ xcc 1)))
-	      (if (= (redit-get-command-from-queue rc) redit-delete-line-command) (setq xcc (- xcc 1))))
-
-	  (if (> (+ (redit-get-line-from-queue rc) xrc) (+ (redit-get-line-from-queue cc) xcc))
-	      (if (= (redit-get-command-from-queue cc) redit-insert-command) (setq xrc (- xrc 1)))
-	    (if (= (redit-get-command-from-queue cc) redit-delete-line-command) (setq xrc (+ xrc 1))))
-
-	  (if (= (+ (redit-get-line-from-queue rc) xrc) (+ (redit-get-line-from-queue cc) xcc))
-	      (if (= (redit-get-command-from-queue cc) redit-insert-command) (setq xcc (+ xcc 1)))
-	    (if (= (redit-get-command-from-queue cc) redit-replace-command)
-		(if (= (redit-get-command-from-queue rc) redit-insert-command) (setq xcc (+ xcc 1)))
-	      (if (= (redit-get-command-from-queue rc) redit-replace-command) (setq cignore 1))
-	      (if (= (redit-get-command-from-queue rc) redit-delete-line-command) (setq crc redit-insert-command) (setq cignore 1))))
-	  (if (= (redit-get-command-from-queue cc) redit-delete-line-command)
-	      (if (= (redit-get-command-from-queue rc) redit-insert-command) (setq xcc (+ (redit-get-line-from-queue cc) 1)))
-	    (if (= (redit-get-command-from-queue rc) redit-replace-command) (setq crc redit-insert-command) (setq cignore 1))
-	    (if (= (redit-get-command-from-queue rc) redit-delete-line-command) (setq cignore 1) (setq rignore 1))))
-
-	;; -------- translation ------------
-
-	(setq cque (cdr cque)))	;; while rque
-
-      ;; ignore
-      (if (= cignore 1)
-	  ;; xxx
-	  (setq cignore 0))
-      (if (= rignore 1)
-	  ;; xxx
-	  (setq rignore 0))
-
-      ;; -------- add after que ------------
-      (enqueue after-RQ (concat (format "%2d%2d%9d" (redit-get-command-from-queue rc) (redit-get-uid-from-queue rc) (+ (redit-get-line-from-queue rc) xrc)) (redit-get-text-from-queue rc)))
-      ;; -------- add after que ------------
-
-      (setq rque (cdr rque))) ;; while cque
-    )			      ;; let
-  )			      ;; defun
+;;(defun redit-line-translate-out (cque rque)
+;;  "redit line translate for output"
+;;  (let ((cc) (rc) (xcc) (xrc) (ccc) (crc) (cignore 0) (rignore 0))
+;;    (setq xcc 0)
+;;    (setq xrc 0)
+;;    (setq cignore 0)
+;;    (setq rignore 0)
+;;    (while cque
+;;      (setq cc (car cque))
+;;      (while rque
+;;	(setq rc (car rque))
+;;	;; -------- translation ------------
+;;
+;;	(if (< (+ (redit-get-line-from-queue cc) xcc) (+ (redit-get-line-from-queue rc) xrc))
+;;	    (if (= (redit-get-command-from-queue cc) redit-insert-command) (setq xrc (- xrc 1)))
+;;	  (if (= (redit-get-command-from-queue cc) redit-delete-line-command) (setq xrc (- xrc 1))))
+;;
+;;	(if (> (+ (redit-get-line-from-queue cc) xcc) (+ (redit-get-line-from-queue rc) xrc))
+;;	    (if (= (redit-get-command-from-queue rc) redit-insert-command) (setq xcc (+ xcc 1)))
+;;	  (if (= (redit-get-command-from-queue rc) redit-delete-line-command) (setq xcc (- xcc 1))))
+;;
+;;	(if (= (+ (redit-get-line-from-queue cc) xcc) (+ (redit-get-line-from-queue rc) xrc))
+;;	    (if (= (redit-get-command-from-queue rc) redit-insert-command) (setq xcc (+ xcc 1)))
+;;	  (if (= (redit-get-command-from-queue rc) redit-replace-command)
+;;	      (if (= (redit-get-command-from-queue cc) redit-insert-command) (setq xrc (+ xrc 1)))
+;;	    (if (= (redit-get-command-from-queue cc) redit-replace-command) (setq cignore 1))
+;;	    (if (= (redit-get-command-from-queue cc) redit-delete-line-command) (setq crc redit-insert-command) (setq cignore 1))))
+;;
+;;	(if (= (redit-get-command-from-queue rc) redit-delete-line-command)
+;;	    (if (= (redit-get-command-from-queue cc) redit-insert-command) (setq xrc (+ (redit-get-line-from-queue rc) 1)))
+;;	  (if (= (redit-get-command-from-queue cc) redit-replace-command) (setq cignore 1))
+;;	  (if (= (redit-get-command-from-queue cc) redit-delete-line-command) (setq cignore 1) (setq rignore 1)))
+;;
+;;	;; -------- translation ------------
+;;
+;;	(setq rque (cdr rque)))	;; while rque
+;;
+;;      ;; ignore
+;;      (if (= cignore 1)
+;;	  ;; xxx
+;;	  (setq cignore 0))
+;;      (if (= rignore 1)
+;;	  ;; xxx
+;;	  (setq cignore 0))
+;;
+;;      ;; -------- add after que ------------
+;;      (enqueue after-CQ (concat (format "%2d%2d%9d" (redit-get-command-from-queue cc) (redit-get-uid-from-queue cc) (+ (redit-get-line-from-queue cc) xcc)) (redit-get-text-from-queue cc)))
+;;      ;; -------- add after que ------------
+;;
+;;      (setq cque (cdr cque))) ;; while cque
+;;    )			      ;; let
+;;  )			      ;; defun
+;;
+;;(defun redit-line-translate-in (cque rque)
+;;  "redit line translate for input"
+;;  (let ((cc) (rc) (xcc) (xrc) (ccc) (crc) (cignore 0) (rignore 0))
+;;    (setq xcc 0)
+;;    (setq xrc 0)
+;;    (setq cignore 0)
+;;    (setq rignore 0)
+;;    (while rque
+;;      (setq rc (car rque))
+;;      (setq cignore 0)
+;;      (setq rignore 0)
+;;      (while cque
+;;	(setq cc (car cque))
+;;	;; -------- translation ------------
+;;
+;;	(if (and (= cignore 1) (= rignore 1))
+;;	    (if (< (+ (redit-get-line-from-queue rc) xrc) (+ (redit-get-line-from-queue cc) xcc))
+;;		(if (= (redit-get-command-from-queue rc) redit-insert-command) (setq xcc (+ xcc 1)))
+;;	      (if (= (redit-get-command-from-queue rc) redit-delete-line-command) (setq xcc (- xcc 1))))
+;;
+;;	  (if (> (+ (redit-get-line-from-queue rc) xrc) (+ (redit-get-line-from-queue cc) xcc))
+;;	      (if (= (redit-get-command-from-queue cc) redit-insert-command) (setq xrc (- xrc 1)))
+;;	    (if (= (redit-get-command-from-queue cc) redit-delete-line-command) (setq xrc (+ xrc 1))))
+;;
+;;	  (if (= (+ (redit-get-line-from-queue rc) xrc) (+ (redit-get-line-from-queue cc) xcc))
+;;	      (if (= (redit-get-command-from-queue cc) redit-insert-command) (setq xcc (+ xcc 1)))
+;;	    (if (= (redit-get-command-from-queue cc) redit-replace-command)
+;;		(if (= (redit-get-command-from-queue rc) redit-insert-command) (setq xcc (+ xcc 1)))
+;;	      (if (= (redit-get-command-from-queue rc) redit-replace-command) (setq cignore 1))
+;;	      (if (= (redit-get-command-from-queue rc) redit-delete-line-command) (setq crc redit-insert-command) (setq cignore 1))))
+;;	  (if (= (redit-get-command-from-queue cc) redit-delete-line-command)
+;;	      (if (= (redit-get-command-from-queue rc) redit-insert-command) (setq xcc (+ (redit-get-line-from-queue cc) 1)))
+;;	    (if (= (redit-get-command-from-queue rc) redit-replace-command) (setq crc redit-insert-command) (setq cignore 1))
+;;	    (if (= (redit-get-command-from-queue rc) redit-delete-line-command) (setq cignore 1) (setq rignore 1))))
+;;
+;;	;; -------- translation ------------
+;;
+;;	(setq cque (cdr cque)))	;; while rque
+;;
+;;      ;; ignore
+;;      (if (= cignore 1)
+;;	  ;; xxx
+;;	  (setq cignore 0))
+;;      (if (= rignore 1)
+;;	  ;; xxx
+;;	  (setq rignore 0))
+;;
+;;      ;; -------- add after que ------------
+;;      (enqueue after-RQ (concat (format "%2d%2d%9d" (redit-get-command-from-queue rc) (redit-get-uid-from-queue rc) (+ (redit-get-line-from-queue rc) xrc)) (redit-get-text-from-queue rc)))
+;;      ;; -------- add after que ------------
+;;
+;;      (setq rque (cdr rque))) ;; while cque
+;;    )			      ;; let
+;;  )			      ;; defun
 
 ;; for debug
 ;;(defun redit-client-print-command-queue ()
@@ -926,4 +959,37 @@
 ;;  "Print command queue."
 ;;  (interactive)
 ;;  (print redit-client-send-queue))
-;;
\ No newline at end of file
+;;
+
+;;
+;; insert-line-to-buffer.el
+;;   指定したバッファの、指定した行に、指定した文字列を挿入。
+;;   バッファの最後尾行が指定した行に足りない場合、その数だけ改行する
+;;
+;; buffer : 編集するバッファ(名)
+;; lineno : 編集するbufの行番号
+;; string : lineno行目に挿入する文字列
+(defun insert-line-to-buffer (buffer lineno string)
+  "Insert STRING at line LINENO of BUFFER.
+The line LINENO is deleted, and STRING is inserted."
+  (let (curlineno)
+    (save-excursion
+      (set-buffer (get-buffer-create buffer))
+      (goto-line lineno) ;; 指定行番号へ移動
+      (setq curlineno (real-count-lines (point))) ;; 現在の行番号
+
+      (if (> lineno curlineno)
+	  ;; buffer の 最後の行番号が、指定した lineno に足りない場合、
+	  ;; その行数だけ改行し、その行へ移動する。
+	  ;; newline なので、下のようにテキストを削除する必要は無い
+	  (progn (end-of-line)
+		 (newline (- lineno curlineno))
+		 (goto-line lineno))
+	
+	;; 行頭から末尾までのテキストを削除
+	(delete-region (progn (beginning-of-line) (point))
+		       (progn (end-of-line) (point)))
+	)
+
+      ;; 新しい行を挿入
+      (insert string))))