* server.el (server-save-buffers-kill-terminal): Args changed.
[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,
ae940284 4;; 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 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 187Please note that only buffers that still have a client are killed,
a77ad240
JB
188i.e. buffers visited with \"emacsclient --no-wait\" are never killed
189in this way."
c6a117f0
GM
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 205(defvar server-socket-dir
a77ad240
JB
206 (and (featurep 'make-network-process '(:family local))
207 (format "%s/emacs%d" (or (getenv "TMPDIR") "/tmp") (user-uid)))
208 "The directory in which to place the server socket.
209If local sockets are not supported, this is nil.")
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.
a77ad240
JB
243If NOFRAME is non-nil, let the frames live.
244Updates `server-clients'."
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 294(defvar server-log-time-function 'current-time-string
f03ea9d9 295 "Function to generate timestamps for `server-buffer'.")
88fd26a1 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
f03ea9d9 301safely let-bind buffer-local variables like `default-directory'.")
28cbade4
SM
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 327 ;; Delete the associated connection file, if applicable.
c63a334e
JB
328 ;; Although there's no 100% guarantee that the file is owned by the
329 ;; running Emacs instance, server-start uses server-running-p to check
330 ;; for possible servers before doing anything, so it *should* be ours.
331 (and (process-contact proc :server)
332 (eq (process-status proc) 'closed)
333 (ignore-errors (delete-file (process-get proc :server-file))))
9002956f
KL
334 (server-log (format "Status changed to %s: %s" (process-status proc) msg) proc)
335 (server-delete-client proc))
0c851d78 336
13ba3740
SM
337(defun server-select-display (display)
338 ;; If the current frame is on `display' we're all set.
a77ad240 339 ;; Similarly if we are unable to open frames on other displays, there's
1a4a884c
SM
340 ;; nothing more we can do.
341 (unless (or (not (fboundp 'make-frame-on-display))
342 (equal (frame-parameter (selected-frame) 'display) display))
13ba3740
SM
343 ;; Otherwise, look for an existing frame there and select it.
344 (dolist (frame (frame-list))
345 (when (equal (frame-parameter frame 'display) display)
346 (select-frame frame)))
347 ;; If there's no frame on that display yet, create and select one.
348 (unless (equal (frame-parameter (selected-frame) 'display) display)
349 (let* ((buffer (generate-new-buffer " *server-dummy*"))
350 (frame (make-frame-on-display
351 display
352 ;; Make it display (and remember) some dummy buffer, so
353 ;; we can detect later if the frame is in use or not.
ff91dc79 354 `((server-dummy-buffer . ,buffer)
13ba3740
SM
355 ;; This frame may be deleted later (see
356 ;; server-unselect-display) so we want it to be as
357 ;; unobtrusive as possible.
358 (visibility . nil)))))
359 (select-frame frame)
360 (set-window-buffer (selected-window) buffer)
361 frame))))
362
363(defun server-unselect-display (frame)
364 (when (frame-live-p frame)
365 ;; If the temporary frame is in use (displays something real), make it
366 ;; visible. If not (which can happen if the user's customizations call
367 ;; pop-to-buffer etc.), delete it to avoid preserving the connection after
368 ;; the last real frame is deleted.
369 (if (and (eq (frame-first-window frame)
370 (next-window (frame-first-window frame) 'nomini))
371 (eq (window-buffer (frame-first-window frame))
372 (frame-parameter frame 'server-dummy-buffer)))
373 ;; The temp frame still only shows one buffer, and that is the
374 ;; internal temp buffer.
375 (delete-frame frame)
376 (set-frame-parameter frame 'visibility t))
377 (kill-buffer (frame-parameter frame 'server-dummy-buffer))
378 (set-frame-parameter frame 'server-dummy-buffer nil)))
379
77134727 380(defun server-handle-delete-frame (frame)
a77ad240
JB
381 "Delete the client connection when the emacsclient frame is deleted.
382\(To be used from `delete-frame-functions'.)"
9002956f 383 (let ((proc (frame-parameter frame 'client)))
e519a50b
KL
384 (when (and (frame-live-p frame)
385 proc
160f0817 386 ;; See if this is the last frame for this client.
d5381da2 387 (>= 1 (let ((frame-num 0))
aabf0cb9 388 (dolist (f (frame-list))
160f0817
KL
389 (when (eq proc (frame-parameter f 'client))
390 (setq frame-num (1+ frame-num))))
391 frame-num)))
9002956f 392 (server-log (format "server-handle-delete-frame, frame %s" frame) proc)
de93c791 393 (server-delete-client proc 'noframe)))) ; Let delete-frame delete the frame later.
9002956f 394
6ed8eeff 395(defun server-handle-suspend-tty (terminal)
9002956f 396 "Notify the emacsclient process to suspend itself when its tty device is suspended."
6ed8eeff
KL
397 (dolist (proc (server-clients-with 'terminal terminal))
398 (server-log (format "server-handle-suspend-tty, terminal %s" terminal) proc)
6d3a46f7 399 (condition-case err
6afdd335 400 (server-send-string proc "-suspend \n")
44954c2f
SM
401 (file-error ;The pipe/socket was closed.
402 (ignore-errors (server-delete-client proc))))))
44a56b29 403
0c851d78 404(defun server-unquote-arg (arg)
6afdd335
KL
405 "Remove &-quotation from ARG.
406See `server-quote-arg' and `server-process-filter'."
0c851d78
SM
407 (replace-regexp-in-string
408 "&." (lambda (s)
409 (case (aref s 1)
410 (?& "&")
411 (?- "-")
412 (?n "\n")
413 (t " ")))
414 arg t t))
9ae0f972 415
0b0d3e0b 416(defun server-quote-arg (arg)
9002956f 417 "In ARG, insert a & before each &, each space, each newline, and -.
0b0d3e0b 418Change spaces to underscores, too, so that the return value never
6afdd335
KL
419contains a space.
420
421See `server-unquote-arg' and `server-process-filter'."
0b0d3e0b
KL
422 (replace-regexp-in-string
423 "[-&\n ]" (lambda (s)
424 (case (aref s 0)
425 (?& "&&")
426 (?- "&-")
427 (?\n "&n")
428 (?\s "&_")))
429 arg t t))
430
6afdd335 431(defun server-send-string (proc string)
a77ad240 432 "A wrapper around `process-send-string' for logging."
6afdd335
KL
433 (server-log (concat "Sent " string) proc)
434 (process-send-string proc string))
435
724629d2
SM
436(defun server-ensure-safe-dir (dir)
437 "Make sure DIR is a directory with no race-condition issues.
438Creates the directory if necessary and makes sure:
439- there's no symlink involved
440- it's owned by us
441- it's not readable/writable by anybody else."
442 (setq dir (directory-file-name dir))
443 (let ((attrs (file-attributes dir)))
444 (unless attrs
337e3c70 445 (letf (((default-file-modes) ?\700)) (make-directory dir t))
724629d2
SM
446 (setq attrs (file-attributes dir)))
447 ;; Check that it's safe for use.
da6657b7 448 (unless (and (eq t (car attrs)) (eql (nth 2 attrs) (user-uid))
337e3c70
JB
449 (or (eq system-type 'windows-nt)
450 (zerop (logand ?\077 (file-modes dir)))))
724629d2
SM
451 (error "The directory %s is unsafe" dir))))
452
7229064d 453;;;###autoload
9ae0f972 454(defun server-start (&optional leave-dead)
455 "Allow this Emacs process to be a server for client processes.
456This starts a server communications subprocess through which
6d3a46f7
KL
457client \"editors\" can send your editing commands to this Emacs
458job. To use the server, set up the program `emacsclient' in the
9ae0f972 459Emacs distribution as your standard \"editor\".
460
bd410bb0 461Optional argument LEAVE-DEAD (interactively, a prefix arg) means just
c63a334e
JB
462kill any existing server communications subprocess.
463
464If a server is already running, the server is not started.
465To force-start a server, do \\[server-force-delete] and then
466\\[server-start]."
9ae0f972 467 (interactive "P")
d6b4b3cf
KL
468 (when (or
469 (not server-clients)
470 (yes-or-no-p
471 "The current server still has clients; delete them? "))
c63a334e
JB
472 (let* ((server-dir (if server-use-tcp server-auth-dir server-socket-dir))
473 (server-file (expand-file-name server-name server-dir)))
474 (when server-process
475 ;; kill it dead!
476 (ignore-errors (delete-process server-process)))
477 ;; Delete the socket files made by previous server invocations.
478 (if (not (eq t (server-running-p server-name)))
479 ;; Remove any leftover socket or authentication file
480 (ignore-errors (delete-file server-file))
481 (setq server-mode nil) ;; already set by the minor mode code
35f372ca
JB
482 (display-warning 'server
483 (format "Emacs server named %S already running" server-name)
484 :warning)
485 (setq leave-dead t))
c63a334e
JB
486 ;; If this Emacs already had a server, clear out associated status.
487 (while server-clients
488 (server-delete-client (car server-clients)))
489 ;; Now any previous server is properly stopped.
490 (if leave-dead
491 (progn
35f372ca 492 (unless (eq t leave-dead) (server-log (message "Server stopped")))
c63a334e 493 (setq server-process nil))
974b73e8
KL
494 ;; Make sure there is a safe directory in which to place the socket.
495 (server-ensure-safe-dir server-dir)
974b73e8
KL
496 (when server-process
497 (server-log (message "Restarting server")))
498 (letf (((default-file-modes) ?\700))
e4019195 499 (add-hook 'suspend-tty-functions 'server-handle-suspend-tty)
974b73e8
KL
500 (add-hook 'delete-frame-functions 'server-handle-delete-frame)
501 (add-hook 'kill-buffer-query-functions 'server-kill-buffer-query-function)
502 (add-hook 'kill-emacs-query-functions 'server-kill-emacs-query-function)
1d515b42 503 (add-hook 'kill-emacs-hook (lambda () (server-mode -1))) ;Cleanup upon exit.
974b73e8
KL
504 (setq server-process
505 (apply #'make-network-process
506 :name server-name
507 :server t
508 :noquery t
509 :sentinel 'server-sentinel
510 :filter 'server-process-filter
511 ;; We must receive file names without being decoded.
512 ;; Those are decoded by server-process-filter according
1b0a6c68
SM
513 ;; to file-name-coding-system. Also don't get
514 ;; confused by CRs since we don't quote them.
515 :coding 'raw-text-unix
28cbade4 516 ;; The other args depend on the kind of socket used.
974b73e8
KL
517 (if server-use-tcp
518 (list :family nil
519 :service t
520 :host (or server-host 'local)
521 :plist '(:authenticated nil))
522 (list :family 'local
523 :service server-file
524 :plist '(:authenticated t)))))
525 (unless server-process (error "Could not start server process"))
c63a334e 526 (process-put server-process :server-file server-file)
974b73e8
KL
527 (when server-use-tcp
528 (let ((auth-key
529 (loop
d76e2046
JB
530 ;; The auth key is a 64-byte string of random chars in the
531 ;; range `!'..`~'.
532 for i below 64
533 collect (+ 33 (random 94)) into auth
534 finally return (concat auth))))
974b73e8
KL
535 (process-put server-process :auth-key auth-key)
536 (with-temp-file server-file
537 (set-buffer-multibyte nil)
538 (setq buffer-file-coding-system 'no-conversion)
539 (insert (format-network-address
540 (process-contact server-process :local))
541 " " (int-to-string (emacs-pid))
542 "\n" auth-key)))))))))
33186f32 543
c63a334e
JB
544;;;###autoload
545(defun server-force-delete (&optional name)
546 "Unconditionally delete connection file for server NAME.
547If server is running, it is first stopped.
548NAME defaults to `server-name'. With argument, ask for NAME."
549 (interactive
550 (list (if current-prefix-arg
551 (read-string "Server name: " nil nil server-name))))
552 (when server-mode (with-temp-message nil (server-mode -1)))
553 (let ((file (expand-file-name (or name server-name)
554 (if server-use-tcp
555 server-auth-dir
556 server-socket-dir))))
557 (condition-case nil
558 (progn
559 (delete-file file)
560 (message "Connection file %S deleted" file))
561 (file-error
562 (message "No connection file %S" file)))))
563
44954c2f 564(defun server-running-p (&optional name)
c63a334e
JB
565 "Test whether server NAME is running.
566
567Return values:
568 nil the server is definitely not running.
569 t the server seems to be running.
570 something else we cannot determine whether it's running without using
571 commands which may have to wait for a long time."
44954c2f
SM
572 (unless name (setq name server-name))
573 (condition-case nil
c63a334e
JB
574 (if server-use-tcp
575 (with-temp-buffer
576 (insert-file-contents-literally (expand-file-name name server-auth-dir))
d9569a55 577 (or (and (looking-at "127\\.0\\.0\\.1:[0-9]+ \\([0-9]+\\)")
c63a334e
JB
578 (assq 'comm
579 (system-process-attributes
580 (string-to-number (match-string 1))))
581 t)
582 :other))
44954c2f
SM
583 (delete-process
584 (make-network-process
585 :name "server-client-test" :family 'local :server nil :noquery t
586 :service (expand-file-name name server-socket-dir)))
587 t)
588 (file-error nil)))
589
33186f32
DL
590;;;###autoload
591(define-minor-mode server-mode
592 "Toggle Server mode.
593With ARG, turn Server mode on if ARG is positive, off otherwise.
594Server mode runs a process that accepts commands from the
595`emacsclient' program. See `server-start' and Info node `Emacs server'."
596 :global t
597 :group 'server
bf247b6e 598 :version "22.1"
33186f32
DL
599 ;; Fixme: Should this check for an existing server socket and do
600 ;; nothing if there is one (for multiple Emacs sessions)?
601 (server-start (not server-mode)))
9ae0f972 602\f
13ba3740
SM
603(defun server-eval-and-print (expr proc)
604 "Eval EXPR and send the result back to client PROC."
605 (let ((v (eval (car (read-from-string expr)))))
606 (when (and v proc)
607 (with-temp-buffer
608 (let ((standard-output (current-buffer)))
609 (pp v)
610 (let ((text (buffer-substring-no-properties
611 (point-min) (point-max))))
612 (server-send-string
613 proc (format "-print %s\n"
614 (server-quote-arg text)))))))))
615
616(defun server-create-tty-frame (tty type proc)
4419b755 617 (add-to-list 'frame-inherited-parameters 'client)
13ba3740
SM
618 (let ((frame
619 (server-with-environment (process-get proc 'env)
620 '("LANG" "LC_CTYPE" "LC_ALL"
621 ;; For tgetent(3); list according to ncurses(3).
622 "BAUDRATE" "COLUMNS" "ESCDELAY" "HOME" "LINES"
623 "NCURSES_ASSUMED_COLORS" "NCURSES_NO_PADDING"
624 "NCURSES_NO_SETBUF" "TERM" "TERMCAP" "TERMINFO"
c48254fb 625 "TERMINFO_DIRS" "TERMPATH"
13ba3740
SM
626 ;; rxvt wants these
627 "COLORFGBG" "COLORTERM")
052056a9
CY
628 (make-frame-on-tty tty type
629 ;; Ignore nowait here; we always need to
630 ;; clean up opened ttys when the client dies.
631 `((client . ,proc)
632 ;; This is a leftover from an earlier
633 ;; attempt at making it possible for process
634 ;; run in the server process to use the
635 ;; environment of the client process.
636 ;; It has no effect now and to make it work
637 ;; we'd need to decide how to make
638 ;; process-environment interact with client
639 ;; envvars, and then to change the
640 ;; C functions `child_setup' and
641 ;; `getenv_internal' accordingly.
642 (environment . ,(process-get proc 'env)))))))
643
e159b869
SM
644 ;; ttys don't use the `display' parameter, but callproc.c does to set
645 ;; the DISPLAY environment on subprocesses.
646 (set-frame-parameter frame 'display
647 (getenv-internal "DISPLAY" (process-get proc 'env)))
13ba3740 648 (select-frame frame)
448f754f 649 (process-put proc 'frame frame)
448f754f 650 (process-put proc 'terminal (frame-terminal frame))
13ba3740
SM
651
652 ;; Display *scratch* by default.
653 (switch-to-buffer (get-buffer-create "*scratch*") 'norecord)
654
655 ;; Reply with our pid.
656 (server-send-string proc (concat "-emacs-pid "
657 (number-to-string (emacs-pid)) "\n"))
658 frame))
659
660(defun server-create-window-system-frame (display nowait proc)
4419b755 661 (add-to-list 'frame-inherited-parameters 'client)
e159b869 662 (if (not (fboundp 'make-frame-on-display))
13ba3740
SM
663 (progn
664 ;; This emacs does not support X.
665 (server-log "Window system unsupported" proc)
666 (server-send-string proc "-window-system-unsupported \n")
667 nil)
668 ;; Flag frame as client-created, but use a dummy client.
669 ;; This will prevent the frame from being deleted when
670 ;; emacsclient quits while also preventing
671 ;; `server-save-buffers-kill-terminal' from unexpectedly
672 ;; killing emacs on that frame.
673 (let* ((params `((client . ,(if nowait 'nowait proc))
4419b755 674 ;; This is a leftover, see above.
13ba3740
SM
675 (environment . ,(process-get proc 'env))))
676 (frame (make-frame-on-display
677 (or display
678 (frame-parameter nil 'display)
679 (getenv "DISPLAY")
680 (error "Please specify display"))
448f754f 681 params)))
13ba3740 682 (server-log (format "%s created" frame) proc)
13ba3740 683 (select-frame frame)
448f754f
SM
684 (process-put proc 'frame frame)
685 (process-put proc 'terminal (frame-terminal frame))
13ba3740
SM
686
687 ;; Display *scratch* by default.
688 (switch-to-buffer (get-buffer-create "*scratch*") 'norecord)
689 frame)))
690
13ba3740
SM
691(defun server-goto-toplevel (proc)
692 (condition-case nil
693 ;; If we're running isearch, we must abort it to allow Emacs to
694 ;; display the buffer and switch to it.
695 (dolist (buffer (buffer-list))
696 (with-current-buffer buffer
697 (when (bound-and-true-p isearch-mode)
698 (isearch-cancel))))
699 ;; Signaled by isearch-cancel.
700 (quit (message nil)))
701 (when (> (recursion-depth) 0)
702 ;; We're inside a minibuffer already, so if the emacs-client is trying
703 ;; to open a frame on a new display, we might end up with an unusable
704 ;; frame because input from that display will be blocked (until exiting
705 ;; the minibuffer). Better exit this minibuffer right away.
706 ;; Similarly with recursive-edits such as the splash screen.
707 (run-with-timer 0 nil (lexical-let ((proc proc))
708 (lambda () (server-execute-continuation proc))))
709 (top-level)))
710
711;; We use various special properties on process objects:
712;; - `env' stores the info about the environment of the emacsclient process.
713;; - `continuation' is a no-arg function that we need to execute. It contains
714;; commands we wanted to execute in some earlier invocation of the process
715;; filter but that we somehow were unable to process at that time
716;; (e.g. because we first need to throw to the toplevel).
717
718(defun server-execute-continuation (proc)
719 (let ((continuation (process-get proc 'continuation)))
720 (process-put proc 'continuation nil)
721 (if continuation (ignore-errors (funcall continuation)))))
722
337e3c70 723(defun* server-process-filter (proc string)
33186f32 724 "Process a request from the server to edit some files.
6afdd335 725PROC is the server process. STRING consists of a sequence of
909049cb
JB
726commands prefixed by a dash. Some commands have arguments;
727these are &-quoted and need to be decoded by `server-unquote-arg'.
728The filter parses and executes these commands.
6afdd335
KL
729
730To illustrate the protocol, here is an example command that
731emacsclient sends to create a new X frame (note that the whole
732sequence is sent on a single line):
733
909049cb
JB
734 -env HOME=/home/lorentey
735 -env DISPLAY=:0.0
6afdd335
KL
736 ... lots of other -env commands
737 -display :0.0
738 -window-system
739
6afdd335
KL
740The following commands are accepted by the server:
741
974b73e8
KL
742`-auth AUTH-STRING'
743 Authenticate the client using the secret authentication string
a38daa0a 744 AUTH-STRING.
974b73e8 745
59e085e0 746`-env NAME=VALUE'
6afdd335
KL
747 An environment variable on the client side.
748
2828d5f9
KL
749`-dir DIRNAME'
750 The current working directory of the client process.
751
92071250
KL
752`-current-frame'
753 Forbid the creation of new frames.
754
6afdd335
KL
755`-nowait'
756 Request that the next frame created should not be
757 associated with this client.
758
759`-display DISPLAY'
760 Set the display name to open X frames on.
761
762`-position LINE[:COLUMN]'
763 Go to the given line and column number
764 in the next file opened.
765
766`-file FILENAME'
767 Load the given file in the current frame.
768
769`-eval EXPR'
770 Evaluate EXPR as a Lisp expression and return the
771 result in -print commands.
772
773`-window-system'
774 Open a new X frame.
775
776`-tty DEVICENAME TYPE'
777 Open a new tty frame at the client.
778
6afdd335
KL
779`-suspend'
780 Suspend this tty frame. The client sends this string in
781 response to SIGTSTP and SIGTTOU. The server must cease all I/O
782 on this tty until it gets a -resume command.
783
2828d5f9 784`-resume'
c48254fb 785 Resume this tty frame. The client sends this string when it
2828d5f9
KL
786 gets the SIGCONT signal and it is the foreground process on its
787 controlling tty.
788
6afdd335 789`-ignore COMMENT'
909049cb
JB
790 Do nothing, but put the comment in the server log.
791 Useful for debugging.
6afdd335
KL
792
793
794The following commands are accepted by the client:
795
6afdd335
KL
796`-emacs-pid PID'
797 Describes the process id of the Emacs process;
798 used to forward window change signals to it.
799
800`-window-system-unsupported'
c48254fb
JB
801 Signals that the server does not support creating X frames;
802 the client must try again with a tty frame.
6afdd335
KL
803
804`-print STRING'
805 Print STRING on stdout. Used to send values
806 returned by -eval.
807
808`-error DESCRIPTION'
809 Signal an error (but continue processing).
810
811`-suspend'
c48254fb
JB
812 Suspend this terminal, i.e., stop the client process.
813 Sent when the user presses C-z."
6afdd335 814 (server-log (concat "Received " string) proc)
337e3c70
JB
815 ;; First things first: let's check the authentication
816 (unless (process-get proc :authenticated)
38b9f0f3 817 (if (and (string-match "-auth \\([!-~]+\\)\n?" string)
974b73e8
KL
818 (equal (match-string 1 string) (process-get proc :auth-key)))
819 (progn
820 (setq string (substring string (match-end 0)))
821 (process-put proc :authenticated t)
822 (server-log "Authentication successful" proc))
337e3c70 823 (server-log "Authentication failed" proc)
974b73e8
KL
824 (server-send-string
825 proc (concat "-error " (server-quote-arg "Authentication failed")))
337e3c70
JB
826 (delete-process proc)
827 ;; We return immediately
828 (return-from server-process-filter)))
3f7ef08e
SM
829 (let ((prev (process-get proc 'previous-string)))
830 (when prev
831 (setq string (concat prev string))
832 (process-put proc 'previous-string nil)))
a9298135 833 (condition-case err
0b0d3e0b 834 (progn
9002956f 835 (server-add-client proc)
13ba3740
SM
836 (if (not (string-match "\n" string))
837 ;; Save for later any partial line that remains.
838 (when (> (length string) 0)
839 (process-put proc 'previous-string string))
c48254fb 840
13ba3740
SM
841 ;; In earlier versions of server.el (where we used an `emacsserver'
842 ;; process), there could be multiple lines. Nowadays this is not
843 ;; supported any more.
844 (assert (eq (match-end 0) (length string)))
0b0d3e0b
KL
845 (let ((request (substring string 0 (match-beginning 0)))
846 (coding-system (and default-enable-multibyte-characters
847 (or file-name-coding-system
848 default-file-name-coding-system)))
9002956f
KL
849 nowait ; t if emacsclient does not want to wait for us.
850 frame ; The frame that was opened for the client (if any).
59e085e0 851 display ; Open the frame on this display.
0b0d3e0b 852 dontkill ; t if the client should not be killed.
650d0dbc 853 commands
2828d5f9 854 dir
cd9c54eb 855 use-current-frame
650d0dbc
CY
856 tty-name ;nil, `window-system', or the tty name.
857 tty-type ;string.
858 files
859 filepos
bfb74e75
DK
860 command-line-args-left
861 arg)
0b0d3e0b
KL
862 ;; Remove this line from STRING.
863 (setq string (substring string (match-end 0)))
bfb74e75
DK
864 (setq command-line-args-left
865 (mapcar 'server-unquote-arg (split-string request " " t)))
866 (while (setq arg (pop command-line-args-left))
0b0d3e0b 867 (cond
13ba3740 868 ;; -version CLIENT-VERSION: obsolete at birth.
bfb74e75
DK
869 ((and (equal "-version" arg) command-line-args-left)
870 (pop command-line-args-left))
0b0d3e0b 871
9002956f 872 ;; -nowait: Emacsclient won't wait for a result.
0b0d3e0b
KL
873 ((equal "-nowait" arg) (setq nowait t))
874
92071250 875 ;; -current-frame: Don't create frames.
cd9c54eb 876 ((equal "-current-frame" arg) (setq use-current-frame t))
92071250 877
9002956f 878 ;; -display DISPLAY:
59e085e0 879 ;; Open X frames on the given display instead of the default.
bfb74e75 880 ((and (equal "-display" arg) command-line-args-left)
ff91dc79
SM
881 (setq display (pop command-line-args-left))
882 (if (zerop (length display)) (setq display nil)))
0b0d3e0b 883
9002956f 884 ;; -window-system: Open a new X frame.
0b0d3e0b 885 ((equal "-window-system" arg)
13ba3740
SM
886 (setq dontkill t)
887 (setq tty-name 'window-system))
9002956f
KL
888
889 ;; -resume: Resume a suspended tty frame.
0b0d3e0b 890 ((equal "-resume" arg)
448f754f 891 (lexical-let ((terminal (process-get proc 'terminal)))
0b0d3e0b 892 (setq dontkill t)
13ba3740
SM
893 (push (lambda ()
894 (when (eq (terminal-live-p terminal) t)
895 (resume-tty terminal)))
896 commands)))
0b0d3e0b 897
9002956f
KL
898 ;; -suspend: Suspend the client's frame. (In case we
899 ;; get out of sync, and a C-z sends a SIGTSTP to
900 ;; emacsclient.)
0b0d3e0b 901 ((equal "-suspend" arg)
448f754f 902 (lexical-let ((terminal (process-get proc 'terminal)))
0b0d3e0b 903 (setq dontkill t)
13ba3740
SM
904 (push (lambda ()
905 (when (eq (terminal-live-p terminal) t)
906 (suspend-tty terminal)))
907 commands)))
0b0d3e0b 908
9002956f
KL
909 ;; -ignore COMMENT: Noop; useful for debugging emacsclient.
910 ;; (The given comment appears in the server log.)
bfb74e75
DK
911 ((and (equal "-ignore" arg) command-line-args-left
912 (setq dontkill t)
913 (pop command-line-args-left)))
0b0d3e0b 914
9002956f 915 ;; -tty DEVICE-NAME TYPE: Open a new tty frame at the client.
13ba3740 916 ((and (equal "-tty" arg)
bfb74e75
DK
917 (cdr command-line-args-left))
918 (setq tty-name (pop command-line-args-left)
919 tty-type (pop command-line-args-left)
cd9c54eb
CY
920 dontkill (or dontkill
921 (not use-current-frame))))
13ba3740
SM
922
923 ;; -position LINE[:COLUMN]: Set point to the given
924 ;; position in the next file.
925 ((and (equal "-position" arg)
bfb74e75
DK
926 command-line-args-left
927 (string-match "\\+\\([0-9]+\\)\\(?::\\([0-9]+\\)\\)?"
928 (car command-line-args-left)))
929 (setq arg (pop command-line-args-left))
656d4706
SM
930 (setq filepos
931 (cons (string-to-number (match-string 1 arg))
932 (string-to-number (or (match-string 2 arg) "")))))
0b0d3e0b 933
9002956f 934 ;; -file FILENAME: Load the given file.
13ba3740 935 ((and (equal "-file" arg)
bfb74e75
DK
936 command-line-args-left)
937 (let ((file (pop command-line-args-left)))
0b0d3e0b
KL
938 (if coding-system
939 (setq file (decode-coding-string file coding-system)))
940 (setq file (command-line-normalize-file-name file))
656d4706
SM
941 (push (cons file filepos) files)
942 (server-log (format "New file: %s %s"
943 file (or filepos "")) proc))
944 (setq filepos nil))
0b0d3e0b 945
9002956f 946 ;; -eval EXPR: Evaluate a Lisp expression.
13ba3740 947 ((and (equal "-eval" arg)
bfb74e75 948 command-line-args-left)
cd9c54eb
CY
949 (if use-current-frame
950 (setq use-current-frame 'always))
bfb74e75 951 (lexical-let ((expr (pop command-line-args-left)))
0b0d3e0b
KL
952 (if coding-system
953 (setq expr (decode-coding-string expr coding-system)))
13ba3740
SM
954 (push (lambda () (server-eval-and-print expr proc))
955 commands)
656d4706 956 (setq filepos nil)))
0b0d3e0b 957
59e085e0 958 ;; -env NAME=VALUE: An environment variable.
bfb74e75
DK
959 ((and (equal "-env" arg) command-line-args-left)
960 (let ((var (pop command-line-args-left)))
da8e8fc1 961 ;; XXX Variables should be encoded as in getenv/setenv.
13ba3740
SM
962 (process-put proc 'env
963 (cons var (process-get proc 'env)))))
9002956f 964
2828d5f9 965 ;; -dir DIRNAME: The cwd of the emacsclient process.
bfb74e75
DK
966 ((and (equal "-dir" arg) command-line-args-left)
967 (setq dir (pop command-line-args-left))
2828d5f9
KL
968 (if coding-system
969 (setq dir (decode-coding-string dir coding-system)))
970 (setq dir (command-line-normalize-file-name dir)))
971
0b0d3e0b 972 ;; Unknown command.
bfb74e75 973 (t (error "Unknown command: %s" arg))))
c48254fb 974
cd9c54eb
CY
975 (setq frame
976 (cond
977 ((and use-current-frame
978 (or (eq use-current-frame 'always)
979 ;; We can't use the Emacs daemon's
980 ;; terminal frame.
d9bf544c
CY
981 (not (and (daemonp)
982 (= (length (frame-list)) 1)
cd9c54eb
CY
983 (eq (selected-frame)
984 terminal-frame)))))
d9bf544c 985 (setq tty-name nil tty-type nil)
cd9c54eb
CY
986 (if display (server-select-display display)))
987 ((eq tty-name 'window-system)
988 (server-create-window-system-frame display nowait proc))
650d0dbc
CY
989 ;; When resuming on a tty, tty-name is nil.
990 (tty-name
991 (server-create-tty-frame tty-name tty-type proc))))
13ba3740 992
28cbade4
SM
993 (process-put
994 proc 'continuation
995 (lexical-let ((proc proc)
996 (files files)
997 (nowait nowait)
998 (commands commands)
999 (dontkill dontkill)
1000 (frame frame)
1001 (dir dir)
1002 (tty-name tty-name))
1003 (lambda ()
1004 (with-current-buffer (get-buffer-create server-buffer)
1005 ;; Use the same cwd as the emacsclient, if possible, so
1006 ;; relative file names work correctly, even in `eval'.
1007 (let ((default-directory
f03ea9d9
JB
1008 (if (and dir (file-directory-p dir))
1009 dir default-directory)))
28cbade4
SM
1010 (server-execute proc files nowait commands
1011 dontkill frame tty-name))))))
13ba3740
SM
1012
1013 (when (or frame files)
1014 (server-goto-toplevel proc))
1015
1016 (server-execute-continuation proc))))
a9298135 1017 ;; condition-case
13ba3740
SM
1018 (error (server-return-error proc err))))
1019
1020(defun server-execute (proc files nowait commands dontkill frame tty-name)
1021 (condition-case err
448f754f 1022 (let* ((buffers
13ba3740
SM
1023 (when files
1024 (run-hooks 'pre-command-hook)
448f754f 1025 (prog1 (server-visit-files files proc nowait)
13ba3740
SM
1026 (run-hooks 'post-command-hook)))))
1027
1028 (mapc 'funcall (nreverse commands))
c48254fb 1029
13ba3740
SM
1030 ;; Delete the client if necessary.
1031 (cond
1032 (nowait
1033 ;; Client requested nowait; return immediately.
1034 (server-log "Close nowait client" proc)
1035 (server-delete-client proc))
1036 ((and (not dontkill) (null buffers))
1037 ;; This client is empty; get rid of it immediately.
1038 (server-log "Close empty client" proc)
1039 (server-delete-client proc)))
1040 (cond
1041 ((or isearch-mode (minibufferp))
1042 nil)
1043 ((and frame (null buffers))
1044 (message "%s" (substitute-command-keys
1045 "When done with this frame, type \\[delete-frame]")))
1046 ((not (null buffers))
ee0aed46 1047 (server-switch-buffer (car buffers) nil (cdr (car files)))
13ba3740
SM
1048 (run-hooks 'server-switch-hook)
1049 (unless nowait
1050 (message "%s" (substitute-command-keys
1051 "When done with a buffer, type \\[server-edit]")))))
1052 (when (and frame (null tty-name))
1053 (server-unselect-display frame)))
1054 (error (server-return-error proc err))))
1055
1056(defun server-return-error (proc err)
1057 (ignore-errors
1058 (server-send-string
1059 proc (concat "-error " (server-quote-arg
1060 (error-message-string err))))
1061 (server-log (error-message-string err) proc)
1062 (delete-process proc)))
9ae0f972 1063
656d4706
SM
1064(defun server-goto-line-column (line-col)
1065 "Move point to the position indicated in LINE-COL.
1066LINE-COL should be a pair (LINE . COL)."
1067 (when line-col
1068 (goto-line (car line-col))
1069 (let ((column-number (cdr line-col)))
1070 (when (> column-number 0)
1071 (move-to-column (1- column-number))))))
6b98185f 1072
448f754f 1073(defun server-visit-files (files proc &optional nowait)
c5b0a355 1074 "Find FILES and return a list of buffers created.
656d4706
SM
1075FILES is an alist whose elements are (FILENAME . FILEPOS)
1076where FILEPOS can be nil or a pair (LINENUMBER . COLUMNNUMBER).
448f754f 1077PROC is the client that requested this operation.
dfa35e6b
RS
1078NOWAIT non-nil means this client is not waiting for the results,
1079so don't mark these buffers specially, just visit them normally."
e82e73c2 1080 ;; Bind last-nonmenu-event to force use of keyboard, not mouse, for queries.
44a56b29 1081 (let ((last-nonmenu-event t) client-record)
3a0ce849
RS
1082 ;; Restore the current buffer afterward, but not using save-excursion,
1083 ;; because we don't want to save point in this buffer
1084 ;; if it happens to be one of those specified by the server.
44a56b29
SM
1085 (save-current-buffer
1086 (dolist (file files)
1087 ;; If there is an existing buffer modified or the file is
1088 ;; modified, revert it. If there is an existing buffer with
1089 ;; deleted file, offer to write it.
cd7320d4 1090 (let* ((minibuffer-auto-raise (or server-raise-frame
974b73e8 1091 minibuffer-auto-raise))
c2d0d432 1092 (filen (car file))
44a56b29 1093 (obuf (get-file-buffer filen)))
c398358a 1094 (add-to-history 'file-name-history filen)
656d4706
SM
1095 (if (null obuf)
1096 (set-buffer (find-file-noselect filen))
1097 (set-buffer obuf)
1098 (cond ((file-exists-p filen)
1099 (when (not (verify-visited-file-modtime obuf))
1100 (revert-buffer t nil)))
1101 (t
1102 (when (y-or-n-p
1103 (concat "File no longer exists: " filen
1104 ", write buffer to file? "))
1105 (write-file filen))))
1106 (unless server-buffer-clients
1107 (setq server-existing-buffer t)))
1108 (server-goto-line-column (cdr file))
1109 (run-hooks 'server-visit-hook))
44a56b29
SM
1110 (unless nowait
1111 ;; When the buffer is killed, inform the clients.
1112 (add-hook 'kill-buffer-hook 'server-kill-buffer nil t)
448f754f 1113 (push proc server-buffer-clients))
c5b0a355
KL
1114 (push (current-buffer) client-record)))
1115 (unless nowait
448f754f
SM
1116 (process-put proc 'buffers
1117 (nconc (process-get proc 'buffers) client-record)))
c5b0a355 1118 client-record))
9ae0f972 1119\f
b392bac9 1120(defun server-buffer-done (buffer &optional for-killing)
9ae0f972 1121 "Mark BUFFER as \"done\" for its client(s).
9184aafb
RS
1122This buries the buffer, then returns a list of the form (NEXT-BUFFER KILLED).
1123NEXT-BUFFER is another server buffer, as a suggestion for what to select next,
8b3e840e
SM
1124or nil. KILLED is t if we killed BUFFER (typically, because it was visiting
1125a temp file).
1126FOR-KILLING if non-nil indicates that we are called from `kill-buffer'."
0c851d78 1127 (let ((next-buffer nil)
9002956f 1128 (killed nil))
448f754f
SM
1129 (dolist (proc server-clients)
1130 (let ((buffers (process-get proc 'buffers)))
8b3e840e 1131 (or next-buffer
9002956f
KL
1132 (setq next-buffer (nth 1 (memq buffer buffers))))
1133 (when buffers ; Ignore bufferless clients.
1134 (setq buffers (delq buffer buffers))
448f754f 1135 ;; Delete all dead buffers from PROC.
9002956f
KL
1136 (dolist (b buffers)
1137 (and (bufferp b)
1138 (not (buffer-live-p b))
1139 (setq buffers (delq b buffers))))
448f754f 1140 (process-put proc 'buffers buffers)
9002956f
KL
1141 ;; If client now has no pending buffers,
1142 ;; tell it that it is done, and forget it entirely.
1143 (unless buffers
448f754f 1144 (server-log "Close" proc)
737e5c83
CY
1145 (if for-killing
1146 ;; `server-delete-client' might delete the client's
1147 ;; frames, which might change the current buffer. We
1148 ;; don't want that (bug#640).
1149 (save-current-buffer
1150 (server-delete-client proc))
1151 (server-delete-client proc))))))
337e3c70
JB
1152 (when (and (bufferp buffer) (buffer-name buffer))
1153 ;; We may or may not kill this buffer;
1154 ;; if we do, do not call server-buffer-done recursively
1155 ;; from kill-buffer-hook.
1156 (let ((server-kill-buffer-running t))
1157 (with-current-buffer buffer
1158 (setq server-buffer-clients nil)
1159 (run-hooks 'server-done-hook))
1160 ;; Notice whether server-done-hook killed the buffer.
1161 (if (null (buffer-name buffer))
1162 (setq killed t)
1163 ;; Don't bother killing or burying the buffer
1164 ;; when we are called from kill-buffer.
1165 (unless for-killing
1166 (when (and (not killed)
1167 server-kill-new-buffers
1168 (with-current-buffer buffer
1169 (not server-existing-buffer)))
599f9a5c 1170 (setq killed t)
337e3c70
JB
1171 (bury-buffer buffer)
1172 (kill-buffer buffer))
1173 (unless killed
1174 (if (server-temp-file-p buffer)
1175 (progn
1176 (kill-buffer buffer)
1177 (setq killed t))
1178 (bury-buffer buffer)))))))
9184aafb 1179 (list next-buffer killed)))
9ae0f972 1180
408784a7 1181(defun server-temp-file-p (&optional buffer)
9ae0f972 1182 "Return non-nil if BUFFER contains a file considered temporary.
1183These are files whose names suggest they are repeatedly
1184reused to pass information to another program.
1185
1186The variable `server-temp-file-regexp' controls which filenames
1187are considered temporary."
1188 (and (buffer-file-name buffer)
a77ad240 1189 (string-match-p server-temp-file-regexp (buffer-file-name buffer))))
9ae0f972 1190
1191(defun server-done ()
cc9875f9 1192 "Offer to save current buffer, mark it as \"done\" for clients.
ed9ae328
RS
1193This kills or buries the buffer, then returns a list
1194of the form (NEXT-BUFFER KILLED). NEXT-BUFFER is another server buffer,
1195as a suggestion for what to select next, or nil.
1196KILLED is t if we killed BUFFER, which happens if it was created
1197specifically for the clients and did not exist before their request for it."
408784a7
SM
1198 (when server-buffer-clients
1199 (if (server-temp-file-p)
1200 ;; For a temp file, save, and do make a non-numeric backup
1201 ;; (unless make-backup-files is nil).
1202 (let ((version-control nil)
1203 (buffer-backed-up nil))
1204 (save-buffer))
337e3c70
JB
1205 (when (and (buffer-modified-p)
1206 buffer-file-name
1207 (y-or-n-p (concat "Save file " buffer-file-name "? ")))
1208 (save-buffer)))
408784a7 1209 (server-buffer-done (current-buffer))))
faf931a8 1210
71207de2
RS
1211;; Ask before killing a server buffer.
1212;; It was suggested to release its client instead,
1213;; but I think that is dangerous--the client would proceed
1214;; using whatever is on disk in that file. -- rms.
03d78665 1215(defun server-kill-buffer-query-function ()
9002956f 1216 "Ask before killing a server buffer."
03d78665 1217 (or (not server-buffer-clients)
114a8b8c
KL
1218 (let ((res t))
1219 (dolist (proc server-buffer-clients res)
448f754f
SM
1220 (when (and (memq proc server-clients)
1221 (eq (process-status proc) 'open))
1222 (setq res nil))))
03d78665
RS
1223 (yes-or-no-p (format "Buffer `%s' still has clients; kill it? "
1224 (buffer-name (current-buffer))))))
1225
03d78665 1226(defun server-kill-emacs-query-function ()
c48254fb 1227 "Ask before exiting Emacs if it has live clients."
9002956f
KL
1228 (or (not server-clients)
1229 (let (live-client)
448f754f
SM
1230 (dolist (proc server-clients live-client)
1231 (when (memq t (mapcar 'buffer-live-p (process-get
1232 proc 'buffers)))
974b73e8 1233 (setq live-client t))))
9002956f 1234 (yes-or-no-p "This Emacs session has clients; exit anyway? ")))
b392bac9 1235
fb873cfc 1236(defvar server-kill-buffer-running nil
599f9a5c 1237 "Non-nil while `server-kill-buffer' or `server-buffer-done' is running.")
fb873cfc 1238
b392bac9 1239(defun server-kill-buffer ()
6d3a46f7
KL
1240 "Remove the current buffer from its clients' buffer list.
1241Designed to be added to `kill-buffer-hook'."
fb873cfc
RS
1242 ;; Prevent infinite recursion if user has made server-done-hook
1243 ;; call kill-buffer.
1244 (or server-kill-buffer-running
599f9a5c
RS
1245 (and server-buffer-clients
1246 (let ((server-kill-buffer-running t))
1247 (when server-process
1248 (server-buffer-done (current-buffer) t))))))
9ae0f972 1249\f
1250(defun server-edit (&optional arg)
1251 "Switch to next server editing buffer; say \"Done\" for current buffer.
1252If a server buffer is current, it is marked \"done\" and optionally saved.
ed9ae328 1253The buffer is also killed if it did not exist before the clients asked for it.
9ae0f972 1254When all of a client's buffers are marked as \"done\", the client is notified.
1255
1256Temporary files such as MH <draft> files are always saved and backed up,
991298c3
RS
1257no questions asked. (The variable `make-backup-files', if nil, still
1258inhibits a backup; you can set it locally in a particular buffer to
1259prevent a backup for it.) The variable `server-temp-file-regexp' controls
9ae0f972 1260which filenames are considered temporary.
1261
64f51134 1262If invoked with a prefix argument, or if there is no server process running,
9ae0f972 1263starts server process and that is all. Invoked by \\[server-edit]."
9ae0f972 1264 (interactive "P")
6b519504 1265 (cond
95eefb35
JB
1266 ((or arg
1267 (not server-process)
1268 (memq (process-status server-process) '(signal exit)))
1269 (server-mode 1))
1270 (server-clients (apply 'server-switch-buffer (server-done)))
1271 (t (message "No server editing buffers exist"))))
9ae0f972 1272
ee0aed46 1273(defun server-switch-buffer (&optional next-buffer killed-one filepos)
9ae0f972 1274 "Switch to another buffer, preferably one that has a client.
6d3a46f7
KL
1275Arg NEXT-BUFFER is a suggestion; if it is a live buffer, use it.
1276
1277KILLED-ONE is t in a recursive call if we have already killed one
1278temp-file server buffer. This means we should avoid the final
1279\"switch to some other buffer\" since we've already effectively
ee0aed46
CY
1280done that.
1281
1282FILEPOS specifies a new buffer position for NEXT-BUFFER, if we
1283visit NEXT-BUFFER in an existing window. If non-nil, it should
1284be a cons cell (LINENUMBER . COLUMNNUMBER)."
ca0c7250 1285 (if (null next-buffer)
9002956f
KL
1286 (progn
1287 (let ((rest server-clients))
1288 (while (and rest (not next-buffer))
448f754f 1289 (let ((proc (car rest)))
a7ce6c7f
AS
1290 ;; Only look at frameless clients, or those in the selected
1291 ;; frame.
1292 (when (or (not (process-get proc 'frame))
1293 (eq (process-get proc 'frame) (selected-frame)))
448f754f 1294 (setq next-buffer (car (process-get proc 'buffers))))
9002956f
KL
1295 (setq rest (cdr rest)))))
1296 (and next-buffer (server-switch-buffer next-buffer killed-one))
1297 (unless (or next-buffer killed-one (window-dedicated-p (selected-window)))
1298 ;; (switch-to-buffer (other-buffer))
90ee5627 1299 (message "No server buffers remain to edit")))
9002956f 1300 (if (not (buffer-live-p next-buffer))
ca0c7250 1301 ;; If NEXT-BUFFER is a dead buffer, remove the server records for it
9ae0f972 1302 ;; and try the next surviving server buffer.
ca0c7250
SM
1303 (apply 'server-switch-buffer (server-buffer-done next-buffer))
1304 ;; OK, we know next-buffer is live, let's display and select it.
408784a7
SM
1305 (if (functionp server-window)
1306 (funcall server-window next-buffer)
1307 (let ((win (get-buffer-window next-buffer 0)))
1308 (if (and win (not server-window))
ee0aed46
CY
1309 ;; The buffer is already displayed: just reuse the
1310 ;; window. If FILEPOS is non-nil, use it to replace the
1311 ;; window's own value of point.
90caccca
JB
1312 (progn
1313 (select-window win)
ee0aed46
CY
1314 (set-buffer next-buffer)
1315 (when filepos
1316 (server-goto-line-column filepos)))
408784a7 1317 ;; Otherwise, let's find an appropriate window.
60b4b298 1318 (cond ((window-live-p server-window)
408784a7
SM
1319 (select-window server-window))
1320 ((framep server-window)
337e3c70
JB
1321 (unless (frame-live-p server-window)
1322 (setq server-window (make-frame)))
408784a7 1323 (select-window (frame-selected-window server-window))))
337e3c70
JB
1324 (when (window-minibuffer-p (selected-window))
1325 (select-window (next-window nil 'nomini 0)))
408784a7
SM
1326 ;; Move to a non-dedicated window, if we have one.
1327 (when (window-dedicated-p (selected-window))
1328 (select-window
1329 (get-window-with-predicate
1330 (lambda (w)
1331 (and (not (window-dedicated-p w))
6ed8eeff
KL
1332 (equal (frame-terminal (window-frame w))
1333 (frame-terminal (selected-frame)))))
408784a7
SM
1334 'nomini 'visible (selected-window))))
1335 (condition-case nil
1336 (switch-to-buffer next-buffer)
1337 ;; After all the above, we might still have ended up with
1338 ;; a minibuffer/dedicated-window (if there's no other).
90caccca
JB
1339 (error (pop-to-buffer next-buffer)))))))
1340 (when server-raise-frame
1341 (select-frame-set-input-focus (window-frame (selected-window))))))
9ae0f972 1342
59e085e0 1343;;;###autoload
6ed8eeff 1344(defun server-save-buffers-kill-terminal (proc &optional arg)
c61a4448 1345 ;; Called from save-buffers-kill-terminal in files.el.
59e085e0 1346 "Offer to save each buffer, then kill PROC.
b4ca0271 1347
a77ad240 1348With ARG non-nil, silently save all file-visiting buffers, then kill.
7540c1e0
KL
1349
1350If emacsclient was started with a list of filenames to edit, then
1351only these files will be asked to be saved."
c61a4448
SM
1352 (when (processp proc)
1353 (let ((buffers (process-get proc 'buffers)))
1354 ;; If client is bufferless, emulate a normal Emacs session
1355 ;; exit and offer to save all buffers. Otherwise, offer to
1356 ;; save only the buffers belonging to the client.
1357 (save-some-buffers arg
1358 (if buffers
1359 (lambda () (memq (current-buffer) buffers))
1360 t))
1361 (server-delete-client proc))))
b4ca0271 1362
772c5eb7 1363(define-key ctl-x-map "#" 'server-edit)
df4e8a11 1364
08446d5e 1365(defun server-unload-function ()
6d3a46f7 1366 "Unload the server library."
2e8457a0 1367 (server-mode -1)
a8e0c053 1368 (substitute-key-definition 'server-edit nil ctl-x-map)
08446d5e
JB
1369 (save-current-buffer
1370 (dolist (buffer (buffer-list))
1371 (set-buffer buffer)
1372 (remove-hook 'kill-buffer-hook 'server-kill-buffer t)))
1373 ;; continue standard unloading
1374 nil)
3bb38bc2 1375
16c15321
RM
1376\f
1377(provide 'server)
c88ab9ce 1378
2e8457a0 1379;; arch-tag: 1f7ecb42-f00a-49f8-906d-61995d84c8d6
c88ab9ce 1380;;; server.el ends here