(tar-extract): Use kill-buffer-if-not-modified as
[bpt/emacs.git] / lisp / server.el
CommitLineData
55535639 1;;; server.el --- Lisp code for GNU Emacs running as server process
c88ab9ce 2
0d30b337 3;; Copyright (C) 1986, 1987, 1992, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
f86228e3 4;; 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
6d74b528 5
630cc463 6;; Author: William Sommerfeld <wesommer@athena.mit.edu>
e4874521 7;; Maintainer: FSF
d7b4d18f 8;; Keywords: processes
630cc463 9
9ae0f972 10;; Changes by peck@sun.com and by rms.
35dfa9b6 11;; Overhaul by Karoly Lorentey <lorentey@elte.hu> for multi-tty support.
9ae0f972 12
13;; This file is part of GNU Emacs.
14
15;; GNU Emacs is free software; you can redistribute it and/or modify
16;; it under the terms of the GNU General Public License as published by
b4aa6026 17;; the Free Software Foundation; either version 3, or (at your option)
9ae0f972 18;; any later version.
19
20;; GNU Emacs is distributed in the hope that it will be useful,
21;; but WITHOUT ANY WARRANTY; without even the implied warranty of
22;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23;; GNU General Public License for more details.
24
25;; You should have received a copy of the GNU General Public License
b578f267 26;; along with GNU Emacs; see the file COPYING. If not, write to the
086add15
LK
27;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
28;; Boston, MA 02110-1301, USA.
9ae0f972 29
630cc463 30;;; Commentary:
9ae0f972 31
b578f267
EN
32;; This Lisp code is run in Emacs when it is to operate as
33;; a server for other processes.
9ae0f972 34
b578f267 35;; Load this library and do M-x server-edit to enable Emacs as a server.
44a56b29
SM
36;; Emacs opens up a socket for communication with clients. If there are no
37;; client buffers to edit, server-edit acts like (switch-to-buffer
38;; (other-buffer))
9ae0f972 39
b578f267
EN
40;; When some other program runs "the editor" to edit a file,
41;; "the editor" can be the Emacs client program ../lib-src/emacsclient.
42;; This program transmits the file names to Emacs through
43;; the server subprocess, and Emacs visits them and lets you edit them.
9ae0f972 44
6d3a46f7 45;; Note that any number of clients may dispatch files to Emacs to be edited.
9ae0f972 46
b578f267 47;; When you finish editing a Server buffer, again call server-edit
64f51134
JPW
48;; to mark that buffer as done for the client and switch to the next
49;; Server buffer. When all the buffers for a client have been edited
b578f267 50;; and exited with server-edit, the client "editor" will return
64f51134 51;; to the program that invoked it.
9ae0f972 52
b578f267
EN
53;; Your editing commands and Emacs's display output go to and from
54;; the terminal in the usual way. Thus, server operation is possible
55;; only when Emacs can talk to the terminal at the time you invoke
56;; the client. This is possible in four cases:
9ae0f972 57
b578f267
EN
58;; 1. On a window system, where Emacs runs in one window and the
59;; program that wants to use "the editor" runs in another.
9ae0f972 60
b578f267
EN
61;; 2. On a multi-terminal system, where Emacs runs on one terminal and the
62;; program that wants to use "the editor" runs on another.
9ae0f972 63
b578f267
EN
64;; 3. When the program that wants to use "the editor" is running
65;; as a subprocess of Emacs.
9ae0f972 66
b578f267
EN
67;; 4. On a system with job control, when Emacs is suspended, the program
68;; that wants to use "the editor" will stop and display
69;; "Waiting for Emacs...". It can then be suspended, and Emacs can be
70;; brought into the foreground for editing. When done editing, Emacs is
71;; suspended again, and the client program is brought into the foreground.
9ae0f972 72
64f51134
JPW
73;; The buffer local variable "server-buffer-clients" lists
74;; the clients who are waiting for this buffer to be edited.
b578f267
EN
75;; The global variable "server-clients" lists all the waiting clients,
76;; and which files are yet to be edited for each.
630cc463 77
0acb1916
SM
78;; Todo:
79
80;; - handle command-line-args-left.
81;; - move most of the args processing and decision making from emacsclient.c
82;; to here.
83;; - fix up handling of the client's environment (place it in the terminal?).
84
630cc463 85;;; Code:
8b3e840e
SM
86
87(eval-when-compile (require 'cl))
88
ab1c7f35
RS
89(defgroup server nil
90 "Emacs running as a server process."
91 :group 'external)
92
337e3c70
JB
93(defcustom server-use-tcp nil
94 "If non-nil, use TCP sockets instead of local sockets."
95 :set #'(lambda (sym val)
96 (unless (featurep 'make-network-process '(:family local))
97 (setq val t)
98 (unless load-in-progress
99 (message "Local sockets unsupported, using TCP sockets")))
100 (when val (random t))
101 (set-default sym val))
102 :group 'server
103 :type 'boolean
104 :version "22.1")
105
106(defcustom server-host nil
107 "The name or IP address to use as host address of the server process.
108If set, the server accepts remote connections; otherwise it is local."
109 :group 'server
110 :type '(choice
111 (string :tag "Name or IP address")
112 (const :tag "Local" nil))
113 :version "22.1")
114(put 'server-host 'risky-local-variable t)
115
0eee7a1d 116(defcustom server-auth-dir (concat user-emacs-directory "server/")
337e3c70
JB
117 "Directory for server authentication files."
118 :group 'server
119 :type 'directory
120 :version "22.1")
121(put 'server-auth-dir 'risky-local-variable t)
122
90caccca 123(defcustom server-raise-frame t
ff348fba 124 "If non-nil, raise frame when switching to a buffer."
90caccca
JB
125 :group 'server
126 :type 'boolean
127 :version "22.1")
128
ab1c7f35 129(defcustom server-visit-hook nil
ff348fba 130 "Hook run when visiting a file for the Emacs server."
ab1c7f35 131 :group 'server
0c851d78 132 :type 'hook)
ab1c7f35
RS
133
134(defcustom server-switch-hook nil
ff348fba 135 "Hook run when switching to a buffer for the Emacs server."
ab1c7f35 136 :group 'server
0c851d78 137 :type 'hook)
ab1c7f35
RS
138
139(defcustom server-done-hook nil
ff348fba 140 "Hook run when done editing a buffer for the Emacs server."
ab1c7f35 141 :group 'server
0c851d78 142 :type 'hook)
f9b3ef88 143
64f51134
JPW
144(defvar server-process nil
145 "The current server process.")
9ae0f972 146
147(defvar server-clients nil
148 "List of current server clients.
448f754f 149Each element is a process.")
0a125897 150
9ae0f972 151(defvar server-buffer-clients nil
5f3c1a63 152 "List of client processes requesting editing of current buffer.")
faf931a8 153(make-variable-buffer-local 'server-buffer-clients)
9ae0f972 154;; Changing major modes should not erase this local.
155(put 'server-buffer-clients 'permanent-local t)
156
33186f32 157(defcustom server-window nil
ff348fba 158 "Specification of the window to use for selecting Emacs server buffers.
ec40ed9f 159If nil, use the selected window.
408784a7 160If it is a function, it should take one argument (a buffer) and
33186f32
DL
161display and select it. A common value is `pop-to-buffer'.
162If it is a window, use that.
163If it is a frame, use the frame's selected window.
164
165It is not meaningful to set this to a specific frame or window with Custom.
166Only programs can do so."
167 :group 'server
bf247b6e 168 :version "22.1"
33186f32
DL
169 :type '(choice (const :tag "Use selected window"
170 :match (lambda (widget value)
171 (not (functionp value)))
172 nil)
ee9272ff 173 (function-item :tag "Display in new frame" switch-to-buffer-other-frame)
33186f32
DL
174 (function-item :tag "Use pop-to-buffer" pop-to-buffer)
175 (function :tag "Other function")))
ec40ed9f 176
ab1c7f35 177(defcustom server-temp-file-regexp "^/tmp/Re\\|/draft$"
ff348fba 178 "Regexp matching names of temporary files.
33186f32
DL
179These are deleted and reused after each edit by the programs that
180invoke the Emacs server."
ab1c7f35
RS
181 :group 'server
182 :type 'regexp)
9ae0f972 183
c6a117f0 184(defcustom server-kill-new-buffers t
ff348fba 185 "Whether to kill buffers when done with them.
c6a117f0 186If non-nil, kill a buffer unless it already existed before editing
f258b525 187it with the Emacs server. If nil, kill only buffers as specified by
c6a117f0 188`server-temp-file-regexp'.
f258b525
GM
189Please note that only buffers that still have a client are killed,
190i.e. buffers visited with \"emacsclient --no-wait\" are never killed in
c6a117f0
GM
191this way."
192 :group 'server
193 :type 'boolean
194 :version "21.1")
195
9ae0f972 196(or (assq 'server-buffer-clients minor-mode-alist)
b7621225 197 (push '(server-buffer-clients " Server") minor-mode-alist))
9ae0f972 198
c6a117f0 199(defvar server-existing-buffer nil
ca0c7250 200 "Non-nil means the buffer existed before the server was asked to visit it.
4dd04714 201This means that the server should not kill the buffer when you say you
ca0c7250 202are done with it in the server.")
c6a117f0
GM
203(make-variable-buffer-local 'server-existing-buffer)
204
03ae35cf
SM
205(defvar server-name "server")
206
fc0dcdef
KL
207(defvar server-socket-dir nil
208 "The directory in which to place the server socket.
209Initialized by `server-start'.")
0c851d78 210
9002956f
KL
211(defun server-clients-with (property value)
212 "Return a list of clients with PROPERTY set to VALUE."
213 (let (result)
448f754f
SM
214 (dolist (proc server-clients result)
215 (when (equal value (process-get proc property))
216 (push proc result)))))
9002956f
KL
217
218(defun server-add-client (proc)
219 "Create a client for process PROC, if it doesn't already have one.
220New clients have no properties."
448f754f 221 (add-to-list 'server-clients proc))
9002956f 222
59e085e0
KL
223(defmacro server-with-environment (env vars &rest body)
224 "Evaluate BODY with environment variables VARS set to those in ENV.
65f64034
KL
225The environment variables are then restored to their previous values.
226
59e085e0
KL
227VARS should be a list of strings.
228ENV should be in the same format as `process-environment'."
65f64034 229 (declare (indent 2))
13ba3740
SM
230 (let ((var (make-symbol "var"))
231 (value (make-symbol "value")))
232 `(let ((process-environment process-environment))
59e085e0 233 (dolist (,var ,vars)
e159b869 234 (let ((,value (getenv-internal ,var ,env)))
13ba3740
SM
235 (push (if (null ,value)
236 ,var
237 (concat ,var "=" ,value))
238 process-environment)))
239 (progn ,@body))))
65f64034 240
448f754f 241(defun server-delete-client (proc &optional noframe)
c48254fb 242 "Delete PROC, including its buffers, terminals and frames.
de93c791 243If NOFRAME is non-nil, let the frames live. (To be used from
5f3c1a63 244`delete-frame-functions'.)"
ff91dc79 245 (server-log (concat "server-delete-client" (if noframe " noframe")) proc)
9002956f 246 ;; Force a new lookup of client (prevents infinite recursion).
448f754f
SM
247 (when (memq proc server-clients)
248 (let ((buffers (process-get proc 'buffers)))
9002956f 249
5f3c1a63 250 ;; Kill the client's buffers.
9002956f 251 (dolist (buf buffers)
6ed9e43a
KL
252 (when (buffer-live-p buf)
253 (with-current-buffer buf
6ed9e43a 254 ;; Kill the buffer if necessary.
5f3c1a63
KL
255 (when (and (equal server-buffer-clients
256 (list proc))
6ed9e43a
KL
257 (or (and server-kill-new-buffers
258 (not server-existing-buffer))
5f3c1a63
KL
259 (server-temp-file-p))
260 (not (buffer-modified-p)))
261 (let (flag)
262 (unwind-protect
263 (progn (setq server-buffer-clients nil)
264 (kill-buffer (current-buffer))
265 (setq flag t))
266 (unless flag
267 ;; Restore clients if user pressed C-g in `kill-buffer'.
268 (setq server-buffer-clients (list proc)))))))))
9002956f 269
160f0817
KL
270 ;; Delete the client's frames.
271 (unless noframe
272 (dolist (frame (frame-list))
273 (when (and (frame-live-p frame)
274 (equal proc (frame-parameter frame 'client)))
275 ;; Prevent `server-handle-delete-frame' from calling us
276 ;; recursively.
277 (set-frame-parameter frame 'client nil)
278 (delete-frame frame))))
279
448f754f 280 (setq server-clients (delq proc server-clients))
5f3c1a63 281
9002956f 282 ;; Delete the client's tty.
448f754f 283 (let ((terminal (process-get proc 'terminal)))
977ede64
DN
284 ;; Only delete the terminal if it is non-nil.
285 (when (and terminal (eq (terminal-live-p terminal) t))
6ed8eeff 286 (delete-terminal terminal)))
9002956f 287
9002956f 288 ;; Delete the client's process.
448f754f
SM
289 (if (eq (process-status proc) 'open)
290 (delete-process proc))
9002956f
KL
291
292 (server-log "Deleted" proc))))
293
88fd26a1
JB
294(defvar server-log-time-function 'current-time-string
295 "Function to generate timestamps for the *server* buffer.")
296
28cbade4
SM
297(defconst server-buffer " *server*"
298 "Buffer used internally by Emacs's server.
299One use is to log the I/O for debugging purposes (see `server-log'),
300the other is to provide a current buffer in which the process filter can
301safely let-bind buffer-local variables like default-directory.")
302
303(defvar server-log nil
304 "If non-nil, log the server's inputs and outputs in the `server-buffer'.")
305
8b3e840e 306(defun server-log (string &optional client)
28cbade4 307 "If `server-log' is non-nil, log STRING to `server-buffer'.
c48254fb 308If CLIENT is non-nil, add a description of it to the logged message."
28cbade4
SM
309 (when server-log
310 (with-current-buffer (get-buffer-create server-buffer)
337e3c70 311 (goto-char (point-max))
88fd26a1 312 (insert (funcall server-log-time-function)
974b73e8 313 (cond
88fd26a1
JB
314 ((null client) " ")
315 ((listp client) (format " %s: " (car client)))
316 (t (format " %s: " client)))
337e3c70
JB
317 string)
318 (or (bolp) (newline)))))
9ae0f972 319
320(defun server-sentinel (proc msg)
9002956f 321 "The process sentinel for Emacs server connections."
cbfc02e4
RF
322 ;; If this is a new client process, set the query-on-exit flag to nil
323 ;; for this process (it isn't inherited from the server process).
324 (when (and (eq (process-status proc) 'open)
325 (process-query-on-exit-flag proc))
326 (set-process-query-on-exit-flag proc nil))
757e1681
SM
327 ;; Delete the associated connection file, if applicable.
328 ;; This is actually problematic: the file may have been overwritten by
329 ;; another Emacs server in the mean time, so it's not ours any more.
330 ;; (and (process-contact proc :server)
331 ;; (eq (process-status proc) 'closed)
332 ;; (ignore-errors (delete-file (process-get proc :server-file))))
9002956f
KL
333 (server-log (format "Status changed to %s: %s" (process-status proc) msg) proc)
334 (server-delete-client proc))
0c851d78 335
13ba3740
SM
336(defun server-select-display (display)
337 ;; If the current frame is on `display' we're all set.
1a4a884c
SM
338 ;; Similarly if we are unable to open a frames on other displays, there's
339 ;; nothing more we can do.
340 (unless (or (not (fboundp 'make-frame-on-display))
341 (equal (frame-parameter (selected-frame) 'display) display))
13ba3740
SM
342 ;; Otherwise, look for an existing frame there and select it.
343 (dolist (frame (frame-list))
344 (when (equal (frame-parameter frame 'display) display)
345 (select-frame frame)))
346 ;; If there's no frame on that display yet, create and select one.
347 (unless (equal (frame-parameter (selected-frame) 'display) display)
348 (let* ((buffer (generate-new-buffer " *server-dummy*"))
349 (frame (make-frame-on-display
350 display
351 ;; Make it display (and remember) some dummy buffer, so
352 ;; we can detect later if the frame is in use or not.
ff91dc79 353 `((server-dummy-buffer . ,buffer)
13ba3740
SM
354 ;; This frame may be deleted later (see
355 ;; server-unselect-display) so we want it to be as
356 ;; unobtrusive as possible.
357 (visibility . nil)))))
358 (select-frame frame)
359 (set-window-buffer (selected-window) buffer)
360 frame))))
361
362(defun server-unselect-display (frame)
363 (when (frame-live-p frame)
364 ;; If the temporary frame is in use (displays something real), make it
365 ;; visible. If not (which can happen if the user's customizations call
366 ;; pop-to-buffer etc.), delete it to avoid preserving the connection after
367 ;; the last real frame is deleted.
368 (if (and (eq (frame-first-window frame)
369 (next-window (frame-first-window frame) 'nomini))
370 (eq (window-buffer (frame-first-window frame))
371 (frame-parameter frame 'server-dummy-buffer)))
372 ;; The temp frame still only shows one buffer, and that is the
373 ;; internal temp buffer.
374 (delete-frame frame)
375 (set-frame-parameter frame 'visibility t))
376 (kill-buffer (frame-parameter frame 'server-dummy-buffer))
377 (set-frame-parameter frame 'server-dummy-buffer nil)))
378
77134727
KL
379(defun server-handle-delete-frame (frame)
380 "Delete the client connection when the emacsclient frame is deleted."
9002956f 381 (let ((proc (frame-parameter frame 'client)))
e519a50b
KL
382 (when (and (frame-live-p frame)
383 proc
160f0817 384 ;; See if this is the last frame for this client.
d5381da2 385 (>= 1 (let ((frame-num 0))
aabf0cb9 386 (dolist (f (frame-list))
160f0817
KL
387 (when (eq proc (frame-parameter f 'client))
388 (setq frame-num (1+ frame-num))))
389 frame-num)))
9002956f 390 (server-log (format "server-handle-delete-frame, frame %s" frame) proc)
de93c791 391 (server-delete-client proc 'noframe)))) ; Let delete-frame delete the frame later.
9002956f 392
6ed8eeff 393(defun server-handle-suspend-tty (terminal)
9002956f 394 "Notify the emacsclient process to suspend itself when its tty device is suspended."
6ed8eeff
KL
395 (dolist (proc (server-clients-with 'terminal terminal))
396 (server-log (format "server-handle-suspend-tty, terminal %s" terminal) proc)
6d3a46f7 397 (condition-case err
6afdd335 398 (server-send-string proc "-suspend \n")
44954c2f
SM
399 (file-error ;The pipe/socket was closed.
400 (ignore-errors (server-delete-client proc))))))
44a56b29 401
0c851d78 402(defun server-unquote-arg (arg)
6afdd335
KL
403 "Remove &-quotation from ARG.
404See `server-quote-arg' and `server-process-filter'."
0c851d78
SM
405 (replace-regexp-in-string
406 "&." (lambda (s)
407 (case (aref s 1)
408 (?& "&")
409 (?- "-")
410 (?n "\n")
411 (t " ")))
412 arg t t))
9ae0f972 413
0b0d3e0b 414(defun server-quote-arg (arg)
9002956f 415 "In ARG, insert a & before each &, each space, each newline, and -.
0b0d3e0b 416Change spaces to underscores, too, so that the return value never
6afdd335
KL
417contains a space.
418
419See `server-unquote-arg' and `server-process-filter'."
0b0d3e0b
KL
420 (replace-regexp-in-string
421 "[-&\n ]" (lambda (s)
422 (case (aref s 0)
423 (?& "&&")
424 (?- "&-")
425 (?\n "&n")
426 (?\s "&_")))
427 arg t t))
428
6afdd335
KL
429(defun server-send-string (proc string)
430 "A wrapper around `proc-send-string' for logging."
431 (server-log (concat "Sent " string) proc)
432 (process-send-string proc string))
433
724629d2
SM
434(defun server-ensure-safe-dir (dir)
435 "Make sure DIR is a directory with no race-condition issues.
436Creates the directory if necessary and makes sure:
437- there's no symlink involved
438- it's owned by us
439- it's not readable/writable by anybody else."
440 (setq dir (directory-file-name dir))
441 (let ((attrs (file-attributes dir)))
442 (unless attrs
337e3c70 443 (letf (((default-file-modes) ?\700)) (make-directory dir t))
724629d2
SM
444 (setq attrs (file-attributes dir)))
445 ;; Check that it's safe for use.
da6657b7 446 (unless (and (eq t (car attrs)) (eql (nth 2 attrs) (user-uid))
337e3c70
JB
447 (or (eq system-type 'windows-nt)
448 (zerop (logand ?\077 (file-modes dir)))))
724629d2
SM
449 (error "The directory %s is unsafe" dir))))
450
7229064d 451;;;###autoload
9ae0f972 452(defun server-start (&optional leave-dead)
453 "Allow this Emacs process to be a server for client processes.
454This starts a server communications subprocess through which
6d3a46f7
KL
455client \"editors\" can send your editing commands to this Emacs
456job. To use the server, set up the program `emacsclient' in the
9ae0f972 457Emacs distribution as your standard \"editor\".
458
bd410bb0
EZ
459Optional argument LEAVE-DEAD (interactively, a prefix arg) means just
460kill any existing server communications subprocess."
9ae0f972 461 (interactive "P")
d6b4b3cf
KL
462 (when (or
463 (not server-clients)
464 (yes-or-no-p
465 "The current server still has clients; delete them? "))
466 ;; It is safe to get the user id now.
467 (setq server-socket-dir (or server-socket-dir
468 (format "/tmp/emacs%d" (user-uid))))
974b73e8
KL
469 (when server-process
470 ;; kill it dead!
471 (ignore-errors (delete-process server-process)))
d6b4b3cf
KL
472 ;; Delete the socket files made by previous server invocations.
473 (condition-case ()
474 (delete-file (expand-file-name server-name server-socket-dir))
475 (error nil))
476 ;; If this Emacs already had a server, clear out associated status.
477 (while server-clients
478 (server-delete-client (car server-clients)))
9f97e26d 479 ;; Now any previous server is properly stopped.
d6b4b3cf
KL
480 (if leave-dead
481 (progn
482 (server-log (message "Server stopped"))
483 (setq server-process nil))
974b73e8
KL
484 (let* ((server-dir (if server-use-tcp server-auth-dir server-socket-dir))
485 (server-file (expand-file-name server-name server-dir)))
486 ;; Make sure there is a safe directory in which to place the socket.
487 (server-ensure-safe-dir server-dir)
488 ;; Remove any leftover socket or authentication file.
489 (ignore-errors (delete-file server-file))
490 (when server-process
491 (server-log (message "Restarting server")))
492 (letf (((default-file-modes) ?\700))
e4019195 493 (add-hook 'suspend-tty-functions 'server-handle-suspend-tty)
974b73e8
KL
494 (add-hook 'delete-frame-functions 'server-handle-delete-frame)
495 (add-hook 'kill-buffer-query-functions 'server-kill-buffer-query-function)
496 (add-hook 'kill-emacs-query-functions 'server-kill-emacs-query-function)
1d515b42 497 (add-hook 'kill-emacs-hook (lambda () (server-mode -1))) ;Cleanup upon exit.
974b73e8
KL
498 (setq server-process
499 (apply #'make-network-process
500 :name server-name
501 :server t
502 :noquery t
503 :sentinel 'server-sentinel
504 :filter 'server-process-filter
505 ;; We must receive file names without being decoded.
506 ;; Those are decoded by server-process-filter according
507 ;; to file-name-coding-system.
508 :coding 'raw-text
28cbade4 509 ;; The other args depend on the kind of socket used.
974b73e8
KL
510 (if server-use-tcp
511 (list :family nil
512 :service t
513 :host (or server-host 'local)
514 :plist '(:authenticated nil))
515 (list :family 'local
516 :service server-file
517 :plist '(:authenticated t)))))
518 (unless server-process (error "Could not start server process"))
519 (when server-use-tcp
520 (let ((auth-key
521 (loop
d76e2046
JB
522 ;; The auth key is a 64-byte string of random chars in the
523 ;; range `!'..`~'.
524 for i below 64
525 collect (+ 33 (random 94)) into auth
526 finally return (concat auth))))
974b73e8
KL
527 (process-put server-process :auth-key auth-key)
528 (with-temp-file server-file
529 (set-buffer-multibyte nil)
530 (setq buffer-file-coding-system 'no-conversion)
531 (insert (format-network-address
532 (process-contact server-process :local))
533 " " (int-to-string (emacs-pid))
534 "\n" auth-key)))))))))
33186f32 535
44954c2f
SM
536(defun server-running-p (&optional name)
537 "Test whether server NAME is running."
538 (interactive
539 (list (if current-prefix-arg
540 (read-string "Server name: " nil nil server-name))))
541 (unless name (setq name server-name))
542 (condition-case nil
543 (progn
544 (delete-process
545 (make-network-process
546 :name "server-client-test" :family 'local :server nil :noquery t
547 :service (expand-file-name name server-socket-dir)))
548 t)
549 (file-error nil)))
550
33186f32
DL
551;;;###autoload
552(define-minor-mode server-mode
553 "Toggle Server mode.
554With ARG, turn Server mode on if ARG is positive, off otherwise.
555Server mode runs a process that accepts commands from the
556`emacsclient' program. See `server-start' and Info node `Emacs server'."
557 :global t
558 :group 'server
bf247b6e 559 :version "22.1"
33186f32
DL
560 ;; Fixme: Should this check for an existing server socket and do
561 ;; nothing if there is one (for multiple Emacs sessions)?
562 (server-start (not server-mode)))
9ae0f972 563\f
13ba3740
SM
564(defun server-eval-and-print (expr proc)
565 "Eval EXPR and send the result back to client PROC."
566 (let ((v (eval (car (read-from-string expr)))))
567 (when (and v proc)
568 (with-temp-buffer
569 (let ((standard-output (current-buffer)))
570 (pp v)
571 (let ((text (buffer-substring-no-properties
572 (point-min) (point-max))))
573 (server-send-string
574 proc (format "-print %s\n"
575 (server-quote-arg text)))))))))
576
577(defun server-create-tty-frame (tty type proc)
4419b755 578 (add-to-list 'frame-inherited-parameters 'client)
13ba3740
SM
579 (let ((frame
580 (server-with-environment (process-get proc 'env)
581 '("LANG" "LC_CTYPE" "LC_ALL"
582 ;; For tgetent(3); list according to ncurses(3).
583 "BAUDRATE" "COLUMNS" "ESCDELAY" "HOME" "LINES"
584 "NCURSES_ASSUMED_COLORS" "NCURSES_NO_PADDING"
585 "NCURSES_NO_SETBUF" "TERM" "TERMCAP" "TERMINFO"
c48254fb 586 "TERMINFO_DIRS" "TERMPATH"
13ba3740
SM
587 ;; rxvt wants these
588 "COLORFGBG" "COLORTERM")
589 (make-frame-on-tty tty type
590 ;; Ignore nowait here; we always need to
591 ;; clean up opened ttys when the client dies.
592 `((client . ,proc)
4419b755
SM
593 ;; This is a leftover from an earlier
594 ;; attempt at making it possible for process
595 ;; run in the server process to use the
596 ;; environment of the client process.
597 ;; It has no effect now and to make it work
598 ;; we'd need to decide how to make
599 ;; process-environment interact with client
600 ;; envvars, and then to change the
601 ;; C functions `child_setup' and
602 ;; `getenv_internal' accordingly.
448f754f 603 (environment . ,(process-get proc 'env)))))))
c48254fb 604
e159b869
SM
605 ;; ttys don't use the `display' parameter, but callproc.c does to set
606 ;; the DISPLAY environment on subprocesses.
607 (set-frame-parameter frame 'display
608 (getenv-internal "DISPLAY" (process-get proc 'env)))
13ba3740 609 (select-frame frame)
448f754f 610 (process-put proc 'frame frame)
448f754f 611 (process-put proc 'terminal (frame-terminal frame))
13ba3740
SM
612
613 ;; Display *scratch* by default.
614 (switch-to-buffer (get-buffer-create "*scratch*") 'norecord)
615
616 ;; Reply with our pid.
617 (server-send-string proc (concat "-emacs-pid "
618 (number-to-string (emacs-pid)) "\n"))
619 frame))
620
621(defun server-create-window-system-frame (display nowait proc)
4419b755 622 (add-to-list 'frame-inherited-parameters 'client)
e159b869 623 (if (not (fboundp 'make-frame-on-display))
13ba3740
SM
624 (progn
625 ;; This emacs does not support X.
626 (server-log "Window system unsupported" proc)
627 (server-send-string proc "-window-system-unsupported \n")
628 nil)
629 ;; Flag frame as client-created, but use a dummy client.
630 ;; This will prevent the frame from being deleted when
631 ;; emacsclient quits while also preventing
632 ;; `server-save-buffers-kill-terminal' from unexpectedly
633 ;; killing emacs on that frame.
634 (let* ((params `((client . ,(if nowait 'nowait proc))
4419b755 635 ;; This is a leftover, see above.
13ba3740
SM
636 (environment . ,(process-get proc 'env))))
637 (frame (make-frame-on-display
638 (or display
639 (frame-parameter nil 'display)
640 (getenv "DISPLAY")
641 (error "Please specify display"))
448f754f 642 params)))
13ba3740 643 (server-log (format "%s created" frame) proc)
13ba3740 644 (select-frame frame)
448f754f
SM
645 (process-put proc 'frame frame)
646 (process-put proc 'terminal (frame-terminal frame))
13ba3740
SM
647
648 ;; Display *scratch* by default.
649 (switch-to-buffer (get-buffer-create "*scratch*") 'norecord)
650 frame)))
651
652
653(defun server-goto-toplevel (proc)
654 (condition-case nil
655 ;; If we're running isearch, we must abort it to allow Emacs to
656 ;; display the buffer and switch to it.
657 (dolist (buffer (buffer-list))
658 (with-current-buffer buffer
659 (when (bound-and-true-p isearch-mode)
660 (isearch-cancel))))
661 ;; Signaled by isearch-cancel.
662 (quit (message nil)))
663 (when (> (recursion-depth) 0)
664 ;; We're inside a minibuffer already, so if the emacs-client is trying
665 ;; to open a frame on a new display, we might end up with an unusable
666 ;; frame because input from that display will be blocked (until exiting
667 ;; the minibuffer). Better exit this minibuffer right away.
668 ;; Similarly with recursive-edits such as the splash screen.
669 (run-with-timer 0 nil (lexical-let ((proc proc))
670 (lambda () (server-execute-continuation proc))))
671 (top-level)))
672
673;; We use various special properties on process objects:
674;; - `env' stores the info about the environment of the emacsclient process.
675;; - `continuation' is a no-arg function that we need to execute. It contains
676;; commands we wanted to execute in some earlier invocation of the process
677;; filter but that we somehow were unable to process at that time
678;; (e.g. because we first need to throw to the toplevel).
679
680(defun server-execute-continuation (proc)
681 (let ((continuation (process-get proc 'continuation)))
682 (process-put proc 'continuation nil)
683 (if continuation (ignore-errors (funcall continuation)))))
684
337e3c70 685(defun* server-process-filter (proc string)
33186f32 686 "Process a request from the server to edit some files.
6afdd335
KL
687PROC is the server process. STRING consists of a sequence of
688commands prefixed by a dash. Some commands have arguments; these
689are &-quoted and need to be decoded by `server-unquote-arg'. The
690filter parses and executes these commands.
691
692To illustrate the protocol, here is an example command that
693emacsclient sends to create a new X frame (note that the whole
694sequence is sent on a single line):
695
6afdd335
KL
696 -env HOME /home/lorentey
697 -env DISPLAY :0.0
698 ... lots of other -env commands
699 -display :0.0
700 -window-system
701
6afdd335
KL
702The following commands are accepted by the server:
703
974b73e8
KL
704`-auth AUTH-STRING'
705 Authenticate the client using the secret authentication string
a38daa0a 706 AUTH-STRING.
974b73e8 707
59e085e0 708`-env NAME=VALUE'
6afdd335
KL
709 An environment variable on the client side.
710
2828d5f9
KL
711`-dir DIRNAME'
712 The current working directory of the client process.
713
92071250
KL
714`-current-frame'
715 Forbid the creation of new frames.
716
6afdd335
KL
717`-nowait'
718 Request that the next frame created should not be
719 associated with this client.
720
721`-display DISPLAY'
722 Set the display name to open X frames on.
723
724`-position LINE[:COLUMN]'
725 Go to the given line and column number
726 in the next file opened.
727
728`-file FILENAME'
729 Load the given file in the current frame.
730
731`-eval EXPR'
732 Evaluate EXPR as a Lisp expression and return the
733 result in -print commands.
734
735`-window-system'
736 Open a new X frame.
737
738`-tty DEVICENAME TYPE'
739 Open a new tty frame at the client.
740
6afdd335
KL
741`-suspend'
742 Suspend this tty frame. The client sends this string in
743 response to SIGTSTP and SIGTTOU. The server must cease all I/O
744 on this tty until it gets a -resume command.
745
2828d5f9 746`-resume'
c48254fb 747 Resume this tty frame. The client sends this string when it
2828d5f9
KL
748 gets the SIGCONT signal and it is the foreground process on its
749 controlling tty.
750
6afdd335
KL
751`-ignore COMMENT'
752 Do nothing, but put the comment in the server
753 log. Useful for debugging.
754
755
756The following commands are accepted by the client:
757
6afdd335
KL
758`-emacs-pid PID'
759 Describes the process id of the Emacs process;
760 used to forward window change signals to it.
761
762`-window-system-unsupported'
c48254fb
JB
763 Signals that the server does not support creating X frames;
764 the client must try again with a tty frame.
6afdd335
KL
765
766`-print STRING'
767 Print STRING on stdout. Used to send values
768 returned by -eval.
769
770`-error DESCRIPTION'
771 Signal an error (but continue processing).
772
773`-suspend'
c48254fb
JB
774 Suspend this terminal, i.e., stop the client process.
775 Sent when the user presses C-z."
6afdd335 776 (server-log (concat "Received " string) proc)
337e3c70
JB
777 ;; First things first: let's check the authentication
778 (unless (process-get proc :authenticated)
38b9f0f3 779 (if (and (string-match "-auth \\([!-~]+\\)\n?" string)
974b73e8
KL
780 (equal (match-string 1 string) (process-get proc :auth-key)))
781 (progn
782 (setq string (substring string (match-end 0)))
783 (process-put proc :authenticated t)
784 (server-log "Authentication successful" proc))
337e3c70 785 (server-log "Authentication failed" proc)
974b73e8
KL
786 (server-send-string
787 proc (concat "-error " (server-quote-arg "Authentication failed")))
337e3c70
JB
788 (delete-process proc)
789 ;; We return immediately
790 (return-from server-process-filter)))
3f7ef08e
SM
791 (let ((prev (process-get proc 'previous-string)))
792 (when prev
793 (setq string (concat prev string))
794 (process-put proc 'previous-string nil)))
a9298135 795 (condition-case err
0b0d3e0b 796 (progn
9002956f 797 (server-add-client proc)
13ba3740
SM
798 (if (not (string-match "\n" string))
799 ;; Save for later any partial line that remains.
800 (when (> (length string) 0)
801 (process-put proc 'previous-string string))
c48254fb 802
13ba3740
SM
803 ;; In earlier versions of server.el (where we used an `emacsserver'
804 ;; process), there could be multiple lines. Nowadays this is not
805 ;; supported any more.
806 (assert (eq (match-end 0) (length string)))
0b0d3e0b
KL
807 (let ((request (substring string 0 (match-beginning 0)))
808 (coding-system (and default-enable-multibyte-characters
809 (or file-name-coding-system
810 default-file-name-coding-system)))
9002956f
KL
811 nowait ; t if emacsclient does not want to wait for us.
812 frame ; The frame that was opened for the client (if any).
59e085e0 813 display ; Open the frame on this display.
0b0d3e0b 814 dontkill ; t if the client should not be killed.
13ba3740 815 (commands ())
2828d5f9 816 dir
13ba3740
SM
817 (tty-name nil) ;nil, `window-system', or the tty name.
818 tty-type ;string.
0b0d3e0b 819 (files nil)
656d4706 820 (filepos nil)
bfb74e75
DK
821 command-line-args-left
822 arg)
0b0d3e0b
KL
823 ;; Remove this line from STRING.
824 (setq string (substring string (match-end 0)))
bfb74e75
DK
825 (setq command-line-args-left
826 (mapcar 'server-unquote-arg (split-string request " " t)))
827 (while (setq arg (pop command-line-args-left))
0b0d3e0b 828 (cond
13ba3740 829 ;; -version CLIENT-VERSION: obsolete at birth.
bfb74e75
DK
830 ((and (equal "-version" arg) command-line-args-left)
831 (pop command-line-args-left))
0b0d3e0b 832
9002956f 833 ;; -nowait: Emacsclient won't wait for a result.
0b0d3e0b
KL
834 ((equal "-nowait" arg) (setq nowait t))
835
92071250 836 ;; -current-frame: Don't create frames.
13ba3740 837 ((equal "-current-frame" arg) (setq tty-name nil))
92071250 838
9002956f 839 ;; -display DISPLAY:
59e085e0 840 ;; Open X frames on the given display instead of the default.
bfb74e75 841 ((and (equal "-display" arg) command-line-args-left)
ff91dc79
SM
842 (setq display (pop command-line-args-left))
843 (if (zerop (length display)) (setq display nil)))
0b0d3e0b 844
9002956f 845 ;; -window-system: Open a new X frame.
0b0d3e0b 846 ((equal "-window-system" arg)
13ba3740
SM
847 (setq dontkill t)
848 (setq tty-name 'window-system))
9002956f
KL
849
850 ;; -resume: Resume a suspended tty frame.
0b0d3e0b 851 ((equal "-resume" arg)
448f754f 852 (lexical-let ((terminal (process-get proc 'terminal)))
0b0d3e0b 853 (setq dontkill t)
13ba3740
SM
854 (push (lambda ()
855 (when (eq (terminal-live-p terminal) t)
856 (resume-tty terminal)))
857 commands)))
0b0d3e0b 858
9002956f
KL
859 ;; -suspend: Suspend the client's frame. (In case we
860 ;; get out of sync, and a C-z sends a SIGTSTP to
861 ;; emacsclient.)
0b0d3e0b 862 ((equal "-suspend" arg)
448f754f 863 (lexical-let ((terminal (process-get proc 'terminal)))
0b0d3e0b 864 (setq dontkill t)
13ba3740
SM
865 (push (lambda ()
866 (when (eq (terminal-live-p terminal) t)
867 (suspend-tty terminal)))
868 commands)))
0b0d3e0b 869
9002956f
KL
870 ;; -ignore COMMENT: Noop; useful for debugging emacsclient.
871 ;; (The given comment appears in the server log.)
bfb74e75
DK
872 ((and (equal "-ignore" arg) command-line-args-left
873 (setq dontkill t)
874 (pop command-line-args-left)))
0b0d3e0b 875
9002956f 876 ;; -tty DEVICE-NAME TYPE: Open a new tty frame at the client.
13ba3740 877 ((and (equal "-tty" arg)
bfb74e75
DK
878 (cdr command-line-args-left))
879 (setq tty-name (pop command-line-args-left)
880 tty-type (pop command-line-args-left)
881 dontkill t))
13ba3740
SM
882
883 ;; -position LINE[:COLUMN]: Set point to the given
884 ;; position in the next file.
885 ((and (equal "-position" arg)
bfb74e75
DK
886 command-line-args-left
887 (string-match "\\+\\([0-9]+\\)\\(?::\\([0-9]+\\)\\)?"
888 (car command-line-args-left)))
889 (setq arg (pop command-line-args-left))
656d4706
SM
890 (setq filepos
891 (cons (string-to-number (match-string 1 arg))
892 (string-to-number (or (match-string 2 arg) "")))))
0b0d3e0b 893
9002956f 894 ;; -file FILENAME: Load the given file.
13ba3740 895 ((and (equal "-file" arg)
bfb74e75
DK
896 command-line-args-left)
897 (let ((file (pop command-line-args-left)))
0b0d3e0b
KL
898 (if coding-system
899 (setq file (decode-coding-string file coding-system)))
900 (setq file (command-line-normalize-file-name file))
656d4706
SM
901 (push (cons file filepos) files)
902 (server-log (format "New file: %s %s"
903 file (or filepos "")) proc))
904 (setq filepos nil))
0b0d3e0b 905
9002956f 906 ;; -eval EXPR: Evaluate a Lisp expression.
13ba3740 907 ((and (equal "-eval" arg)
bfb74e75
DK
908 command-line-args-left)
909 (lexical-let ((expr (pop command-line-args-left)))
0b0d3e0b
KL
910 (if coding-system
911 (setq expr (decode-coding-string expr coding-system)))
13ba3740
SM
912 (push (lambda () (server-eval-and-print expr proc))
913 commands)
656d4706 914 (setq filepos nil)))
0b0d3e0b 915
59e085e0 916 ;; -env NAME=VALUE: An environment variable.
bfb74e75
DK
917 ((and (equal "-env" arg) command-line-args-left)
918 (let ((var (pop command-line-args-left)))
da8e8fc1 919 ;; XXX Variables should be encoded as in getenv/setenv.
13ba3740
SM
920 (process-put proc 'env
921 (cons var (process-get proc 'env)))))
9002956f 922
2828d5f9 923 ;; -dir DIRNAME: The cwd of the emacsclient process.
bfb74e75
DK
924 ((and (equal "-dir" arg) command-line-args-left)
925 (setq dir (pop command-line-args-left))
2828d5f9
KL
926 (if coding-system
927 (setq dir (decode-coding-string dir coding-system)))
928 (setq dir (command-line-normalize-file-name dir)))
929
0b0d3e0b 930 ;; Unknown command.
bfb74e75 931 (t (error "Unknown command: %s" arg))))
c48254fb 932
13ba3740
SM
933 (setq frame
934 (case tty-name
935 ((nil) (if display (server-select-display display)))
936 ((window-system)
937 (server-create-window-system-frame display nowait proc))
938 (t (server-create-tty-frame tty-name tty-type proc))))
939
28cbade4
SM
940 (process-put
941 proc 'continuation
942 (lexical-let ((proc proc)
943 (files files)
944 (nowait nowait)
945 (commands commands)
946 (dontkill dontkill)
947 (frame frame)
948 (dir dir)
949 (tty-name tty-name))
950 (lambda ()
951 (with-current-buffer (get-buffer-create server-buffer)
952 ;; Use the same cwd as the emacsclient, if possible, so
953 ;; relative file names work correctly, even in `eval'.
954 (let ((default-directory
475b5907
DN
955 (if (and dir (file-directory-p dir))
956 dir default-directory)))
28cbade4
SM
957 (server-execute proc files nowait commands
958 dontkill frame tty-name))))))
13ba3740
SM
959
960 (when (or frame files)
961 (server-goto-toplevel proc))
962
963 (server-execute-continuation proc))))
a9298135 964 ;; condition-case
13ba3740
SM
965 (error (server-return-error proc err))))
966
967(defun server-execute (proc files nowait commands dontkill frame tty-name)
968 (condition-case err
448f754f 969 (let* ((buffers
13ba3740
SM
970 (when files
971 (run-hooks 'pre-command-hook)
448f754f 972 (prog1 (server-visit-files files proc nowait)
13ba3740
SM
973 (run-hooks 'post-command-hook)))))
974
975 (mapc 'funcall (nreverse commands))
c48254fb 976
13ba3740
SM
977 ;; Delete the client if necessary.
978 (cond
979 (nowait
980 ;; Client requested nowait; return immediately.
981 (server-log "Close nowait client" proc)
982 (server-delete-client proc))
983 ((and (not dontkill) (null buffers))
984 ;; This client is empty; get rid of it immediately.
985 (server-log "Close empty client" proc)
986 (server-delete-client proc)))
987 (cond
988 ((or isearch-mode (minibufferp))
989 nil)
990 ((and frame (null buffers))
991 (message "%s" (substitute-command-keys
992 "When done with this frame, type \\[delete-frame]")))
993 ((not (null buffers))
994 (server-switch-buffer (car buffers))
995 (run-hooks 'server-switch-hook)
996 (unless nowait
997 (message "%s" (substitute-command-keys
998 "When done with a buffer, type \\[server-edit]")))))
999 (when (and frame (null tty-name))
1000 (server-unselect-display frame)))
1001 (error (server-return-error proc err))))
1002
1003(defun server-return-error (proc err)
1004 (ignore-errors
1005 (server-send-string
1006 proc (concat "-error " (server-quote-arg
1007 (error-message-string err))))
1008 (server-log (error-message-string err) proc)
1009 (delete-process proc)))
9ae0f972 1010
656d4706
SM
1011(defun server-goto-line-column (line-col)
1012 "Move point to the position indicated in LINE-COL.
1013LINE-COL should be a pair (LINE . COL)."
1014 (when line-col
1015 (goto-line (car line-col))
1016 (let ((column-number (cdr line-col)))
1017 (when (> column-number 0)
1018 (move-to-column (1- column-number))))))
6b98185f 1019
448f754f 1020(defun server-visit-files (files proc &optional nowait)
c5b0a355 1021 "Find FILES and return a list of buffers created.
656d4706
SM
1022FILES is an alist whose elements are (FILENAME . FILEPOS)
1023where FILEPOS can be nil or a pair (LINENUMBER . COLUMNNUMBER).
448f754f 1024PROC is the client that requested this operation.
dfa35e6b
RS
1025NOWAIT non-nil means this client is not waiting for the results,
1026so don't mark these buffers specially, just visit them normally."
e82e73c2 1027 ;; Bind last-nonmenu-event to force use of keyboard, not mouse, for queries.
44a56b29 1028 (let ((last-nonmenu-event t) client-record)
3a0ce849
RS
1029 ;; Restore the current buffer afterward, but not using save-excursion,
1030 ;; because we don't want to save point in this buffer
1031 ;; if it happens to be one of those specified by the server.
44a56b29
SM
1032 (save-current-buffer
1033 (dolist (file files)
1034 ;; If there is an existing buffer modified or the file is
1035 ;; modified, revert it. If there is an existing buffer with
1036 ;; deleted file, offer to write it.
cd7320d4 1037 (let* ((minibuffer-auto-raise (or server-raise-frame
974b73e8 1038 minibuffer-auto-raise))
c2d0d432 1039 (filen (car file))
44a56b29 1040 (obuf (get-file-buffer filen)))
c398358a 1041 (add-to-history 'file-name-history filen)
656d4706
SM
1042 (if (null obuf)
1043 (set-buffer (find-file-noselect filen))
1044 (set-buffer obuf)
1045 (cond ((file-exists-p filen)
1046 (when (not (verify-visited-file-modtime obuf))
1047 (revert-buffer t nil)))
1048 (t
1049 (when (y-or-n-p
1050 (concat "File no longer exists: " filen
1051 ", write buffer to file? "))
1052 (write-file filen))))
1053 (unless server-buffer-clients
1054 (setq server-existing-buffer t)))
1055 (server-goto-line-column (cdr file))
1056 (run-hooks 'server-visit-hook))
44a56b29
SM
1057 (unless nowait
1058 ;; When the buffer is killed, inform the clients.
1059 (add-hook 'kill-buffer-hook 'server-kill-buffer nil t)
448f754f 1060 (push proc server-buffer-clients))
c5b0a355
KL
1061 (push (current-buffer) client-record)))
1062 (unless nowait
448f754f
SM
1063 (process-put proc 'buffers
1064 (nconc (process-get proc 'buffers) client-record)))
c5b0a355 1065 client-record))
9ae0f972 1066\f
b392bac9 1067(defun server-buffer-done (buffer &optional for-killing)
9ae0f972 1068 "Mark BUFFER as \"done\" for its client(s).
9184aafb
RS
1069This buries the buffer, then returns a list of the form (NEXT-BUFFER KILLED).
1070NEXT-BUFFER is another server buffer, as a suggestion for what to select next,
8b3e840e
SM
1071or nil. KILLED is t if we killed BUFFER (typically, because it was visiting
1072a temp file).
1073FOR-KILLING if non-nil indicates that we are called from `kill-buffer'."
0c851d78 1074 (let ((next-buffer nil)
9002956f 1075 (killed nil))
448f754f
SM
1076 (dolist (proc server-clients)
1077 (let ((buffers (process-get proc 'buffers)))
8b3e840e 1078 (or next-buffer
9002956f
KL
1079 (setq next-buffer (nth 1 (memq buffer buffers))))
1080 (when buffers ; Ignore bufferless clients.
1081 (setq buffers (delq buffer buffers))
448f754f 1082 ;; Delete all dead buffers from PROC.
9002956f
KL
1083 (dolist (b buffers)
1084 (and (bufferp b)
1085 (not (buffer-live-p b))
1086 (setq buffers (delq b buffers))))
448f754f 1087 (process-put proc 'buffers buffers)
9002956f
KL
1088 ;; If client now has no pending buffers,
1089 ;; tell it that it is done, and forget it entirely.
1090 (unless buffers
448f754f
SM
1091 (server-log "Close" proc)
1092 (server-delete-client proc)))))
337e3c70
JB
1093 (when (and (bufferp buffer) (buffer-name buffer))
1094 ;; We may or may not kill this buffer;
1095 ;; if we do, do not call server-buffer-done recursively
1096 ;; from kill-buffer-hook.
1097 (let ((server-kill-buffer-running t))
1098 (with-current-buffer buffer
1099 (setq server-buffer-clients nil)
1100 (run-hooks 'server-done-hook))
1101 ;; Notice whether server-done-hook killed the buffer.
1102 (if (null (buffer-name buffer))
1103 (setq killed t)
1104 ;; Don't bother killing or burying the buffer
1105 ;; when we are called from kill-buffer.
1106 (unless for-killing
1107 (when (and (not killed)
1108 server-kill-new-buffers
1109 (with-current-buffer buffer
1110 (not server-existing-buffer)))
599f9a5c 1111 (setq killed t)
337e3c70
JB
1112 (bury-buffer buffer)
1113 (kill-buffer buffer))
1114 (unless killed
1115 (if (server-temp-file-p buffer)
1116 (progn
1117 (kill-buffer buffer)
1118 (setq killed t))
1119 (bury-buffer buffer)))))))
9184aafb 1120 (list next-buffer killed)))
9ae0f972 1121
408784a7 1122(defun server-temp-file-p (&optional buffer)
9ae0f972 1123 "Return non-nil if BUFFER contains a file considered temporary.
1124These are files whose names suggest they are repeatedly
1125reused to pass information to another program.
1126
1127The variable `server-temp-file-regexp' controls which filenames
1128are considered temporary."
1129 (and (buffer-file-name buffer)
1130 (string-match server-temp-file-regexp (buffer-file-name buffer))))
1131
1132(defun server-done ()
cc9875f9 1133 "Offer to save current buffer, mark it as \"done\" for clients.
ed9ae328
RS
1134This kills or buries the buffer, then returns a list
1135of the form (NEXT-BUFFER KILLED). NEXT-BUFFER is another server buffer,
1136as a suggestion for what to select next, or nil.
1137KILLED is t if we killed BUFFER, which happens if it was created
1138specifically for the clients and did not exist before their request for it."
408784a7
SM
1139 (when server-buffer-clients
1140 (if (server-temp-file-p)
1141 ;; For a temp file, save, and do make a non-numeric backup
1142 ;; (unless make-backup-files is nil).
1143 (let ((version-control nil)
1144 (buffer-backed-up nil))
1145 (save-buffer))
337e3c70
JB
1146 (when (and (buffer-modified-p)
1147 buffer-file-name
1148 (y-or-n-p (concat "Save file " buffer-file-name "? ")))
1149 (save-buffer)))
408784a7 1150 (server-buffer-done (current-buffer))))
faf931a8 1151
71207de2
RS
1152;; Ask before killing a server buffer.
1153;; It was suggested to release its client instead,
1154;; but I think that is dangerous--the client would proceed
1155;; using whatever is on disk in that file. -- rms.
03d78665 1156(defun server-kill-buffer-query-function ()
9002956f 1157 "Ask before killing a server buffer."
03d78665 1158 (or (not server-buffer-clients)
114a8b8c
KL
1159 (let ((res t))
1160 (dolist (proc server-buffer-clients res)
448f754f
SM
1161 (when (and (memq proc server-clients)
1162 (eq (process-status proc) 'open))
1163 (setq res nil))))
03d78665
RS
1164 (yes-or-no-p (format "Buffer `%s' still has clients; kill it? "
1165 (buffer-name (current-buffer))))))
1166
03d78665 1167(defun server-kill-emacs-query-function ()
c48254fb 1168 "Ask before exiting Emacs if it has live clients."
9002956f
KL
1169 (or (not server-clients)
1170 (let (live-client)
448f754f
SM
1171 (dolist (proc server-clients live-client)
1172 (when (memq t (mapcar 'buffer-live-p (process-get
1173 proc 'buffers)))
974b73e8 1174 (setq live-client t))))
9002956f 1175 (yes-or-no-p "This Emacs session has clients; exit anyway? ")))
b392bac9 1176
fb873cfc 1177(defvar server-kill-buffer-running nil
599f9a5c 1178 "Non-nil while `server-kill-buffer' or `server-buffer-done' is running.")
fb873cfc 1179
b392bac9 1180(defun server-kill-buffer ()
6d3a46f7
KL
1181 "Remove the current buffer from its clients' buffer list.
1182Designed to be added to `kill-buffer-hook'."
fb873cfc
RS
1183 ;; Prevent infinite recursion if user has made server-done-hook
1184 ;; call kill-buffer.
1185 (or server-kill-buffer-running
599f9a5c
RS
1186 (and server-buffer-clients
1187 (let ((server-kill-buffer-running t))
1188 (when server-process
1189 (server-buffer-done (current-buffer) t))))))
9ae0f972 1190\f
1191(defun server-edit (&optional arg)
1192 "Switch to next server editing buffer; say \"Done\" for current buffer.
1193If a server buffer is current, it is marked \"done\" and optionally saved.
ed9ae328 1194The buffer is also killed if it did not exist before the clients asked for it.
9ae0f972 1195When all of a client's buffers are marked as \"done\", the client is notified.
1196
1197Temporary files such as MH <draft> files are always saved and backed up,
991298c3
RS
1198no questions asked. (The variable `make-backup-files', if nil, still
1199inhibits a backup; you can set it locally in a particular buffer to
1200prevent a backup for it.) The variable `server-temp-file-regexp' controls
9ae0f972 1201which filenames are considered temporary.
1202
64f51134 1203If invoked with a prefix argument, or if there is no server process running,
9ae0f972 1204starts server process and that is all. Invoked by \\[server-edit]."
9ae0f972 1205 (interactive "P")
6b519504 1206 (cond
95eefb35
JB
1207 ((or arg
1208 (not server-process)
1209 (memq (process-status server-process) '(signal exit)))
1210 (server-mode 1))
1211 (server-clients (apply 'server-switch-buffer (server-done)))
1212 (t (message "No server editing buffers exist"))))
9ae0f972 1213
98a4349c 1214(defun server-switch-buffer (&optional next-buffer killed-one)
9ae0f972 1215 "Switch to another buffer, preferably one that has a client.
6d3a46f7
KL
1216Arg NEXT-BUFFER is a suggestion; if it is a live buffer, use it.
1217
1218KILLED-ONE is t in a recursive call if we have already killed one
1219temp-file server buffer. This means we should avoid the final
1220\"switch to some other buffer\" since we've already effectively
1221done that."
ca0c7250 1222 (if (null next-buffer)
9002956f
KL
1223 (progn
1224 (let ((rest server-clients))
1225 (while (and rest (not next-buffer))
448f754f 1226 (let ((proc (car rest)))
9002956f 1227 ;; Only look at frameless clients.
448f754f
SM
1228 (when (not (process-get proc 'frame))
1229 (setq next-buffer (car (process-get proc 'buffers))))
9002956f
KL
1230 (setq rest (cdr rest)))))
1231 (and next-buffer (server-switch-buffer next-buffer killed-one))
1232 (unless (or next-buffer killed-one (window-dedicated-p (selected-window)))
1233 ;; (switch-to-buffer (other-buffer))
90ee5627 1234 (message "No server buffers remain to edit")))
9002956f 1235 (if (not (buffer-live-p next-buffer))
ca0c7250 1236 ;; If NEXT-BUFFER is a dead buffer, remove the server records for it
9ae0f972 1237 ;; and try the next surviving server buffer.
ca0c7250
SM
1238 (apply 'server-switch-buffer (server-buffer-done next-buffer))
1239 ;; OK, we know next-buffer is live, let's display and select it.
408784a7
SM
1240 (if (functionp server-window)
1241 (funcall server-window next-buffer)
1242 (let ((win (get-buffer-window next-buffer 0)))
1243 (if (and win (not server-window))
1244 ;; The buffer is already displayed: just reuse the window.
90caccca
JB
1245 (progn
1246 (select-window win)
1247 (set-buffer next-buffer))
408784a7 1248 ;; Otherwise, let's find an appropriate window.
60b4b298 1249 (cond ((window-live-p server-window)
408784a7
SM
1250 (select-window server-window))
1251 ((framep server-window)
337e3c70
JB
1252 (unless (frame-live-p server-window)
1253 (setq server-window (make-frame)))
408784a7 1254 (select-window (frame-selected-window server-window))))
337e3c70
JB
1255 (when (window-minibuffer-p (selected-window))
1256 (select-window (next-window nil 'nomini 0)))
408784a7
SM
1257 ;; Move to a non-dedicated window, if we have one.
1258 (when (window-dedicated-p (selected-window))
1259 (select-window
1260 (get-window-with-predicate
1261 (lambda (w)
1262 (and (not (window-dedicated-p w))
6ed8eeff
KL
1263 (equal (frame-terminal (window-frame w))
1264 (frame-terminal (selected-frame)))))
408784a7
SM
1265 'nomini 'visible (selected-window))))
1266 (condition-case nil
1267 (switch-to-buffer next-buffer)
1268 ;; After all the above, we might still have ended up with
1269 ;; a minibuffer/dedicated-window (if there's no other).
90caccca
JB
1270 (error (pop-to-buffer next-buffer)))))))
1271 (when server-raise-frame
1272 (select-frame-set-input-focus (window-frame (selected-window))))))
9ae0f972 1273
59e085e0 1274;;;###autoload
6ed8eeff 1275(defun server-save-buffers-kill-terminal (proc &optional arg)
c61a4448 1276 ;; Called from save-buffers-kill-terminal in files.el.
59e085e0 1277 "Offer to save each buffer, then kill PROC.
b4ca0271 1278
7540c1e0
KL
1279With prefix arg, silently save all file-visiting buffers, then kill.
1280
1281If emacsclient was started with a list of filenames to edit, then
1282only these files will be asked to be saved."
c61a4448
SM
1283 ;; save-buffers-kill-terminal occasionally calls us with proc set
1284 ;; to `nowait' (comes from the value of the `client' frame parameter).
1285 (when (processp proc)
1286 (let ((buffers (process-get proc 'buffers)))
1287 ;; If client is bufferless, emulate a normal Emacs session
1288 ;; exit and offer to save all buffers. Otherwise, offer to
1289 ;; save only the buffers belonging to the client.
1290 (save-some-buffers arg
1291 (if buffers
1292 (lambda () (memq (current-buffer) buffers))
1293 t))
1294 (server-delete-client proc))))
b4ca0271 1295
772c5eb7 1296(define-key ctl-x-map "#" 'server-edit)
df4e8a11 1297
08446d5e 1298(defun server-unload-function ()
6d3a46f7 1299 "Unload the server library."
2e8457a0 1300 (server-mode -1)
a8e0c053 1301 (substitute-key-definition 'server-edit nil ctl-x-map)
08446d5e
JB
1302 (save-current-buffer
1303 (dolist (buffer (buffer-list))
1304 (set-buffer buffer)
1305 (remove-hook 'kill-buffer-hook 'server-kill-buffer t)))
1306 ;; continue standard unloading
1307 nil)
3bb38bc2 1308
16c15321
RM
1309\f
1310(provide 'server)
c88ab9ce 1311
2e8457a0 1312;; arch-tag: 1f7ecb42-f00a-49f8-906d-61995d84c8d6
c88ab9ce 1313;;; server.el ends here