X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/8226e01e77fb265751284d74f9a90e72229c951e..cd30a521aa838f6bcf08ee6ffb62986cd2bf8daa:/lisp/server.el diff --git a/lisp/server.el b/lisp/server.el index 78f10f422d..5a8720e377 100644 --- a/lisp/server.el +++ b/lisp/server.el @@ -1,8 +1,9 @@ ;;; 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 +;; Maintainer: FSF ;; Keywords: processes ;; Changes by peck@sun.com and by rms. @@ -74,17 +75,29 @@ ;;; Code: -(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") @@ -108,10 +121,12 @@ When a buffer is marked as \"done\", it is removed from this list.") 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))) @@ -280,11 +295,12 @@ so don't mark these buffers specially, just visit them normally." (set-buffer obuf)) (nconc client client-record))) -(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, -or nil. KILLED is t if we killed BUFFER (because it was a temp file)." +or nil. KILLED is t if we killed BUFFER +\(typically, because it was visiting a temp file)." (let ((running (eq (process-status server-process) 'run)) (next-buffer nil) (killed nil) @@ -317,15 +333,24 @@ or nil. KILLED is t if we killed BUFFER (because it was a temp file)." (setq server-clients (delq client server-clients)))) (setq old-clients (cdr old-clients))) (if (and (bufferp buffer) (buffer-name buffer)) - (progn + ;; We may or may not kill this buffer; + ;; if we do, do not call server-buffer-done recursively + ;; from kill-buffer-hook. + (let ((server-kill-buffer-running t)) (save-excursion (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)))) + ;; Notice whether server-done-hook killed the buffer. + (if (null (buffer-name buffer)) + (setq killed t) + ;; Don't bother killing or burying the buffer + ;; when we are called from kill-buffer. + (unless 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) @@ -342,7 +367,8 @@ are considered temporary." "Offer to save current buffer, mark it as \"done\" for clients. 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, -or nil. KILLED is t if we killed the BUFFER (because it was a temp file)." +or nil. KILLED is t if we killed BUFFER +\(typically, because it was visiting a temp file)." (let ((buffer (current-buffer))) (if server-buffer-clients (progn @@ -353,6 +379,7 @@ or nil. KILLED is t if we killed the BUFFER (because it was a temp file)." (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))))) @@ -381,6 +408,20 @@ or nil. KILLED is t if we killed the BUFFER (because it was a temp file)." (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' or `server-buffer-done' 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 + (and server-buffer-clients + (let ((server-kill-buffer-running t)) + (when server-process + (server-buffer-done (current-buffer) t)))))) (defun server-edit (&optional arg) "Switch to next server editing buffer; say \"Done\" for current buffer.