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