Mercurial > hg > RemoteEditor > emacs
changeset 2:2b212e5a0009
add redit_client.pl and fix redit-client-sm.el
author | shinobu |
---|---|
date | Tue, 08 Aug 2006 07:49:12 +0900 |
parents | a897604a9280 |
children | 52cb18a3c1e2 |
files | redit-client-sm.el redit_client.pl |
diffstat | 2 files changed, 238 insertions(+), 104 deletions(-) [+] |
line wrap: on
line diff
--- a/redit-client-sm.el Mon Nov 28 18:38:29 2005 +0900 +++ b/redit-client-sm.el Tue Aug 08 07:49:12 2006 +0900 @@ -1,7 +1,7 @@ ; $Id$ ; (defcustom redit-client-program "/usr/home/masasi/work/redit/reditclient" ;(defcustom redit-client-program "/usr/home/shinobu/redit/demo/reditclient" - (defcustom redit-client-program "/home/dot/work/rep/emacs/edit/reditclient" + (defcustom redit-client-program "/Users/dot/work/REP_project/emacs/redit_client.pl" "The program to use as the remote-edit client." :group 'redit :type 'string) @@ -26,6 +26,9 @@ (defvar redit-client-editor-id "0" "Remote-edit client's editor-id.") +(defvar redit-client-session-id 0 + "Remote-edit client's session-id.") + ; editor local sequence number (defvar redit-client-seqno 0 "Remote-edit client's editor-id.") @@ -60,13 +63,20 @@ (defvar redit-replace-command "13") ;; REP Session -(defvar redit-join-command "41") -(defvar redit-get-command "43") -(defvar redit-put-command "45") -(defvar redit-select-command "47") -(defvar redit-register-command "49") -(defvar redit-deregister-command "51") -(defvar redit-quit-command "53") +(defvar redit-join-command "41") +(defvar redit-join-ack-command "42") +(defvar redit-get-command "43") +(defvar redit-get-ack-command "44") +(defvar redit-put-command "45") +(defvar redit-put-ack-command "46") +(defvar redit-select-command "47") +(defvar redit-select-ack-command "48") +(defvar redit-register-command "49") +(defvar redit-register-ack-command "50") +(defvar redit-deregister-command "51") +(defvar redit-deregister-ack-command "52") +(defvar redit-quit-command "53") +(defvar redit-quit-ack-command "54") (defun redit-client-start (host) "Allow this Emacs process to be a remote-edit client for client processes." @@ -117,13 +127,13 @@ (set-process-coding-system redit-client-process 'raw-text 'raw-text) (process-kill-without-query redit-client-process) - (make-local-hook 'before-change-functions) - (make-local-hook 'after-change-functions) + ; (make-local-hook 'before-change-functions) + ; (make-local-hook 'after-change-functions) ; FIXME ; concat my hostname this command? (process-send-string redit-client-process - (concat (format "%10d%10d%10d%10d%10d" (string-to-number redit-join-command) 0 (gen-seqno) 0 0)))) + (concat (format "%10d%10d%10d%10d%10d%10d" (string-to-number redit-join-command) 0 0 (gen-seqno) 0 0) "\n"))) (error "redit-client connection refused."))) ; (redit-get-command) @@ -140,17 +150,29 @@ "select session" (interactive "P") (if (setq session-name (read-string "session name:")) - (process-send-string - redit-client-process - (concat (format "%10d%10d%10d%10d%10d" (string-to-number redit-select-command) (string-to-number redit-client-editor-id) (gen-seqno) 0 0) - session-name)) + (progn + (setq redit-client-session-id (string-to-number session-name)) + (process-send-string + redit-client-process + (concat (format "%10d%10d%10d%10d%10d%10d" (string-to-number redit-select-command) redit-client-session-id redit-client-editor-id (gen-seqno) 0 0) session-name "\n")) + ) (error "invalid session name.") ) ) - (defun redit-put-command () - "put" - (interactive) + ;(defun redit-put-command () + ; "put" + ; (interactive) + ; ) + (defun redit-put-command (session-name) + "put session" + (interactive "P") + (if (setq session-name (read-string "put session name:")) + (process-send-string + redit-client-process + (concat (format "%10d%10d%10d%10d%10d%10d" (string-to-number redit-put-command) redit-client-session-id redit-client-editor-id (gen-seqno) 0 0) session-name "\n")) + (error "invalid session name.") + ) ) (defun redit-register-command (session-name) @@ -159,9 +181,7 @@ (if (setq session-name (read-string "session name:")) (process-send-string redit-client-process - ; FIXME "%10d%10d%10d%10d%10d" ? - (concat (format "%10d%10d%10d%10d%10d" (string-to-number redit-register-command) (string-to-number redit-client-editor-id) (gen-seqno) 0 0) - session-name)) + (concat (format "%10d%10d%10d%10d%10d%10d" (string-to-number redit-register-command) redit-client-session-id redit-client-editor-id (gen-seqno) 0 0) session-name "\n")) (error "invalid session name.") ) ) @@ -198,7 +218,7 @@ (progn (process-send-string redit-client-process - (format "%10d%10d%10d%10d%10d" (string-to-number redit-read-command) (string-to-number redit-client-editor-id) (gen-seqno) linenum 0)) + (format "%10d%10d%10d%10d%10d%10d\n" (string-to-number redit-read-command) redit-client-session-id redit-client-editor-id (gen-seqno) linenum 0)) (while (eq nil (accept-process-output redit-client-process))))) (error "redit-client is not running."))) @@ -220,12 +240,13 @@ ;の文字列を送る (process-send-string redit-client-process - (concat (format "%10d%10d%10d%10d%10d" (string-to-number redit-write-command) (string-to-number redit-client-editor-id) (gen-seqno) linenum length) + (concat (format "%10d%10d%10d%10d%10d%10d" (string-to-number redit-write-command) redit-client-session-id redit-client-editor-id (gen-seqno) linenum length) (buffer-substring beginp endp) (if (eq isnewline t) - "\n"))) - (while (eq nil - (accept-process-output redit-client-process 1))))) + "\n") "\n")) + ;(while (eq nil + ; (accept-process-output redit-client-process 1))))) + )) (error "redit-client is not running."))) ; linenum で指定した行の削除命令を redit-client-process に送信する @@ -235,9 +256,10 @@ ; write lines on server buffer (process-send-string redit-client-process - (concat (format "%10d%10d%10d%10d%10d" (string-to-number redit-delete-line-command) (string-to-number redit-client-editor-id) (gen-seqno) linenum 0))) - (while (eq nil - (accept-process-output redit-client-process 1)))) + (concat (format "%10d%10d%10d%10d%10d%10d" (string-to-number redit-delete-line-command) redit-client-session-id redit-client-editor-id (gen-seqno) linenum 0) "\n")) + ;(while (eq nil + ; (accept-process-output redit-client-process 1)))) + ) (error "redit-client is not running."))) ; redit-client-process へcloseコマンドを送る @@ -248,7 +270,7 @@ (redit-client-write-line line nil) (process-send-string redit-client-process - (concat (format "%10d%10d%10d%10d%10d" (string-to-number redit-close-command) (string-to-number redit-client-editor-id) (gen-seqno) linenum 0))))) + (concat (format "%10d%10d%10d%10d%10d%10d" (string-to-number redit-close-command) redit-client-session-id redit-client-editor-id (gen-seqno) linenum 0) "\n")))) ; redit-client-process を終了させる (defun redit-client-kill () @@ -269,83 +291,79 @@ 'redit-client-before-change-function t) (remove-hook 'after-change-functions 'redit-client-after-change-function t) - (message string) ;; add - (let ((command (string-to-number (rep-get-command-from-pkt string)))) + ; (message string) ;; add + (let ((command (rep-get-command-from-pkt string))) ;command がどの命令かを判断し、対応した処理をする。case みたい (cond ; FIXME - ((string-equal command (string-to-number redit-open-ack)) - (if (not redit-client-editor-id) - (redit-client-exec-open-ack string))) + ((if (= command (string-to-number redit-open-ack)) + (if (/= redit-client-editor-id) + (redit-client-exec-open-ack string)))) - ((string-equal command (string-to-number redit-read-ack)) - (if (= redit-client-editor-id - (string-to-number (rep-get-editor-id-from-pkt string))) - (redit-client-exec-read-ack string))) + ((if (= command (string-to-number redit-read-ack)) + (if (= redit-client-editor-id (rep-get-editor-id-from-pkt string)) + (redit-client-exec-read-ack string)))) - ((string-equal command (string-to-number redit-write-still-ack)) - (if (= redit-client-editor-id - (string-to-number (rep-get-editor-id-from-pkt string))) - (redit-client-exec-write-still-ack string))) + ((if (= command (string-to-number redit-write-still-ack)) + (if (= redit-client-editor-id (rep-get-editor-id-from-pkt string)) + (redit-client-exec-write-still-ack string)))) - ((string-equal command (string-to-number redit-delete-line-ack)) - (if (= redit-client-editor-id - (string-to-number (rep-get-editor-id-from-pkt string))) - (redit-client-exec-delete-line-ack string))) + ((if (= command (string-to-number redit-delete-line-ack)) + (if (= redit-client-editor-id (rep-get-editor-id-from-pkt string)) + (redit-client-exec-delete-line-ack string)))) - ((string-equal command (string-to-number redit-close-ack)) - (if (= redit-client-editor-id - (string-to-number (rep-get-editor-id-from-pkt string))) - (redit-client-exec-close-ack string))) + ((if (= command (string-to-number redit-close-ack)) + (if (= redit-client-editor-id (rep-get-editor-id-from-pkt string)) + (redit-client-exec-close-ack string)))) - ((string-equal command (string-to-number redit-write-command)) - (if (= redit-client-editor-id - (string-to-number (rep-get-editor-id-from-pkt string))) - (redit-client-exec-write-line string))) + ((if (= command (string-to-number redit-write-command)) + (if (/= redit-client-editor-id (rep-get-editor-id-from-pkt string)) + (redit-client-exec-write-line string)))) ; from Session Manager - ; join(editor id) - ; editor idを保存する - ((string-equal command (string-to-number redit-join-command)) - (if (= redit-client-editor-id - (string-to-number (rep-get-command-from-pkt string))) + + ; join ack (editor id) + ; editor id を保存する + ((if (= command (string-to-number redit-join-ack-command)) (redit-client-exec-join string))) - ; get - ((string-equal command (string-to-number redit-get-command)) - (if (= redit-client-editor-id - (string-to-number (rep-get-editor-id-from-pkt string))) - (redit-client-exec-get string))) - ; put - ((string-equal command (string-to-number redit-put-command)) - (if (= redit-client-editor-id - (string-to-number (rep-get-editor-id-from-pkt string))) + + ; put ack (editor id) + ; session id を保存する + ((if (= command (string-to-number redit-put-ack-command)) (redit-client-exec-put string))) - ; select - ((string-equal command (string-to-number redit-select-command)) - (if (= redit-client-editor-id - (string-to-number (rep-get-editor-id-from-pkt string))) - (redit-client-exec-select string))) + + ; select ack + ; TODO : start editing + ((if (= command (string-to-number redit-select-ack-command)) + (progn + (add-hook 'before-change-functions + 'redit-client-before-change-function t t) + (add-hook 'after-change-functions + 'redit-client-after-change-function t t)))) + + ; get + ((if (= command (string-to-number redit-get-command)) + (if (= redit-client-editor-id (rep-get-editor-id-from-pkt string)) + (redit-client-exec-get string)))) ; register - ((string-equal command (string-to-number redit-register-command)) - (if (= redit-client-editor-id - (string-to-number (rep-get-editor-id-from-pkt string))) - (redit-client-exec-register string))) + ((if (= command (string-to-number redit-register-command)) + (if (= redit-client-editor-id (rep-get-editor-id-from-pkt string)) + (redit-client-exec-register string)))) ; deregister - ((string-equal command (string-to-number redit-deregister-command)) - (if (= redit-client-editor-id - (string-to-number (rep-get-editor-id-from-pkt string))) - (redit-client-exec-deregister string))) + ((if (= command (string-to-number redit-deregister-command)) + (if (= redit-client-editor-id (rep-get-editor-id-from-pkt string)) + (redit-client-exec-deregister string)))) ; delete line - ((string-equal command (string-to-number redit-delete-line-command)) - (if (= redit-client-editor-id - (string-to-number (rep-get-editor-id-from-pkt string))) - (redit-server-exec-delete-line string))) + ((if (= command (string-to-number redit-delete-line-command)) + (if (= redit-client-editor-id (rep-get-editor-id-from-pkt string)) + (redit-server-exec-delete-line string)))) ((string-equal string "")))) - (add-hook 'before-change-functions - 'redit-client-before-change-function t t) - (add-hook 'after-change-functions - 'redit-client-after-change-function t t)) + ;(add-hook 'before-change-functions + ; 'redit-client-before-change-function t t) + ;(add-hook 'after-change-functions + ; 'redit-client-after-change-function t t) + ) ; window-scroll-functions に hook される。 ; window がスクロールする度に呼ばれる @@ -401,6 +419,7 @@ ; begin と end には変更前の変更部分の始まりと終わりの point が入る (defun redit-client-before-change-function (begin end) ; check delete + ; (message "call redit-client-before-change-function") (let ((beginl (real-count-lines begin)) ; begin の行番号 (endl (real-count-lines end)) ; end の行番号 (currline)) ; currline = nil @@ -420,6 +439,7 @@ ; begin と end には変更後の変更部分の始まりと終わりの point が入る (defun redit-client-after-change-function (begin end length) ; check insert + ; (message "call redit-client-after-change-function") (let ((beginl (real-count-lines begin)) (endl (real-count-lines end)) (currline)) @@ -435,7 +455,7 @@ ; 引き数で与えられた string (line_num + text_data) から ; 指定された行を削除し、そこに text_data を挿入する (defun redit-client-exec-write-line (string) - (let ((linenum (string-to-number (rep-get-line-number-from-pkt string))) ; 行番号 + (let ((linenum (rep-get-line-number-from-pkt string)) ; 行番号 (text (rep-get-text-from-pkt string))) ; テキストデータ (if (< (real-count-lines (point-max)) linenum) (progn @@ -448,7 +468,7 @@ ; 引き数 string (line_num + text_data) で指定された行を削除する (defun redit-client-exec-delete-line (string) - (let ((linenum (string-to-number (rep-get-line-number-from-pkt string)))) + (let ((linenum (rep-get-line-number-from-pkt string))) (goto-line linenum) ; 行頭から末尾までのテキストを削除 (delete-region (progn (beginning-of-line) (point)) @@ -462,8 +482,8 @@ ; 引き数 string (buf_num + line_num + text_data) (defun redit-client-exec-open-ack (string) (save-excursion - (let ((bufnum (string-to-number (rep-get-editor-id-from-pkt string))) - (linenum (string-to-number (rep-get-line-number-from-pkt string)))) + (let ((bufnum (rep-get-editor-id-from-pkt string)) + (linenum (rep-get-line-number-from-pkt string))) (make-variable-buffer-local 'redit-client-buffer-name) (make-variable-buffer-local 'redit-client-editor-id) (setq redit-client-buffer-name @@ -494,7 +514,7 @@ ; text_data を挿入する (defun redit-client-exec-read-ack (string) (save-excursion - (let ((lines (string-to-number (rep-get-line-number-from-pkt string)))) + (let ((lines (rep-get-line-number-from-pkt string))) ; redit-client-buffer をカレントバッファにする (set-buffer redit-client-buffer) (goto-line lines) @@ -507,13 +527,13 @@ (defun redit-client-exec-write-still-ack (string) (save-excursion (set-buffer redit-client-buffer) - (let ((linenum (string-to-number (rep-get-line-number-from-pkt string )))) + (let ((linenum (rep-get-line-number-from-pkt string ))) (setq redit-client-line-max-in-server linenum)))) (defun redit-client-exec-delete-line-ack (string) (save-excursion (set-buffer redit-client-buffer) - (let ((linenum (string-to-number (rep-get-line-number-from-pkt string)))) + (let ((linenum (rep-get-line-number-from-pkt string))) (setq redit-client-line-max-in-server linenum)))) ; プロセスとバッファ、ローカル変数を削除する @@ -524,12 +544,15 @@ (kill-buffer redit-client-buffer)) (kill-all-local-variables)) -; 引き数で与えられた string から Session IDを取得する +; 引き数で与えられた string から Editor IDを取得する (defun redit-client-exec-join (string) (setq redit-client-editor-id (rep-get-editor-id-from-pkt string)) - ; FIXME : open another buffer? (insert (rep-get-text-from-pkt string))) +; 引き数で与えられた string から Session IDを取得する +(defun redit-client-exec-put (string) + (setq redit-client-session-id (rep-get-session-id-from-pkt string))) + ; プロセスの状態を見て、対応したメッセージを表示 (defun redit-client-sentinel (proc msg) (cond ((eq (process-status proc) 'exit) @@ -543,13 +566,15 @@ (defun rep-get-command-from-pkt (pkt) (string-to-number (substring pkt 0 10))) -(defun rep-get-editor-id-from-pkt (pkt) +(defun rep-get-session-id-from-pkt (pkt) (string-to-number (substring pkt 10 20))) +(defun rep-get-editor-id-from-pkt (pkt) + (string-to-number (substring pkt 20 30))) (defun rep-get-sequence-id-from-pkt (pkt) - (string-to-number (substring pkt 20 30))) + (string-to-number (substring pkt 30 40))) (defun rep-get-line-number-from-pkt (pkt) - (string-to-number (substring pkt 30 40))) + (string-to-number (substring pkt 40 50))) (defun rep-get-text-size-from-pkt (pkt) - (string-to-number (substring pkt 40 50))) + (string-to-number (substring pkt 50 60))) (defun rep-get-text-from-pkt (pkt) - (substring pkt 50)) + (substring pkt 60))
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/redit_client.pl Tue Aug 08 07:49:12 2006 +0900 @@ -0,0 +1,109 @@ +#!/usr/bin/perl + +#use strict; + +use IO::Select; +use IO::Socket; +use Rep; + +if($ARGV[0] eq "") { + print "Usage: $0 SERVER_NAME\n"; + exit; +} + +# Rep.pm に移動する +sub HEADER_TOKEN_SIZ {10}; +sub EMACS_HEADER_SIZ {60}; +sub HEADER_CMD_POS {0}; +sub HEADER_SID_POS {1}; +sub HEADER_EID_POS {2}; +sub HEADER_SEQNO_POS {3}; +sub HEADER_LINENO_POS {4}; +sub HEADER_TEXTSIZ_POS {5}; + +my $peer_addr = $ARGV[0]; +my $peer_port = "8080"; +my $TIMEOUT = 0; + +# connect to the session manager +$sock = new IO::Socket::INET(PeerAddr => $peer_addr, + PeerPort => $peer_port, + Proto => 'tcp') or die("Cannot open socket : $!\n"); + +my $myeid; +my $mysid; +my $ack; +my $packet; + +my $sm_selector = new IO::Select($sock) or die "Cannot select socket : $!\n"; +my $stdin_selector = new IO::Select(\*STDIN) or die "Cannot select stdin : $!\n"; + +while(1){ + # message from remote editor client (STDIN) + if ($stdin_selector->can_read($TIMEOUT)) { + my $buffer = <STDIN>; + # TODO : + my $packet = &make_packet_from_emacs($buffer); + $sock->write($packet,length($packet)); + &debug_msg("send message is : ||" . $buffer . "||\n"); + } + + # message from session manager + if ($sm_selector->can_read($TIMEOUT)) { + my $sm_message = &read_and_unpack($sock); + + if($sm_message->{'cmd'} == SMCMD_JOIN_ACK){ + $myeid = $sm_message->{'eid'}; + &debug_msg("mysid is : " . $mysid . "\n"); + } + + if($sm_message->{'cmd'} == SMCMD_PUT_ACK){ + $mysid = $sm_message->{'sid'}; + &debug_msg("mysid is : " . $mysid . "\n"); + } + + if($sm_message->{'eid'} != $myeid or $sm_message->{'cmd'} == SMCMD_JOIN_ACK or $sm_message->{'cmd'} == SMCMD_PUT_ACK or $sm_message->{'cmd'} == SMCMD_SELECT_ACK){ + my $output = sprintf("%10d%10d%10d%10d%10d%10d" . $sm_message->{'text'}, + $sm_message->{'cmd'}, + $sm_message->{'sid'}, + $sm_message->{'eid'}, + $sm_message->{'seqno'}, + $sm_message->{'lineno'}, + $sm_message->{'textsiz'} + ); + syswrite(STDOUT,$output,length($output)); + &debug_msg("recv message is : ||" . $output . "||\n"); + } else { + &debug_msg("chop cmd : " . $sm_message->{'cmd'} . "\n"); + &debug_msg("chop eid : " . $sm_message->{'eid'} . "\n"); + } + } + +} + +sub make_packet_from_emacs { + # FIXME + my $buffer = shift; + return &make_packet( + &get_header_token($buffer, HEADER_CMD_POS), + &get_header_token($buffer, HEADER_SID_POS), + &get_header_token($buffer, HEADER_EID_POS), + &get_header_token($buffer, HEADER_SEQNO_POS), + &get_header_token($buffer, HEADER_LINENO_POS), + substr($buffer,&EMACS_HEADER_SIZ) + ); +} + +sub get_header_token { + my $buffer = shift; + my $pos = shift; + + return int(substr($buffer, &HEADER_TOKEN_SIZ * $pos, &HEADER_TOKEN_SIZ)); +} + +sub debug_msg { + my $msg = shift; + open(DEBUG,">> debug.txt"); + print DEBUG "eid $myeid : " . $msg; + close(DEBUG); +}