(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.")
+
(defvar server-process nil
"the current server process")
(defvar server-clients nil
"List of current server clients.
-Each element is (CLIENTID FILES...) where CLIENTID is a string
+Each element is (CLIENTID BUFFERS...) where CLIENTID is a string
that can be given to the server process to identify a client.
When a buffer is marked as \"done\", it is removed from this list.")
"Allow this Emacs process to be a server for client processes.
This starts a server communications subprocess through which
client \"editors\" can send your editing commands to this Emacs job.
-To use the server, set up the program `etc/emacsclient' in the
+To use the server, set up the program `emacsclient' in the
Emacs distribution as your standard \"editor\".
Prefix arg means just kill any existing server communications subprocess."
(set-process-sentinel server-process nil)
(condition-case () (delete-process server-process) (error nil))))
(condition-case () (delete-file "~/.emacs_server") (error nil))
+ (condition-case ()
+ (delete-file (format "/tmp/esrv%d-%s" (user-uid) (system-name)))
+ (error nil))
;; If we already had a server, clear out associated status.
(while server-clients
(let ((buffer (nth 1 (car server-clients))))
nil
(if server-process
(server-log (message "Restarting server")))
- (setq server-process (start-process "server" nil server-program))
+ ;; Using a pty is wasteful, and the separate session causes
+ ;; annoyance sometimes (some systems kill idle sessions).
+ (let ((process-connection-type nil))
+ (setq server-process (start-process "server" nil server-program)))
(set-process-sentinel server-process 'server-sentinel)
(set-process-filter server-process 'server-process-filter)
(process-kill-without-query server-process)))
(defun server-visit-files (files client)
"Finds FILES and returns the list CLIENT with the buffers nconc'd.
FILES is an alist whose elements are (FILENAME LINENUMBER)."
- (let (client-record (obuf (current-buffer)))
+ ;; Bind last-nonmenu-event to force use of keyboard, not mouse, for queries.
+ (let (client-record (last-nonmenu-event t) (obuf (current-buffer)))
;; Restore the current buffer afterward, but not using save-excursion,
;; because we don't want to save point in this buffer
;; if it happens to be one of those specified by the server.
(progn
(save-excursion
(set-buffer buffer)
- (setq server-buffer-clients nil))
- (bury-buffer buffer)))
+ (setq server-buffer-clients nil)
+ (run-hooks 'server-done-hook))
+ (if (server-temp-file-p buffer)
+ (kill-buffer buffer)
+ (bury-buffer buffer))))
next-buffer))
(defun server-temp-file-p (buffer)
Then bury it, and return a suggested buffer to select next."
(let ((buffer (current-buffer)))
(if server-buffer-clients
- (let (suggested-buffer)
+ (progn
(if (server-temp-file-p buffer)
;; For a temp file, save, and do make a non-numeric backup
;; (unless make-backup-files is nil).
(let ((version-control nil)
(buffer-backed-up nil))
- (save-buffer)
- (kill-buffer buffer)
- (setq suggested-buffer (current-buffer)))
+ (save-buffer))
(if (and (buffer-modified-p)
(y-or-n-p (concat "Save file " buffer-file-name "? ")))
(save-buffer buffer)))
- (or (server-buffer-done buffer) suggested-buffer)))))
+ (server-buffer-done buffer)))))
;; If a server buffer is killed, release its client.
;; I'm not sure this is really a good idea--do you want the client
'server-kill-buffer-query-function)
(defun server-kill-emacs-query-function ()
- (or (not server-clients)
- (yes-or-no-p "Server buffers still have clients; exit anyway? ")))
+ (let (live-client
+ (tail server-clients))
+ ;; See if any clients have any buffers that are still alive.
+ (while tail
+ (if (memq t (mapcar 'stringp (mapcar 'buffer-name (cdr (car tail)))))
+ (setq live-client t))
+ (setq tail (cdr tail)))
+ (or (not live-client)
+ (yes-or-no-p "Server buffers still have clients; exit anyway? "))))
(add-hook 'kill-emacs-query-functions 'server-kill-emacs-query-function)
\f