changeset 67:90e10010a4f3

*** empty log message ***
author gongo
date Fri, 19 Sep 2008 17:44:41 +0900
parents d3088b01c363
children bb40c73f7af3
files redit-client-sm.el
diffstat 1 files changed, 149 insertions(+), 113 deletions(-) [+]
line wrap: on
line diff
--- a/redit-client-sm.el	Fri Sep 12 14:19:36 2008 +0900
+++ b/redit-client-sm.el	Fri Sep 19 17:44:41 2008 +0900
@@ -1,7 +1,6 @@
 ;; 	$Id$
 
-;; cl-macs でマクロとして定義されているため
-;; cl.el をインクルードしておく
+;; defstruct
 (require 'cl)
 
 ;;
@@ -41,15 +40,6 @@
 (defvar redit-client-line-max-in-server nil
   "Value of point-max in server's buffer.")
 
-;; obsolete
-;; Session と繋がっている各バッファで保持する事になったので
-;; SessionInfo に持たせている
-;;(defvar redit-client-previous-edited-line 1
-;;"Current cursor line of remote-edit client.")
-
-(defvar redit-client-previous-max-line 1
-  "The max line in the current buffer")
-
 (defvar redit-client-after-edited-line 1
   "Current cursor line of remote-edit client.")
 
@@ -130,6 +120,8 @@
 (defconst redit-quit-command           53)
 (defconst redit-quit-ack-command       54)
 
+(defconst redit-sync-command    82)
+(defconst redit-sync-ackcommand 83)
 
 (defconst redit-debug-flag t)
 (defun redit-debug-message (string)
@@ -181,6 +173,8 @@
 (defun redit-get-text-from-queue (queue)
   (nth 3 (Queue-front queue)))
 
+(defvar redit-client-send-command-queue (make-Queue))
+
 ;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; Session Info struct ;;
 ;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -216,6 +210,7 @@
 (defvar htable-bufname2sinfo (make-hash-table))
 
 (defun redit-sinfo-put-sid2buf (sid bufname)
+  ""
   (setf (gethash sid htable-sid2bufname) bufname))
 (defun redit-sinfo-get-sid2buf (sid)
   (gethash sid htable-sid2bufname))
@@ -229,7 +224,6 @@
 (defun redit-sinfo-rm-buf2sinfo (bufname)
   (remhash bufname htable-bufname2sinfo))
 
-
 ;;;;;;;;;;;;;;;;;;;
 ;; pack / unpack ;;
 ;;;;;;;;;;;;;;;;;;;
@@ -379,7 +373,7 @@
 ;; バッファ(sid)番号、行番号、行の内容を送り、 Ack を受け取る
 ;; _text が指定されている場合、バッファのlinenumの文字列ではなく
 ;; _text で指定された文字列を送信する
-(defun redit-client-insert-line (linenum isnewline &optional _text)
+(defun redit-client-insert-line (linenum &optional isnewline _text)
   "Send \"redit-insert-command\" to SessionManager.
 
 If current buffer is not connected with SessionManager,
@@ -406,35 +400,28 @@
 	(let (sinfo)
 	  (setq sinfo (redit-sinfo-get-buf2sinfo (buffer-name)))
 	  (if sinfo
-	      (let (text text-size)
-		(if (null _text)
-		    (let (beginp endp)
-		      (goto-line linenum)
-		      (setq beginp (progn (beginning-of-line) (point)))
-		      (setq endp (progn (end-of-line) (point)))
-		      (setq text
-			    (concat (encode-coding-string
-				     (concat (buffer-substring beginp endp)
-					     (if (eq isnewline t) "\n"))
-				     redit-string-coding)
-				    )))
-		  (setq text _text))
+	      (let ((sid (SessionInfo-sid sinfo))
+		    (eid (SessionInfo-eid sinfo)) (packet) (text) (text-size))
+		(setq text (if (null _text)
+			       (encode-coding-string
+				(get-string-from-buffer linenum)
+				redit-string-coding)
+			     (setq text _text)))
 		(setq text-size (string-bytes text))
-		(let ((sid (SessionInfo-sid sinfo))
-		      (eid (SessionInfo-eid sinfo)) (packet))
-		  
-		  (setq packet (redit-make-packet
-				redit-insert-command sid eid
-				(gen-seqno) linenum text-size text))
+
+		(setq packet (redit-make-packet
+			      redit-insert-command sid eid
+			      (gen-seqno) linenum text-size text))
 		
-		  (process-send-string redit-client-process packet)
+		;;(process-send-string redit-client-process packet)
+		(enqueue redit-client-send-command-queue packet)
 		
-		  (redit-debug-message
-		   (format "insert-command: %d %d %d %d %d %d %s"
-			   redit-insert-command sid eid (gen-seqno)
-			   linenum text-size text))
-		  ))
-	  )))
+		(redit-debug-message
+		 (format "insert-command: %d %d %d %d %d %d %s"
+			 redit-insert-command sid eid (gen-seqno)
+			 linenum text-size text))
+		)
+	    )))
     (error "redit-client is not running.")))
 
 ;; linenum で指定した行の削除命令を redit-client-process に送信する
