Mercurial > hg > RemoteEditor > emacs
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))