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