@@ -452,33 +439,71 @@
       (sid & eid are acquired from hash table `SessionInfo'.)
 seq : Sequence Number. it can be acquired it from function `gen-seqno'.
 lno : Delete line number, LINENUM.
-siz : 0
+siz : byte size of delete text
 
 * REP command text
 
-No text."
+Deleted string of the LINENUM line of current buffer.
+"
   (if redit-client-process
       (save-excursion
 	(let (sinfo)
 	  (setq sinfo (redit-sinfo-get-buf2sinfo (buffer-name)))
 	  (if sinfo
 	      (let ((sid (SessionInfo-sid sinfo))
-		    (eid (SessionInfo-eid sinfo)) (packet))
-		;; insert lines on server buffer
+		    (eid (SessionInfo-eid sinfo)) (packet) (text) (text-size))
+		(setq text (get-string-from-buffer linenum))
+		(setq text-size (string-bytes text))
+
 		(setq packet (redit-make-packet
 			      redit-delete-line-command sid eid
-			      (gen-seqno) linenum 5 "55555"))
+			      (gen-seqno) linenum text-size text))
 	    
-		(process-send-string redit-client-process packet)
+		;;(process-send-string redit-client-process packet)
+		(enqueue redit-client-send-command-queue packet)
 
 		(redit-debug-message
-		 (format "delete-line-command: %d %d %d %d %d %d %s"
+		 (format "delete-command: %d %d %d %d %d %d %s"
 			 redit-delete-line-command sid eid (gen-seqno)
-			 linenum 0 ""))
-		))
-	  ))
+			 linenum text-size text))
+		)
+	    )))
     (error "redit-client is not running.")))
 
