
(defconst gnuserv-rcs-header-id "$Header: /afs/sipb.mit.edu/project/sipbsrc/src/lib/elisp/gnuserv/RCS/gnuserv.el,v 1.1 92/05/24 02:13:46 ckclark Exp $")

(provide (quote gnuserv))

(defvar server-program "/usr/sipb/etc/gnuserv" "\
*The program to use as the edit server")

(defvar server-process nil "\
the current server process")

(defvar server-string "" "\
the last input string from the server")

(defvar current-client nil "\
the client we are currently talking to")

(defvar server-clients nil "\
List of current server clients.
Each element is (CLIENTID BUFFER...) where CLIENTID is an integer
that can be given to the server process to identify a client.
When a buffer is killed, it is removed from this list.")

(defvar server-buffer-clients nil "\
List of clientids for clients requesting editing of current buffer.")

(make-variable-buffer-local (quote server-buffer-clients))

(setq-default server-buffer-clients nil)

(or (assq (quote server-buffer-clients) minor-mode-alist) (setq minor-mode-alist (cons (quote (server-buffer-clients " Server")) minor-mode-alist)))

(defun server-log (string) "\
If a *server* buffer exists, write STRING to it for logging purposes." (byte-code "ÁÂ!… ŠÂqˆdbˆcˆn† Ã )‡" [string get-buffer "*server*" newline] 3))

(defun server-sentinel (proc msg) (byte-code "Á!Â=ƒ ÃÄÅ!!‚ Á!Æ=… ÃÄÇ!!‡" [proc process-status exit server-log message "Server subprocess exited" signal "Server subprocess killed"] 7))

(defun server-process-display-error (string) "\
When an error has been reported from the server, display the error in a
pop-up window." (byte-code "Ä ÂÅÆÇ!!ˆÈÄ `\"ˆÉ!ˆÊ!*‡" [cur pop-up-windows t string selected-window pop-to-buffer get-buffer-create "*server*" set-window-start server-log select-window] 8))

(defun server-process-filter (proc string) "\
Process incoming requests from the server for GNU Emacs to do some actions." (byte-code "	P‰ˆÄÅ\"…4 ÄÆ\"ƒ- Ç!ˆÈ!
@‰ˆÉÊË�ˆÌ‰)‚4 Í!ˆÌ‰‡" [server-string string header current-client string-match "
$" "^[0-9]+" server-log read-from-string oops (byte-code "ÂÃ	A\"@!‡" [server-string header eval read-from-string] 4) ((error (byte-code "Ä‰ˆÅ	
\"ˆÃ‰ˆÆ
@
A\"‡" [server-string current-client oops nil "" server-write-to-client signal] 4)) (quit (byte-code "Ä‰ˆÅ	
\"ˆÃ‰ˆÆÇÃ\"‡" [server-string current-client oops nil "" server-write-to-client signal quit] 4))) "" server-process-display-error] 7))

(defun server-release-outstanding-buffers nil "\
Release all buffers that have clients waiting for them to be finished." (interactive) (byte-code "Âˆ… Ã@8Ä	!)ˆ‚ ‡" [server-clients buffer nil 1 server-buffer-done] 3))

(defun server-start (&optional leave-dead) "\
Allow this Emacs process to be a server for client processes.
This starts a server communications subprocess through which
client \"editors\" can send editing commands to this Emacs job.

Prefix arg means just kill any existing server communications subprocess." (interactive "P") (byte-code "Áˆ… È ˆÉÁ\"ˆÁÊË�ˆ
ƒ Á‚F …$ ÌÍÎ!!ˆÏ‰ˆÁ‰ˆÆÐÑÁ#‰)ˆÉÒ\"ˆÓÔ\"ˆÕ!‡" [server-process nil leave-dead server-string current-client process-connection-type t server-program server-release-outstanding-buffers set-process-sentinel (byte-code "Á!‡" [server-process delete-process] 2) ((error (byte-code "À‡" [nil] 1))) server-log message "Restarting server" "" start-process "server" server-sentinel set-process-filter server-process-filter process-kill-without-query] 9))

(defun server-write-to-client (client form) "\
Write the given form to the given client via the server process." (byte-code "…	 Ä	!Å=… ÆÇ#È	
\"ˆÉ
!)‡" [client server-process s form process-status run format "%s:%s
" send-string server-log] 5))

(defun server-eval (form) "\
Evaluate form and return result to client." (byte-code "ÃÄ	!\"ˆÂ‰‡" [current-client form nil server-write-to-client eval] 4))

(defun server-eval-quickly (form) "\
Let client know that we've received the request, but eval the form
afterwards in order to not keep the client waiting." (byte-code "ÃÁ\"ˆÁ‰ˆÄ
!‡" [current-client nil form server-write-to-client eval] 3))

(defun server-make-window-visible nil "\
Try to make this window even more visible." (byte-code "ÂÀ!… ÂÁ!… Ã=… 	Ä=… ÅÆ!…# Æ ˆÇ ‡" [window-system window-system-version boundp x 11 fboundp x-remap-window accept-process-output] 6))

(defun server-find-file (file) "\
Edit file FILENAME.
Switch to a buffer visiting file FILENAME,
creating one if none already exists." (byte-code "Ä	!…
 qƒ6 Å	!ƒ' Æ!?† Ç!…$ ÈÂÃ\"‚3 ÉÊ	ËQ!…3 Ì	!‚: Í	!q)ˆÎp!‡" [obuf file t nil get-file-buffer file-exists-p verify-visited-file-modtime buffer-modified-p revert-buffer y-or-n-p "File no longer exists: " ", write buffer to file? " write-file find-file-noselect switch-to-buffer] 10))

(defun server-edit-files-quickly (l) "\
For each (lineno . file) pair in the given list, edit the file and goto the
given line number. Note that unlike server-edit-files, no information is saved
about clients waiting for this buffer to be killed." (byte-code "ÅÁ\"ˆÁ‰ˆÆ ˆ
…) 
@@
@AÇ!ˆÈ!*ˆ
A‰ˆ‚ ‡" [current-client nil l line path server-write-to-client server-make-window-visible server-find-file goto-line] 7))

(defun server-edit-files (l) "\
For each (lineno . file) pair in the given list, edit the given file for the
client and save enough information such that server-kill-buffer can let the client
know when the buffer has been finished with." (byte-code "È ˆ…G @@@AÉ
!ˆÊ\"pË	!ˆB‰ˆƒ4 ÌC\"‚< DB‰**ˆA‰ˆ‚ ˆÍÎÏ!!‡" [l line path old-clients current-client server-clients buffer server-buffer-clients server-make-window-visible server-find-file assq goto-line nconc message substitute-command-keys "When done with a buffer, type \\[server-edit]."] 8))

(defun server-get-buffer (buffer) "\
One arg, a string or a buffer. Return either a buffer object or
throw an error if the buffer named was not a buffer." (byte-code "?ƒ	 p‚& Â!	?ƒ$ ;ƒ ÃÄ\"‚! ÃÅ!‚% 	)‡" [buffer buf get-buffer error "No buffer named %s" "Invalid buffer argument"] 4))

(defun server-kill-buffer (buffer) "\
One arg, a string or a buffer.  Get rid of the specified buffer.
NOTE: This function has been enhanced to allow for remote editing
in the following way:

If the buffer is waited upon by one or more clients, and a client is
not waiting for other buffers to be killed, then the client is told
that the buffer has been killed." (interactive "bKill buffer ") (byte-code "ÃˆÅ!‰ˆÆ!…O Šqˆ
Ç!ˆÆ!ƒ\" Ã‚M 	…M 	@È\"ˆAƒ7 Ã‚C É@Ã\"ˆÈ
\"‰)ˆ	A‰ˆ‚\" ))‡" [buffer old-clients server-clients nil client server-get-buffer buffer-name server-real-kill-buffer delq server-write-to-client] 10))

(defun server-kill-all-local-variables nil "\
Eliminate all the buffer-local variable values of the current buffer.
This buffer will then see the default values of all variables.
NOTE: This function has been modified to ignore the variable 
server-buffer-clients." (byte-code "	Â ˆ… ‰)‡" [clients server-buffer-clients server-real-kill-all-local-variables] 3))

(or (fboundp (quote server-real-kill-buffer)) (fset (quote server-real-kill-buffer) (symbol-function (quote kill-buffer))))

(fset (quote kill-buffer) (quote server-kill-buffer))

(or (fboundp (quote server-real-kill-all-local-variables)) (fset (quote server-real-kill-all-local-variables) (symbol-function (quote kill-all-local-variables))))

(fset (quote kill-all-local-variables) (quote server-kill-all-local-variables))

(defun server-buffer-done (buffer) "\
Mark BUFFER as \"done\" for its client(s).
Buries the buffer, and returns another server buffer
as a suggestion for what to select next." (byte-code "Á
…; 
@† Ç>8‰ˆÈ\"ˆAƒ% Á‚1 É@Á\"ˆÈ\"‰)ˆ
A‰ˆ‚ ˆÊ!…K ŠqˆÁ‰)ˆË!ˆ*‡" [next-buffer nil old-clients server-clients client buffer server-buffer-clients 1 delq server-write-to-client buffer-name bury-buffer] 6))

(defun mh-draft-p (buffer) "\
Return non-nil if this BUFFER is an mh <draft> file.
Since MH deletes draft *BEFORE* it is edited, the server treats them specially." (byte-code "ÁÂ!Ã\"‡" [buffer string= buffer-name "draft"] 4))

(defun server-done nil "\
Offer to save current buffer, mark it as \"done\" for clients,
bury it, and return a suggested buffer to select next." (byte-code "p	…2 Ã!ƒ Ä ˆÅed
ÆP#ˆÇ!‚. È …( ÉÊ
ËQ!…. Ä!ˆÌ!)‡" [buffer server-buffer-clients buffer-file-name mh-draft-p save-buffer write-region "~" kill-buffer buffer-modified-p y-or-n-p "Save file " "? " server-buffer-done] 9))

(defun server-edit (&optional arg) "\
Switch to next server editing buffer; say \"Done\" for current buffer.
If a server buffer is current, it is marked \"done\" and optionally saved.
MH <draft> files are always saved and backed up, no questions asked.
When all of a client's buffers are marked as \"done\", the client is notified.

If invoked with a prefix argument, or if there is no server process running, 
starts server process and that is all.  Invoked by \\[server-edit]." (interactive "P") (byte-code "Âˆ† 	?† Ã	!Ä>ƒ ÅÂ!‚ ÆÇ !‡" [arg server-process nil process-status (signal exit) server-start server-switch-buffer server-done] 5))

(defun server-switch-buffer (next-buffer) "\
Switch to another buffer, preferably one that has a client.
Arg NEXT-BUFFER is a suggestion; if it is a live buffer, use it." (byte-code "ƒ Â!… Ã!ƒ Ä!‚ ÅÆ!!‚/ 	ƒ+ ÅÇ	@8!‚/ ÄÈ !‡" [next-buffer server-clients bufferp buffer-name switch-to-buffer server-switch-buffer server-buffer-done 1 other-buffer] 9))

(global-set-key "#" (quote server-edit))
