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