+(defun redit-client-replace-line (linenum &optional text)
+  "Send \"redit-delete-line-command\" and \"redit-insert-line-command
+to SessionManager.
+
+`redit-replace-command' is obsolete command.
+Now, replace command is done by using `redit-client-delete-line' and
+`redit-client-insert-line'.
+
+For example, now buffer
+
+1: hoge
+2: void
+3: elisp
+
+argument LINENUM = 2, TEXT = \"redit-client\"
+
+result
+
+1: hoge
+2: redit-client
+3: elisp
+"
+  (redit-client-delete-line linenum)
+  (redit-client-insert-line linenum text))
+
+(defun redit-client-send-rep-command ()
+  (let (command)
+    (setq command (dequeue redit-client-send-command-queue))
+    (while command
+      (process-send-string redit-client-process command)
+      (setq command (dequeue redit-client-send-command-queue))
+  ))
+)
+
 ;; proc == redit-client-process
 ;; string == redit-client-process からの output
 (defun redit-client-process-filter (proc string)
@@ -561,9 +586,30 @@
 In this function, the line of beginning, end and max line
 of old buffer are only secured.
 "
-  (setq redit-client-before-begin-line (real-count-lines begin))
-  (setq redit-client-before-end-line (real-count-lines end))
-  (setq redit-client-previous-max-line (real-count-lines (point-max)))
+  (let (sinfo)
+    (setq redit-client-before-begin-line (real-count-lines begin))
+    (setq redit-client-before-end-line (real-count-lines end))
+
+    (setq sinfo (redit-sinfo-get-buf2sinfo (buffer-name)))
+    (if sinfo
+	(progn
+	  ;; previous edit line
+	  (let (prev-edit-line)
+	    (setq prev-edit-line (SessionInfo-prevline sinfo))
+	    (if (/= prev-edit-line redit-client-before-begin-line)
+		(progn
+		  (redit-client-replace-line prev-edit-line))))
+
+	  ;; delete-line
+	  (let (editl)
+	    (setq editl redit-client-before-end-line)
+	    (if (> editl redit-client-before-begin-line)
+		(while (>= editl redit-client-before-begin-line)
+		  (redit-client-delete-line editl)
+		  (setq editl (1- editl)))))
+	  )
+      )
+    )
   )
 
 (defun redit-client-after-change-function (begin end length)
@@ -587,66 +633,31 @@
 
 	  (setq redit-client-after-begin-line (real-count-lines begin))
 	  (setq redit-client-after-end-line (real-count-lines end))
-	  (setq cur-max-line (real-count-lines (point-max)))
-	  (setq prev-edit-line (SessionInfo-prevline sinfo))
 
 	  ;; 詳しくは ChangeLog [2008-08-28] を見て
 	  (if (= redit-client-before-begin-line redit-client-after-end-line)
-	      (progn
-		(setq max-line-diff
-		      (- redit-client-previous-max-line cur-max-line))
-
-		;; delete-line
-		(setq editl redit-client-before-end-line)
-		(while (> editl redit-client-before-begin-line)
-		  (redit-client-delete-line editl)
-		  (setq editl (1- editl)))
+	      ;; case delete
+	      (if (/= redit-client-before-begin-line
+		      redit-client-before-end-line)
+		  (redit-client-insert-line redit-client-before-begin-line))
 
-		;; 前回編集行が、今回の編集の範囲に無ければ insert
-		(if (not
-		     (is-value-in-range redit-client-before-begin-line
-					prev-edit-line
-					redit-client-before-end-line))
-		     (progn
-		       ;; 行の削除による prev-edit-line のずれを考慮
-		       (redit-client-insert-line
-			(if (> prev-edit-line redit-client-before-end-line)
-			    (- prev-edit-line max-line-diff) prev-edit-line)
-			nil)
-		       (redit-client-insert-line
-			redit-client-before-begin-line nil)
-		       )
-		  )
-		)
 	    (progn
-	      ;; 行の追加によって最終行が増えていれば
-	      ;; insert する行の最後尾に "\n" を付加する。
-	      ;; また prev-edit-line が変化している可能性があるのでそれの修正
-	      (setq max-line-diff
-		    (- cur-max-line redit-client-previous-max-line))
-	      (if (> max-line-diff 0)
-		  (setq lf-flg t)) ;;
-
-	      ;; insert
+	      ;; case insert or replace
 	      (setq editl redit-client-before-begin-line)
 	      (while (< editl redit-client-after-end-line)
-		(redit-client-insert-line editl lf-flg)
-		(setq editl (1+ editl))
-		)
-	      (redit-client-insert-line redit-client-after-end-line nil)
+		(redit-client-insert-line editl)
+		(setq editl (1+ editl)))
 
-	      ;; 前回編集行が、今回の編集の範囲に無ければ insert
-	      (if (not (is-value-in-range redit-client-before-begin-line
-					  prev-edit-line
-					  redit-client-after-end-line))
-		  (redit-client-insert-line
-		   (if (> prev-edit-line redit-client-before-begin-line)
-		       (+ prev-edit-line max-line-diff) prev-edit-line)
-		   nil)
-		)
+	      ;; case insert
+	      (if (= redit-client-before-begin-line
+		     redit-client-before-end-line)
+		  (redit-client-delete-line redit-client-after-end-line))
+
+	      (redit-client-insert-line redit-client-after-end-line)
 	      )
 	    )
-	  
+
+	  (redit-client-send-rep-command)
 	  (setf (SessionInfo-prevline sinfo) redit-client-after-end-line)
 ))))
 
@@ -668,10 +679,9 @@
 
 1: hoge
 2: redit-client
-3: elisp"
+3: void
+4: elisp"
   (let (curlineno bufname sinfo)
-    ;; SessionID から、このテキストを挿入するべき
-    ;; バッファ名を取得する
     (setq bufname (redit-sinfo-get-sid2buf sid))
 
     (save-excursion
@@ -679,20 +689,17 @@
 
       (goto-line linenum)
       (setq curlineno (real-count-lines (point)))
+
       (if (> linenum curlineno)
 	  ;; buffer の 最後の行番号が、linenum に足りない場合、
 	  ;; その行数だけ改行し、その行へ移動する。
 	  ;; newline なので、下のようにテキストを削除する必要は無い
 	  (progn (end-of-line)
 		 (newline (- linenum curlineno))
-		 (goto-line linenum))
-	
-	;; 行頭から末尾までのテキストを削除
-	(delete-region (progn (beginning-of-line) (point))
-		       (progn (end-of-line) (point)))
-	)
-
-      (insert text)
+		 (goto-line linenum)))
+ 
+      (beginning-of-line)
+      (insert (concat text "\n"))
 )))
 
 (defun redit-client-exec-delete-line (sid linenum)
@@ -780,6 +787,21 @@
     (redit-debug-message (format "Your editor id = %d" eid))
 ))
 
+(defun redit-client-exec-sync (sid)
+  (let ((max-line (real-count-lines (point-max)))
+	(curline 1))
+    (while (<= curline max-line)
+      (redit-client-delete-line curline)
+      (redit-client-insert-line curline)
+
+      (accept-process-output redit-client-process)
+
+      (setq curline (1+ curline))
+      )
+    )
+  )
+
+
 ;; プロセスの状態を見て、対応したメッセージを表示
 (defun redit-client-sentinel (proc msg)
   (cond ((eq (process-status proc) 'exit)
@@ -791,6 +813,20 @@
   "generate editor local sequence number."
   (setq redit-client-seqno (+ redit-client-seqno 1)))
 
+(defun get-string-from-buffer (linenum &optional _bufname)
+  (let (bufname)
+    (if (null _bufname)
+	(setq bufname (buffer-name))
+      (setq bufname _bufname))
+
+    (save-excursion
+      (set-buffer bufname)
+      (goto-line linenum)
+      (buffer-substring (progn (beginning-of-line) (point))
+			(progn (end-of-line) (point)))
+      )
+    )
+  )
 
 (defun is-value-in-range (min value max)
   (if (and (<= min value) (<= value max))