comparison lisp/packages/gnuserv.el @ 195:a2f645c6b9f8 r20-3b24

Import from CVS: tag r20-3b24
author cvs
date Mon, 13 Aug 2007 09:59:05 +0200
parents f53b5ca2e663
children acd284d43ca1
comparison
equal deleted inserted replaced
194:2947057885e5 195:a2f645c6b9f8
1 ;;; gnuserv.el --- Lisp interface code between Emacs and gnuserv 1 ;;; gnuserv.el --- Lisp interface code between Emacs and gnuserv
2 ;; Copyright (C) 1989-1997 Free Software Foundation, Inc. 2 ;; Copyright (C) 1989-1997 Free Software Foundation, Inc.
3 3
4 ;; Version: 3.10 4 ;; Version: 3.9
5 ;; Author: Andy Norman (ange@hplb.hpl.hp.com), originally based on server.el 5 ;; Author: Andy Norman (ange@hplb.hpl.hp.com), originally based on server.el
6 ;; Hrvoje Niksic <hniksic@srce.hr>, rewritten from scratch in May 1997 6 ;; Hrvoje Niksic <hniksic@srce.hr>
7 ;; Maintainer: Jan Vroonhof <vroonhof@math.ethz.ch>, 7 ;; Maintainer: Jan Vroonhof <vroonhof@math.ethz.ch>,
8 ;; Hrvoje Niksic <hniksic@srce.hr> 8 ;; Hrvoje Niksic <hniksic@srce.hr>
9 ;; Keywords: environment, processes, terminals 9 ;; Keywords: environment, processes, terminals
10 10
11 ;; This file is part of XEmacs. 11 ;; This file is part of XEmacs.
61 ;; ver William Sommerfeld's server.el. Since then, a number of people 61 ;; ver William Sommerfeld's server.el. Since then, a number of people
62 ;; have worked on it, including Bob Weiner, Darell Kindred, Arup 62 ;; have worked on it, including Bob Weiner, Darell Kindred, Arup
63 ;; Mukherjee, Ben Wing and Jan Vroonhof. It was completely rewritten 63 ;; Mukherjee, Ben Wing and Jan Vroonhof. It was completely rewritten
64 ;; (labeled as version 3) by Hrvoje Niksic in May 1997. 64 ;; (labeled as version 3) by Hrvoje Niksic in May 1997.
65 65
66 ;; Jan Vroonhof <vroonhof@math.ethz.ch> July/1996
67 ;; ported the server-temp-file-regexp feature from server.el
68 ;; ported server hooks from server.el
69 ;; ported kill-*-query functions from server.el (and made it optional)
70 ;; synced other behaviour with server.el
71 ;;
66 ;; Jan Vroonhof 72 ;; Jan Vroonhof
67 ;; Customized. 73 ;; Customized.
68 ;; 74 ;;
69 ;; Hrvoje Niksic <hniksic@srce.hr> May/1997 75 ;; Hrvoje Niksic <hniksic@srce.hr> May/1997
70 ;; Completely rewritten. Now uses `defstruct' and other CL stuff 76 ;; Completely rewritten. Now uses `defstruct' and other CL stuff
71 ;; to define clients cleanly. Many thanks to Dave Gillespie! 77 ;; to define clients cleanly. Many thanks to Dave Gillespie!
72 ;; 78 ;;
73 ;; Mike Scheidler <c23mts@eng.delcoelect.com> July, 1997 79 ;; Mike Scheidler <c23mts@eng.delcoelect.com> July, 1997
74 ;; Added 'Done' button to the menubar. 80 ;; Added 'Done' button to the menubar.
75 ;;
76 ;; Hrvoje Niksic <hniksic@srce.hr> Sep/1997
77 ;; More pervasive changes.
78 81
79 82
80 ;;; Code: 83 ;;; Code:
81 84
82 (defgroup gnuserv nil 85 (defgroup gnuserv nil
87 90
88 91
89 ;; Provide the old variables as aliases, to avoid breaking .emacs 92 ;; Provide the old variables as aliases, to avoid breaking .emacs
90 ;; files. However, they are obsolete and should be converted to the 93 ;; files. However, they are obsolete and should be converted to the
91 ;; new forms. This ugly crock must be before the variable 94 ;; new forms. This ugly crock must be before the variable
92 ;; declaration, or the scheme fails. I'd prefer if we could junk this 95 ;; declaration, or the scheme fails.
93 ;; sh*t, but I guess the users will appreciate compatibility. Uh...
94 96
95 (define-obsolete-variable-alias 'server-frame 'gnuserv-frame) 97 (define-obsolete-variable-alias 'server-frame 'gnuserv-frame)
96 (define-obsolete-variable-alias 'server-done-function 98 (define-obsolete-variable-alias 'server-done-function
97 'gnuserv-done-function) 99 'gnuserv-done-function)
98 (define-obsolete-variable-alias 'server-done-temp-file-function 100 (define-obsolete-variable-alias 'server-done-temp-file-function
105 'gnuserv-visit-hook) 107 'gnuserv-visit-hook)
106 (define-obsolete-variable-alias 'server-done-hook 108 (define-obsolete-variable-alias 'server-done-hook
107 'gnuserv-done-hook) 109 'gnuserv-done-hook)
108 (define-obsolete-variable-alias 'server-kill-quietly 110 (define-obsolete-variable-alias 'server-kill-quietly
109 'gnuserv-kill-quietly) 111 'gnuserv-kill-quietly)
112 (define-obsolete-variable-alias 'server-temp-file-regexp
113 'gnuserv-temp-file-regexp)
114 (define-obsolete-variable-alias 'server-make-temp-file-backup
115 'gnuserv-make-temp-file-backup)
110 116
111 ;;;###autoload 117 ;;;###autoload
112 (defcustom gnuserv-frame 'new 118 (defcustom gnuserv-frame nil
113 "*Determines what frame will be used to display all edited files. 119 "*The frame to be used to display all edited files.
114 Legal values are: 120 If nil, then a new frame is created for each file edited.
115 `new' -- a new frame will be created for each file edited; 121 If t, then the currently selected frame will be used.
116 `current' -- the currently selected frame will be used; 122 If a function, then this will be called with a symbol `x' or `tty' as the
117 `main' -- \"main\" Emacs frame will be used; 123 only argument, and its return value will be interpreted as above."
118 `visible' -- a visible frame will be used, or a new one created;
119 `special' -- a special Gnuserv frame will be created, and used for
120 all gnuserv-edited files;
121 frame -- that particular frame will be used.
122
123 If gnuclient is called using the `-nw' method (from a TTY device), the
124 behaviour will be as if gnuserv-frame were `new'.
125 This variable is read by `gnuserv-frame-default-function'. If you
126 change `gnuserv-frame-function' to anything else, this variable will
127 have no effect."
128 :tag "Gnuserv Frame" 124 :tag "Gnuserv Frame"
129 ;; Compatibility 125 :type '(radio (const :tag "Create new frame each time" nil)
130 :type '(radio (const :tag "Create new frame each time" new) 126 (const :tag "Use selected frame" t)
131 (const :tag "Use currently selected frame" current) 127 (function-item :tag "Use main Emacs frame"
132 (const :tag "Use main Emacs frame" main) 128 gnuserv-main-frame-function)
133 (const :tag "Use visible frame, otherwise create new" visible) 129 (function-item :tag "Use visible frame, otherwise create new"
134 (const :tag "Create special Gnuserv frame and use it" special)) 130 gnuserv-visible-frame-function)
135 :group 'gnuserv) 131 (function-item :tag "Create special Gnuserv frame and use it"
136 132 gnuserv-special-frame-function)
137 (defcustom gnuserv-frame-properties nil 133 (function :tag "Other"))
138 "*Properties of the frame in which gnuclient buffers are displayed. 134 :group 'gnuserv)
139 Note that this is in effect only for frames created by
140 `gnuserv-frame-default-function'."
141 :type '(repeat (group :inline t
142 (symbol :tag "Property")
143 (sexp :tag "Value")))
144 :group 'gnuserv)
145
146 (defcustom gnuserv-frame-function 'gnuserv-frame-default-function
147 "*Function to return the appropriate frame for use by gnuclient.
148 The function will be called with two arguments: the first one as
149 described by `gnuserv-frame', and the second one as the device to
150 create the frame on.
151 The function must return a valid frame object."
152 :type 'function
153 :group 'gnuserv)
154 135
155 (defcustom gnuserv-done-function 'kill-buffer 136 (defcustom gnuserv-done-function 'kill-buffer
156 "*Function used to remove a buffer after editing. 137 "*Function used to remove a buffer after editing.
157 It is called with one BUFFER argument. Functions such as `kill-buffer' and 138 It is called with one BUFFER argument. Functions such as `kill-buffer' and
158 `bury-buffer' are good values. See also `gnuserv-done-temp-file-function'." 139 `bury-buffer' are good values. See also `gnuserv-done-temp-file-function'."
159 :type '(radio (function-item kill-buffer) 140 :type '(radio (function-item kill-buffer)
160 (function-item bury-buffer) 141 (function-item bury-buffer)
161 (function :tag "Other")) 142 (function :tag "Other"))
162 :group 'gnuserv) 143 :group 'gnuserv)
163 144
145 (defcustom gnuserv-done-temp-file-function 'kill-buffer
146 "*Function used to remove a temporary buffer after editing.
147 It is called with one BUFFER argument. Functions such as `kill-buffer' and
148 `bury-buffer' are good values. See also `gnuserv-done-temp-file-function'."
149 :type '(radio (function-item kill-buffer)
150 (function-item bury-buffer)
151 (function :tag "Other"))
152 :group 'gnuserv)
153
164 (defcustom gnuserv-find-file-function 'find-file 154 (defcustom gnuserv-find-file-function 'find-file
165 "*Function to visit a file with. 155 "*Function to visit a file with.
166 It takes one argument, a file name to visit." 156 It takes one argument, a file name to visit."
167 :type 'function 157 :type 'function
168 :group 'gnuserv) 158 :group 'gnuserv)
202 :type 'hook 192 :type 'hook
203 :group 'gnuserv) 193 :group 'gnuserv)
204 194
205 (defcustom gnuserv-kill-quietly nil 195 (defcustom gnuserv-kill-quietly nil
206 "*Non-nil means to kill buffers with clients attached without requiring confirmation." 196 "*Non-nil means to kill buffers with clients attached without requiring confirmation."
197 :type 'boolean
198 :group 'gnuserv)
199
200 (defcustom gnuserv-temp-file-regexp "^/tmp/Re\\|/draft$"
201 "*Regexp which should match filenames of temporary files deleted
202 and reused by the programs that invoke the Emacs server."
203 :type 'regexp
204 :group 'gnuserv)
205
206 (defcustom gnuserv-make-temp-file-backup nil
207 "*Non-nil makes the server backup temporary files also."
207 :type 'boolean 208 :type 'boolean
208 :group 'gnuserv) 209 :group 'gnuserv)
209 210
210 211
211 ;;; Internal variables: 212 ;;; Internal variables:
227 (id nil) 228 (id nil)
228 (buffers nil) 229 (buffers nil)
229 (device nil) 230 (device nil)
230 (frame nil)) 231 (frame nil))
231 232
232 (defvar gnuserv-process nil 233 (defvar gnuserv-process nil
233 "The current gnuserv process.") 234 "The current gnuserv process.")
234 235
235 (defvar gnuserv-string "" 236 (defvar gnuserv-string ""
236 "The last input string from the server.") 237 "The last input string from the server.")
237 238
243 Each element is a gnuclient structure that identifies a client.") 244 Each element is a gnuclient structure that identifies a client.")
244 245
245 (defvar gnuserv-devices nil 246 (defvar gnuserv-devices nil
246 "List of devices created by clients.") 247 "List of devices created by clients.")
247 248
248 ;; We want the client-infested buffers to have some modeline
249 ;; identification, so we'll make a "minor mode". We don't use
250 ;; `add-minor-mode', as we don't want it to be togglable.
251 (defvar gnuserv-minor-mode nil)
252
253 (make-variable-buffer-local 'gnuserv-mode)
254 (pushnew '(gnuserv-minor-mode " Server") minor-mode-alist :test 'equal)
255
256 (defvar gnuserv-special-frame nil 249 (defvar gnuserv-special-frame nil
257 "Frame created specially for Server.") 250 "Frame created specially for Server.")
258 251
252 ;; We want the client-infested buffers to have some modeline
253 ;; identification, so we'll make a "minor mode".
254 (defvar gnuserv-minor-mode nil)
255 (make-variable-buffer-local 'gnuserv-mode)
256 (pushnew '(gnuserv-minor-mode " Server") minor-mode-alist
257 :test 'equal)
258
259 259
260 ;; Creating gnuserv frame. 260 ;; Sample gnuserv-frame functions
261 261
262 (defun gnuserv-frame-default-function (arg device) 262 (defun gnuserv-main-frame-function (type)
263 "Default function to create Gnuserv frames. 263 "Returns a sensible value for the main Emacs frame."
264 See the documentation of `gnuserv-frame' for instructions how to 264 (if (eq type 'x)
265 customize it." 265 (car (frame-list))
266 ;; If we are on TTY, act as if `new' was given. 266 nil))
267 (if (not (device-on-window-system-p)) 267
268 (gnuserv-frame-default-function 'new device) 268 (defun gnuserv-visible-frame-function (type)
269 (cond 269 "Returns a frame if there is a frame that is truly visible, nil otherwise.
270 ((or (eq arg 'new) 270 This is meant in the X sense, so it will not return frames that are on another
271 ;; nil for back-compat 271 visual screen. Totally visible frames are preferred. If none found, return nil."
272 (eq arg nil)) 272 (if (eq type 'x)
273 (make-frame gnuserv-frame-properties device)) 273 (cond ((car (filtered-frame-list 'frame-totally-visible-p
274 ((or (eq arg 'current) 274 (selected-device))))
275 ;; t for back-compat 275 ((car (filtered-frame-list (lambda (frame)
276 (eq arg t)) 276 ;; eq t as in not 'hidden
277 (selected-frame)) 277 (eq t (frame-visible-p frame)))
278 ((eq arg 'main) 278 (selected-device)))))
279 (car (frame-list))) 279 nil))
280 ((eq arg 'visible) 280
281 (cond ((car (filtered-frame-list 'frame-totally-visible-p device))) 281 (defun gnuserv-special-frame-function (type)
282 ((car (filtered-frame-list (lambda (frame) 282 "Creates a special frame for Gnuserv and returns it on later invocations."
283 ;; eq t as in not 'hidden 283 (unless (frame-live-p gnuserv-special-frame)
284 (eq (frame-visible-p frame) t)) 284 (setq gnuserv-special-frame (make-frame)))
285 device))) 285 gnuserv-special-frame)
286 (t (make-frame gnuserv-frame-properties device))))
287 ((eq arg 'special)
288 (unless (frame-live-p gnuserv-special-frame)
289 (setq gnuserv-special-frame
290 (make-frame gnuserv-frame-properties device))))
291 ((frame-live-p arg)
292 arg)
293 (t
294 (error "Invalid argument %s" arg)))))
295 286
296 287
297 ;;; Communication functions 288 ;;; Communication functions
298 289
299 ;; We used to restart the server here, but it's too risky -- if 290 ;; We used to restart the server here, but it's too risky -- if
409 (quick (setq quick t)) 400 (quick (setq quick t))
410 (view (setq view t)) 401 (view (setq view t))
411 (t (error "Invalid flag %s" flag)))) 402 (t (error "Invalid flag %s" flag))))
412 flags) 403 flags)
413 (let* ((old-device-num (length (device-list))) 404 (let* ((old-device-num (length (device-list)))
414 (old-frame-num (length (frame-list))) 405 (new-frame nil)
415 (device (case (car type) 406 (dest-frame (if (functionp gnuserv-frame)
407 (funcall gnuserv-frame (car type))
408 gnuserv-frame))
409 ;; The gnuserv-frame dependencies are ugly.
410 (device (cond ((frame-live-p dest-frame)
411 (frame-device dest-frame))
412 ((null dest-frame)
413 (case (car type)
416 (tty (apply 'make-tty-device (cdr type))) 414 (tty (apply 'make-tty-device (cdr type)))
417 (x (make-x-device (cadr type))) 415 (x (make-x-device (cadr type)))
418 (t (error "Invalid device type")))) 416 (t (error "Invalid device type"))))
419 (frame (funcall gnuserv-frame-function gnuserv-frame device)) 417 (t
418 (selected-device))))
419 (frame (cond ((frame-live-p dest-frame)
420 dest-frame)
421 ((null dest-frame)
422 (setq new-frame (make-frame nil device))
423 new-frame)
424 (t (selected-frame))))
420 (client (make-gnuclient :id gnuserv-current-client 425 (client (make-gnuclient :id gnuserv-current-client
421 :device device 426 :device device
422 :frame (if (= (length (frame-list)) 427 :frame new-frame)))
423 old-frame-num)
424 nil frame))))
425 (setq gnuserv-current-client nil) 428 (setq gnuserv-current-client nil)
426 ;; If the device was created by this client, push it to the list. 429 ;; If the device was created by this client, push it to the list.
427 (and (/= old-device-num (length (device-list))) 430 (and (/= old-device-num (length (device-list)))
428 (push device gnuserv-devices)) 431 (push device gnuserv-devices))
429 (and (frame-iconified-p frame) 432 (and (frame-iconified-p frame)
430 (deiconify-frame frame)) 433 (deiconify-frame frame))
431 ;; Visit all the listed files. 434 ;; Visit all the listed files.
432 (while list 435 (while list
433 (let ((line (caar list)) (path (cdar list))) 436 (let ((line (caar list)) (path (cdar list)))
434 (select-frame frame) 437 (select-frame frame)
435 (raise-frame frame)
436 ;; Visit the file. 438 ;; Visit the file.
437 (funcall (if view 439 (funcall (if view
438 gnuserv-view-file-function 440 gnuserv-view-file-function
439 gnuserv-find-file-function) 441 gnuserv-find-file-function)
440 path) 442 path)
442 ;; Don't memorize the quick and view buffers. 444 ;; Don't memorize the quick and view buffers.
443 (unless (or quick view) 445 (unless (or quick view)
444 (pushnew (current-buffer) (gnuclient-buffers client)) 446 (pushnew (current-buffer) (gnuclient-buffers client))
445 (setq gnuserv-minor-mode t) 447 (setq gnuserv-minor-mode t)
446 ;; Add the "Done" button to the menubar, only in this buffer. 448 ;; Add the "Done" button to the menubar, only in this buffer.
447 (when (boundp 'current-menubar) 449 (if (boundp 'current-menubar)
448 (set-buffer-menubar current-menubar) 450 (progn (set-buffer-menubar current-menubar)
449 (add-menu-button nil ["Done" gnuserv-edit t]))) 451 (add-menu-button nil ["Done" gnuserv-edit t]))
452 ))
450 (run-hooks 'gnuserv-visit-hook) 453 (run-hooks 'gnuserv-visit-hook)
451 (pop list))) 454 (pop list)))
452 (cond 455 (cond
453 ((and (or quick view) 456 ((and (or quick view)
454 (device-on-window-system-p device)) 457 (device-on-window-system-p device))
458 ;; should be unique. 461 ;; should be unique.
459 (gnuserv-write-to-client (gnuclient-id client) nil)) 462 (gnuserv-write-to-client (gnuclient-id client) nil))
460 (t 463 (t
461 ;; Else, the client gets a vote. 464 ;; Else, the client gets a vote.
462 (push client gnuserv-clients) 465 (push client gnuserv-clients)
463 ;; Explain buffer exit options. If client-frame is non-nil, 466 ;; Explain buffer exit options. If dest-frame is nil, the
464 ;; the user can exit via `delete-frame'. OTOH, if FLAGS are 467 ;; user can exit via `delete-frame'. OTOH, if FLAGS are nil
465 ;; nil and there are some buffers, the user can exit via 468 ;; and there are some buffers, the user can exit via
466 ;; `gnuserv-edit'. 469 ;; `gnuserv-edit'.
467 (if (and (not (or quick view)) 470 (if (and (not (or quick view))
468 (gnuclient-buffers client)) 471 (gnuclient-buffers client))
469 (message "%s" 472 (message "%s"
470 (substitute-command-keys 473 (substitute-command-keys
471 "Type `\\[gnuserv-edit]' to finish editing")) 474 "Type `\\[gnuserv-edit]' to finish editing"))
472 (and (gnuclient-frame client) 475 (or dest-frame
473 (message "%s" 476 (message "%s"
474 (substitute-command-keys 477 (substitute-command-keys
475 "Type `\\[delete-frame]' to finish editing"))))))))) 478 "Type `\\[delete-frame]' to finish editing")))))))))
476 479
477 480
478 ;;; Functions that hook into Emacs in various way to enable operation 481 ;;; Functions that hook into Emacs in various way to enable operation
479 482
480 ;; Defined later. 483 ;; Defined later.
484 ;; possible, because it is slow, and conses a list. Use 487 ;; possible, because it is slow, and conses a list. Use
485 ;; `gnuserv-buffer-p' when appropriate, for instance. 488 ;; `gnuserv-buffer-p' when appropriate, for instance.
486 (defun gnuserv-buffer-clients (buffer) 489 (defun gnuserv-buffer-clients (buffer)
487 "Returns a list of clients to which BUFFER belongs." 490 "Returns a list of clients to which BUFFER belongs."
488 (let (res) 491 (let (res)
489 (dolist (client gnuserv-clients res) 492 (dolist (client gnuserv-clients)
490 (when (memq buffer (gnuclient-buffers client)) 493 (when (memq buffer (gnuclient-buffers client))
491 (push client res))))) 494 (push client res)))
495 res))
492 496
493 ;; Like `gnuserv-buffer-clients', but returns a boolean; doesn't 497 ;; Like `gnuserv-buffer-clients', but returns a boolean; doesn't
494 ;; collect a list. 498 ;; collect a list.
495 (defun gnuserv-buffer-p (buffer) 499 (defun gnuserv-buffer-p (buffer)
496 (member* buffer gnuserv-clients 500 (member* buffer gnuserv-clients
546 ;; error when `delete-device' tries to do the job later. 550 ;; error when `delete-device' tries to do the job later.
547 (gnuserv-kill-client client t)))) 551 (gnuserv-kill-client client t))))
548 (callf2 delq device gnuserv-devices)) 552 (callf2 delq device gnuserv-devices))
549 553
550 (add-hook 'delete-device-hook 'gnuserv-check-device) 554 (add-hook 'delete-device-hook 'gnuserv-check-device)
555
556 (defun gnuserv-temp-file-p (buffer)
557 "Return non-nil if BUFFER contains a file considered temporary.
558 These are files whose names suggest they are repeatedly
559 reused to pass information to another program.
560
561 The variable `gnuserv-temp-file-regexp' controls which filenames
562 are considered temporary."
563 (and (buffer-file-name buffer)
564 (string-match gnuserv-temp-file-regexp (buffer-file-name buffer))))
551 565
552 (defun gnuserv-kill-client (client &optional leave-frame) 566 (defun gnuserv-kill-client (client &optional leave-frame)
553 "Kill the gnuclient CLIENT. 567 "Kill the gnuclient CLIENT.
554 This will do away with all the associated buffers. If LEAVE-FRAME, 568 This will do away with all the associated buffers. If LEAVE-FRAME,
555 the function will not remove the frames associated with the client." 569 the function will not remove the frames associated with the client."
592 (run-hooks 'gnuserv-done-hook) 606 (run-hooks 'gnuserv-done-hook)
593 (setq gnuserv-minor-mode nil) 607 (setq gnuserv-minor-mode nil)
594 ;; Delete the menu button. 608 ;; Delete the menu button.
595 (if (boundp 'current-menubar) 609 (if (boundp 'current-menubar)
596 (delete-menu-item '("Done"))) 610 (delete-menu-item '("Done")))
597 (funcall gnuserv-done-function buffer))) 611 (funcall (if (gnuserv-temp-file-p buffer)
612 gnuserv-done-temp-file-function
613 gnuserv-done-function)
614 buffer)))
598 615
599 616
600 ;;; Higher-level functions 617 ;;; Higher-level functions
601 618
602 ;; Choose a `next' server buffer, according to several criteria, and 619 ;; Choose a `next' server buffer, according to several criteria, and
631 Does the save/backup queries first, and calls `gnuserv-done-function'." 648 Does the save/backup queries first, and calls `gnuserv-done-function'."
632 ;; Check whether this is the real thing. 649 ;; Check whether this is the real thing.
633 (unless (gnuserv-buffer-p buffer) 650 (unless (gnuserv-buffer-p buffer)
634 (error "%s does not belong to a gnuserv client" buffer)) 651 (error "%s does not belong to a gnuserv client" buffer))
635 ;; Backup/ask query. 652 ;; Backup/ask query.
636 (if (and (buffer-modified-p) 653 (if (gnuserv-temp-file-p buffer)
637 (y-or-n-p (concat "Save file " buffer-file-name "? "))) 654 ;; For a temp file, save, and do NOT make a non-numeric backup
638 (save-buffer buffer)) 655 ;; Why does server.el explicitly back up temporary files?
656 (let ((version-control nil)
657 (buffer-backed-up (not gnuserv-make-temp-file-backup)))
658 (save-buffer))
659 (if (and (buffer-modified-p)
660 (y-or-n-p (concat "Save file " buffer-file-name "? ")))
661 (save-buffer buffer)))
639 (gnuserv-buffer-done-1 buffer)) 662 (gnuserv-buffer-done-1 buffer))
640 663
641 ;; Called by `gnuserv-start-1' to clean everything. Hooked into 664 ;; Called by `gnuserv-start-1' to clean everything. Hooked into
642 ;; `kill-emacs-hook', too. 665 ;; `kill-emacs-hook', too.
643 (defun gnuserv-kill-all-clients () 666 (defun gnuserv-kill-all-clients ()
690 (not (not gnuserv-process))) 713 (not (not gnuserv-process)))
691 714
692 ;;;###autoload 715 ;;;###autoload
693 (defun gnuserv-start (&optional leave-dead) 716 (defun gnuserv-start (&optional leave-dead)
694 "Allow this Emacs process to be a server for client processes. 717 "Allow this Emacs process to be a server for client processes.
695 This starts a gnuserv communications subprocess through which 718 This starts a gnuserv communications subprocess through which
696 client \"editors\" (gnuclient and gnudoit) can send editing commands to 719 client \"editors\" (gnuclient and gnudoit) can send editing commands to
697 this Emacs job. See the gnuserv(1) manual page for more details. 720 this Emacs job. See the gnuserv(1) manual page for more details.
721
698 Prefix arg means just kill any existing server communications subprocess." 722 Prefix arg means just kill any existing server communications subprocess."
699 (interactive "P") 723 (interactive "P")
700 (and gnuserv-process 724 (and gnuserv-process
701 (not leave-dead) 725 (not leave-dead)
702 (message "Restarting gnuserv")) 726 (message "Restarting gnuserv"))
703 (gnuserv-start-1 leave-dead)) 727 (gnuserv-start-1 leave-dead))
704 728
705 (defun gnuserv-edit (&optional count) 729 (defun gnuserv-edit (&optional count)
706 "Mark the current gnuserv buffer as \"done\", and switch to next one. 730 "Mark the current gnuserv editing buffer as \"done\", and switch to next one.
731
707 Run with a numeric prefix argument, repeat the operation that number 732 Run with a numeric prefix argument, repeat the operation that number
708 of times. If given a universal prefix argument, close all the buffers 733 of times. If given a universal prefix argument, close all the buffers
709 of this buffer's clients. 734 of this buffer's clients.
710 The `gnuserv-done-function' (`kill-buffer' by default) is called to 735
711 dispose of the buffer after marking it as done. 736 The `gnuserv-done-function' (bound to `kill-buffer' by default) is
712 When all of a client's buffers are marked as \"done\", the client is 737 called to dispose of the buffer after marking it as done.
713 notified." 738
739 Files that match `gnuserv-temp-file-regexp' are considered temporary and
740 are saved unconditionally and backed up if `gnuserv-make-temp-file-backup'
741 is non-nil. They are disposed of using `gnuserv-done-temp-file-function'
742 (also bound to `kill-buffer' by default).
743
744 When all of a client's buffers are marked as \"done\", the client is notified."
714 (interactive "P") 745 (interactive "P")
715 (when (null count) 746 (when (null count)
716 (setq count 1)) 747 (setq count 1))
717 (cond ((numberp count) 748 (cond ((numberp count)
718 (let (next) 749 (let (next)