;;; server.el --- Lisp code for GNU Emacs running as server process.
-;; Copyright (C) 1986, 1987, 1992, 1994, 1995 Free Software Foundation, Inc.
+;; Copyright (C) 1986, 87, 92, 94, 95, 96, 1997 Free Software Foundation, Inc.
;; Author: William Sommerfeld <wesommer@athena.mit.edu>
+;; Maintainer: FSF
;; Keywords: processes
;; Changes by peck@sun.com and by rms.
;;; Code:
\f
-(defvar server-program (expand-file-name "emacsserver" exec-directory)
- "*The program to use as the edit server.")
-
-(defvar server-visit-hook nil
- "*List of hooks to call when visiting a file for the Emacs server.")
-
-(defvar server-switch-hook nil
- "*List of hooks to call when switching to a buffer for the Emacs server.")
-
-(defvar server-done-hook nil
- "*List of hooks to call when done editing a buffer for the Emacs server.")
+(defgroup server nil
+ "Emacs running as a server process."
+ :group 'external)
+
+(defcustom server-program (expand-file-name "emacsserver" exec-directory)
+ "*The program to use as the edit server."
+ :group 'server
+ :type 'string)
+
+(defcustom server-visit-hook nil
+ "*List of hooks to call when visiting a file for the Emacs server."
+ :group 'server
+ :type '(repeat function))
+
+(defcustom server-switch-hook nil
+ "*List of hooks to call when switching to a buffer for the Emacs server."
+ :group 'server
+ :type '(repeat function))
+
+(defcustom server-done-hook nil
+ "*List of hooks to call when done editing a buffer for the Emacs server."
+ :group 'server
+ :type '(repeat function))
(defvar server-process nil
"the current server process")
If nil, use the selected window.
If it is a frame, use the frame's selected window.")
-(defvar server-temp-file-regexp "^/tmp/Re\\|/draft$"
+(defcustom server-temp-file-regexp "^/tmp/Re\\|/draft$"
"*Regexp which should match filenames of temporary files
which are deleted and reused after each edit
-by the programs that invoke the emacs server.")
+by the programs that invoke the emacs server."
+ :group 'server
+ :type 'regexp)
(or (assq 'server-buffer-clients minor-mode-alist)
(setq minor-mode-alist (cons '(server-buffer-clients " Server") minor-mode-alist)))
(setq request (substring request (match-end 0)))
(while (string-match "[^ ]+ " request)
(let ((arg
- (substring request (match-beginning 0) (1- (match-end 0)))))
+ (substring request (match-beginning 0) (1- (match-end 0))))
+ (pos 0))
(setq request (substring request (match-end 0)))
(if (string-match "\\`-nowait" arg)
(setq nowait t)
;; ARG is a file name.
;; Collapse multiple slashes to single slashes.
(setq arg (command-line-normalize-file-name arg))
- (setq pos 0)
;; Undo the quoting that emacsclient does
;; for certain special characters.
(while (string-match "&." arg pos)
(set-buffer obuf))
(nconc client client-record)))
\f
-(defun server-buffer-done (buffer)
+(defun server-buffer-done (buffer &optional for-killing)
"Mark BUFFER as \"done\" for its client(s).
This buries the buffer, then returns a list of the form (NEXT-BUFFER KILLED).
NEXT-BUFFER is another server buffer, as a suggestion for what to select next,
(set-buffer buffer)
(setq server-buffer-clients nil)
(run-hooks 'server-done-hook))
- (if (server-temp-file-p buffer)
- (progn (kill-buffer buffer)
- (setq killed t))
- (bury-buffer buffer))))
+ (if for-killing
+ (if (server-temp-file-p buffer)
+ (progn (kill-buffer buffer)
+ (setq killed t))
+ (bury-buffer buffer)))))
(list next-buffer killed)))
(defun server-temp-file-p (buffer)
(buffer-backed-up nil))
(save-buffer))
(if (and (buffer-modified-p)
+ buffer-file-name
(y-or-n-p (concat "Save file " buffer-file-name "? ")))
(save-buffer buffer)))
(server-buffer-done buffer)))))
(yes-or-no-p "Server buffers still have clients; exit anyway? "))))
(add-hook 'kill-emacs-query-functions 'server-kill-emacs-query-function)
+
+(defvar server-kill-buffer-running nil
+ "Non-nil while `server-kill-buffer' is running.")
+
+;; When a buffer is killed, inform the clients.
+(add-hook 'kill-buffer-hook 'server-kill-buffer)
+(defun server-kill-buffer ()
+ ;; Prevent infinite recursion if user has made server-done-hook
+ ;; call kill-buffer.
+ (or server-kill-buffer-running
+ (let ((server-kill-buffer-running t))
+ (when server-process
+ (server-buffer-done (current-buffer) t)))))
\f
(defun server-edit (&optional arg)
"Switch to next server editing buffer; say \"Done\" for current buffer.