comparison lisp/packages/gnuserv.el @ 193:f53b5ca2e663 r20-3b23

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