Mercurial > hg > xemacs-beta
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) |