comparison lisp/server.el @ 84601:c38a9291ef0a

(server-clients): Only keep procs, no properties any more. (server-client): Remove. (server-client-get, server-client-set): Remove, replace all callers by process-get and process-put resp. (server-clients-with, server-add-client, server-delete-client) (server-create-tty-frame, server-create-window-system-frame) (server-process-filter, server-execute, server-visit-files) (server-buffer-done, server-kill-buffer-query-function) (server-kill-emacs-query-function, server-switch-buffer) (server-save-buffers-kill-terminal): Update accordingly.
author Stefan Monnier <monnier@iro.umontreal.ca>
date Sun, 16 Sep 2007 05:16:42 +0000
parents 6cce7d77ef38
children f539dbd0a615
comparison
equal deleted inserted replaced
84600:6cce7d77ef38 84601:c38a9291ef0a
137 (defvar server-process nil 137 (defvar server-process nil
138 "The current server process.") 138 "The current server process.")
139 139
140 (defvar server-clients nil 140 (defvar server-clients nil
141 "List of current server clients. 141 "List of current server clients.
142 Each element is (PROC PROPERTIES...) where PROC is a process object, 142 Each element is a process.")
143 and PROPERTIES is an association list of client properties.")
144 143
145 (defvar server-buffer-clients nil 144 (defvar server-buffer-clients nil
146 "List of client processes requesting editing of current buffer.") 145 "List of client processes requesting editing of current buffer.")
147 (make-variable-buffer-local 'server-buffer-clients) 146 (make-variable-buffer-local 'server-buffer-clients)
148 ;; Changing major modes should not erase this local. 147 ;; Changing major modes should not erase this local.
200 199
201 (defvar server-socket-dir nil 200 (defvar server-socket-dir nil
202 "The directory in which to place the server socket. 201 "The directory in which to place the server socket.
203 Initialized by `server-start'.") 202 Initialized by `server-start'.")
204 203
205 (defun server-client (proc)
206 "Return the Emacs client corresponding to PROC.
207 PROC must be a process object.
208 The car of the result is PROC; the cdr is an association list.
209 See `server-client-get' and `server-client-set'."
210 (assq proc server-clients))
211
212 (defun server-client-get (client property)
213 "Get the value of PROPERTY in CLIENT.
214 CLIENT may be a process object, or a client returned by `server-client'.
215 Return nil if CLIENT has no such property."
216 (or (listp client) (setq client (server-client client)))
217 (cdr (assq property (cdr client))))
218
219 (defun server-client-set (client property value)
220 "Set the PROPERTY to VALUE in CLIENT, and return VALUE.
221 CLIENT may be a process object, or a client returned by `server-client'."
222 (let (p proc)
223 (if (listp client)
224 (setq proc (car client))
225 (setq proc client
226 client (server-client client)))
227 (setq p (assq property client))
228 (cond
229 (p (setcdr p value))
230 (client (setcdr client (cons (cons property value) (cdr client))))
231 (t (setq server-clients
232 `((,proc (,property . ,value)) . ,server-clients))))
233 value))
234
235 (defun server-clients-with (property value) 204 (defun server-clients-with (property value)
236 "Return a list of clients with PROPERTY set to VALUE." 205 "Return a list of clients with PROPERTY set to VALUE."
237 (let (result) 206 (let (result)
238 (dolist (client server-clients result) 207 (dolist (proc server-clients result)
239 (when (equal value (server-client-get client property)) 208 (when (equal value (process-get proc property))
240 (setq result (cons (car client) result)))))) 209 (push proc result)))))
241 210
242 (defun server-add-client (proc) 211 (defun server-add-client (proc)
243 "Create a client for process PROC, if it doesn't already have one. 212 "Create a client for process PROC, if it doesn't already have one.
244 New clients have no properties." 213 New clients have no properties."
245 (unless (server-client proc) 214 (add-to-list 'server-clients proc))
246 (setq server-clients (cons (cons proc nil)
247 server-clients))))
248 215
249 (defun server-getenv-from (env variable) 216 (defun server-getenv-from (env variable)
250 "Get the value of VARIABLE in ENV. 217 "Get the value of VARIABLE in ENV.
251 VARIABLE should be a string. Value is nil if VARIABLE is 218 VARIABLE should be a string. Value is nil if VARIABLE is
252 undefined in ENV. Otherwise, value is a string. 219 undefined in ENV. Otherwise, value is a string.
278 ,var 245 ,var
279 (concat ,var "=" ,value)) 246 (concat ,var "=" ,value))
280 process-environment))) 247 process-environment)))
281 (progn ,@body)))) 248 (progn ,@body))))
282 249
283 (defun server-delete-client (client &optional noframe) 250 (defun server-delete-client (proc &optional noframe)
284 "Delete CLIENT, including its buffers, terminals and frames. 251 "Delete CLIENT, including its buffers, terminals and frames.
285 If NOFRAME is non-nil, let the frames live. (To be used from 252 If NOFRAME is non-nil, let the frames live. (To be used from
286 `delete-frame-functions'.)" 253 `delete-frame-functions'.)"
287 (server-log (concat "server-delete-client" (if noframe " noframe")) 254 (server-log (concat "server-delete-client" (if noframe " noframe"))
288 client) 255 proc)
289 ;; Force a new lookup of client (prevents infinite recursion). 256 ;; Force a new lookup of client (prevents infinite recursion).
290 (setq client (server-client 257 (when (memq proc server-clients)
291 (if (listp client) (car client) client))) 258 (let ((buffers (process-get proc 'buffers)))
292 (let ((proc (car client))
293 (buffers (server-client-get client 'buffers)))
294 (when client
295 259
296 ;; Kill the client's buffers. 260 ;; Kill the client's buffers.
297 (dolist (buf buffers) 261 (dolist (buf buffers)
298 (when (buffer-live-p buf) 262 (when (buffer-live-p buf)
299 (with-current-buffer buf 263 (with-current-buffer buf
321 ;; Prevent `server-handle-delete-frame' from calling us 285 ;; Prevent `server-handle-delete-frame' from calling us
322 ;; recursively. 286 ;; recursively.
323 (set-frame-parameter frame 'client nil) 287 (set-frame-parameter frame 'client nil)
324 (delete-frame frame)))) 288 (delete-frame frame))))
325 289
326 (setq server-clients (delq client server-clients)) 290 (setq server-clients (delq proc server-clients))
327 291
328 ;; Delete the client's tty. 292 ;; Delete the client's tty.
329 (let ((terminal (server-client-get client 'terminal))) 293 (let ((terminal (process-get proc 'terminal)))
330 (when (eq (terminal-live-p terminal) t) 294 (when (eq (terminal-live-p terminal) t)
331 (delete-terminal terminal))) 295 (delete-terminal terminal)))
332 296
333 ;; Delete the client's process. 297 ;; Delete the client's process.
334 (if (eq (process-status (car client)) 'open) 298 (if (eq (process-status proc) 'open)
335 (delete-process (car client))) 299 (delete-process proc))
336 300
337 (server-log "Deleted" proc)))) 301 (server-log "Deleted" proc))))
338 302
339 (defun server-log (string &optional client) 303 (defun server-log (string &optional client)
340 "If a *server* buffer exists, write STRING to it for logging purposes. 304 "If a *server* buffer exists, write STRING to it for logging purposes.
425 "Notify the emacsclient process to suspend itself when its tty device is suspended." 389 "Notify the emacsclient process to suspend itself when its tty device is suspended."
426 (dolist (proc (server-clients-with 'terminal terminal)) 390 (dolist (proc (server-clients-with 'terminal terminal))
427 (server-log (format "server-handle-suspend-tty, terminal %s" terminal) proc) 391 (server-log (format "server-handle-suspend-tty, terminal %s" terminal) proc)
428 (condition-case err 392 (condition-case err
429 (server-send-string proc "-suspend \n") 393 (server-send-string proc "-suspend \n")
430 (file-error (condition-case nil (server-delete-client proc) (error nil)))))) 394 (file-error (ignore-errors (server-delete-client proc))))))
431 395
432 (defun server-unquote-arg (arg) 396 (defun server-unquote-arg (arg)
433 "Remove &-quotation from ARG. 397 "Remove &-quotation from ARG.
434 See `server-quote-arg' and `server-process-filter'." 398 See `server-quote-arg' and `server-process-filter'."
435 (replace-regexp-in-string 399 (replace-regexp-in-string
601 "COLORFGBG" "COLORTERM") 565 "COLORFGBG" "COLORTERM")
602 (make-frame-on-tty tty type 566 (make-frame-on-tty tty type
603 ;; Ignore nowait here; we always need to 567 ;; Ignore nowait here; we always need to
604 ;; clean up opened ttys when the client dies. 568 ;; clean up opened ttys when the client dies.
605 `((client . ,proc) 569 `((client . ,proc)
606 (environment . ,(process-get proc 'env)))))) 570 (environment . ,(process-get proc 'env)))))))
607 (client (server-client proc)))
608 571
609 (set-frame-parameter frame 'display-environment-variable 572 (set-frame-parameter frame 'display-environment-variable
610 (server-getenv-from (process-get proc 'env) "DISPLAY")) 573 (server-getenv-from (process-get proc 'env) "DISPLAY"))
611 (select-frame frame) 574 (select-frame frame)
612 (server-client-set client 'frame frame) 575 (process-put proc 'frame frame)
613 (server-client-set client 'tty (terminal-name frame)) 576 (process-put proc 'tty (terminal-name frame))
614 (server-client-set client 'terminal (frame-terminal frame)) 577 (process-put proc 'terminal (frame-terminal frame))
615 578
616 ;; Display *scratch* by default. 579 ;; Display *scratch* by default.
617 (switch-to-buffer (get-buffer-create "*scratch*") 'norecord) 580 (switch-to-buffer (get-buffer-create "*scratch*") 'norecord)
618 581
619 ;; Reply with our pid. 582 ;; Reply with our pid.
638 (frame (make-frame-on-display 601 (frame (make-frame-on-display
639 (or display 602 (or display
640 (frame-parameter nil 'display) 603 (frame-parameter nil 'display)
641 (getenv "DISPLAY") 604 (getenv "DISPLAY")
642 (error "Please specify display")) 605 (error "Please specify display"))
643 params)) 606 params)))
644 (client (server-client proc)))
645 (server-log (format "%s created" frame) proc) 607 (server-log (format "%s created" frame) proc)
646 ;; XXX We need to ensure the parameters are 608 ;; XXX We need to ensure the parameters are
647 ;; really set because Emacs forgets unhandled 609 ;; really set because Emacs forgets unhandled
648 ;; initialization parameters for X frames at 610 ;; initialization parameters for X frames at
649 ;; the moment. 611 ;; the moment.
650 (modify-frame-parameters frame params) 612 (modify-frame-parameters frame params)
651 (set-frame-parameter frame 'display-environment-variable 613 (set-frame-parameter frame 'display-environment-variable
652 (server-getenv-from (process-get proc 'env) "DISPLAY")) 614 (server-getenv-from (process-get proc 'env) "DISPLAY"))
653 (select-frame frame) 615 (select-frame frame)
654 (server-client-set client 'frame frame) 616 (process-put proc 'frame frame)
655 (server-client-set client 'terminal (frame-terminal frame)) 617 (process-put proc 'terminal (frame-terminal frame))
656 618
657 ;; Display *scratch* by default. 619 ;; Display *scratch* by default.
658 (switch-to-buffer (get-buffer-create "*scratch*") 'norecord) 620 (switch-to-buffer (get-buffer-create "*scratch*") 'norecord)
659 frame))) 621 frame)))
660 622
816 (assert (eq (match-end 0) (length string))) 778 (assert (eq (match-end 0) (length string)))
817 (let ((request (substring string 0 (match-beginning 0))) 779 (let ((request (substring string 0 (match-beginning 0)))
818 (coding-system (and default-enable-multibyte-characters 780 (coding-system (and default-enable-multibyte-characters
819 (or file-name-coding-system 781 (or file-name-coding-system
820 default-file-name-coding-system))) 782 default-file-name-coding-system)))
821 (client (server-client proc))
822 nowait ; t if emacsclient does not want to wait for us. 783 nowait ; t if emacsclient does not want to wait for us.
823 frame ; The frame that was opened for the client (if any). 784 frame ; The frame that was opened for the client (if any).
824 display ; Open the frame on this display. 785 display ; Open the frame on this display.
825 dontkill ; t if the client should not be killed. 786 dontkill ; t if the client should not be killed.
826 (commands ()) 787 (commands ())
859 (setq dontkill t) 820 (setq dontkill t)
860 (setq tty-name 'window-system)) 821 (setq tty-name 'window-system))
861 822
862 ;; -resume: Resume a suspended tty frame. 823 ;; -resume: Resume a suspended tty frame.
863 ((equal "-resume" arg) 824 ((equal "-resume" arg)
864 (lexical-let ((terminal (server-client-get client 'terminal))) 825 (lexical-let ((terminal (process-get proc 'terminal)))
865 (setq dontkill t) 826 (setq dontkill t)
866 (push (lambda () 827 (push (lambda ()
867 (when (eq (terminal-live-p terminal) t) 828 (when (eq (terminal-live-p terminal) t)
868 (resume-tty terminal))) 829 (resume-tty terminal)))
869 commands))) 830 commands)))
870 831
871 ;; -suspend: Suspend the client's frame. (In case we 832 ;; -suspend: Suspend the client's frame. (In case we
872 ;; get out of sync, and a C-z sends a SIGTSTP to 833 ;; get out of sync, and a C-z sends a SIGTSTP to
873 ;; emacsclient.) 834 ;; emacsclient.)
874 ((equal "-suspend" arg) 835 ((equal "-suspend" arg)
875 (lexical-let ((terminal (server-client-get client 'terminal))) 836 (lexical-let ((terminal (process-get proc 'terminal)))
876 (setq dontkill t) 837 (setq dontkill t)
877 (push (lambda () 838 (push (lambda ()
878 (when (eq (terminal-live-p terminal) t) 839 (when (eq (terminal-live-p terminal) t)
879 (suspend-tty terminal))) 840 (suspend-tty terminal)))
880 commands))) 841 commands)))
975 ;; condition-case 936 ;; condition-case
976 (error (server-return-error proc err)))) 937 (error (server-return-error proc err))))
977 938
978 (defun server-execute (proc files nowait commands dontkill frame tty-name) 939 (defun server-execute (proc files nowait commands dontkill frame tty-name)
979 (condition-case err 940 (condition-case err
980 (let* ((client (server-client proc)) 941 (let* ((buffers
981 (buffers
982 (when files 942 (when files
983 (run-hooks 'pre-command-hook) 943 (run-hooks 'pre-command-hook)
984 (prog1 (server-visit-files files client nowait) 944 (prog1 (server-visit-files files proc nowait)
985 (run-hooks 'post-command-hook))))) 945 (run-hooks 'post-command-hook)))))
986 946
987 (mapc 'funcall (nreverse commands)) 947 (mapc 'funcall (nreverse commands))
988 948
989 ;; Delete the client if necessary. 949 ;; Delete the client if necessary.
1027 (goto-line (nth 1 file-line-col)) 987 (goto-line (nth 1 file-line-col))
1028 (let ((column-number (nth 2 file-line-col))) 988 (let ((column-number (nth 2 file-line-col)))
1029 (if (> column-number 0) 989 (if (> column-number 0)
1030 (move-to-column (1- column-number))))) 990 (move-to-column (1- column-number)))))
1031 991
1032 (defun server-visit-files (files client &optional nowait) 992 (defun server-visit-files (files proc &optional nowait)
1033 "Find FILES and return a list of buffers created. 993 "Find FILES and return a list of buffers created.
1034 FILES is an alist whose elements are (FILENAME LINENUMBER COLUMNNUMBER). 994 FILES is an alist whose elements are (FILENAME LINENUMBER COLUMNNUMBER).
1035 CLIENT is the client that requested this operation. 995 PROC is the client that requested this operation.
1036 NOWAIT non-nil means this client is not waiting for the results, 996 NOWAIT non-nil means this client is not waiting for the results,
1037 so don't mark these buffers specially, just visit them normally." 997 so don't mark these buffers specially, just visit them normally."
1038 ;; Bind last-nonmenu-event to force use of keyboard, not mouse, for queries. 998 ;; Bind last-nonmenu-event to force use of keyboard, not mouse, for queries.
1039 (let ((last-nonmenu-event t) client-record) 999 (let ((last-nonmenu-event t) client-record)
1040 ;; Restore the current buffer afterward, but not using save-excursion, 1000 ;; Restore the current buffer afterward, but not using save-excursion,
1067 (server-goto-line-column file) 1027 (server-goto-line-column file)
1068 (run-hooks 'server-visit-hook))) 1028 (run-hooks 'server-visit-hook)))
1069 (unless nowait 1029 (unless nowait
1070 ;; When the buffer is killed, inform the clients. 1030 ;; When the buffer is killed, inform the clients.
1071 (add-hook 'kill-buffer-hook 'server-kill-buffer nil t) 1031 (add-hook 'kill-buffer-hook 'server-kill-buffer nil t)
1072 (push (car client) server-buffer-clients)) 1032 (push proc server-buffer-clients))
1073 (push (current-buffer) client-record))) 1033 (push (current-buffer) client-record)))
1074 (unless nowait 1034 (unless nowait
1075 (server-client-set 1035 (process-put proc 'buffers
1076 client 'buffers 1036 (nconc (process-get proc 'buffers) client-record)))
1077 (nconc (server-client-get client 'buffers) client-record)))
1078 client-record)) 1037 client-record))
1079 1038
1080 (defun server-buffer-done (buffer &optional for-killing) 1039 (defun server-buffer-done (buffer &optional for-killing)
1081 "Mark BUFFER as \"done\" for its client(s). 1040 "Mark BUFFER as \"done\" for its client(s).
1082 This buries the buffer, then returns a list of the form (NEXT-BUFFER KILLED). 1041 This buries the buffer, then returns a list of the form (NEXT-BUFFER KILLED).
1084 or nil. KILLED is t if we killed BUFFER (typically, because it was visiting 1043 or nil. KILLED is t if we killed BUFFER (typically, because it was visiting
1085 a temp file). 1044 a temp file).
1086 FOR-KILLING if non-nil indicates that we are called from `kill-buffer'." 1045 FOR-KILLING if non-nil indicates that we are called from `kill-buffer'."
1087 (let ((next-buffer nil) 1046 (let ((next-buffer nil)
1088 (killed nil)) 1047 (killed nil))
1089 (dolist (client server-clients) 1048 (dolist (proc server-clients)
1090 (let ((buffers (server-client-get client 'buffers))) 1049 (let ((buffers (process-get proc 'buffers)))
1091 (or next-buffer 1050 (or next-buffer
1092 (setq next-buffer (nth 1 (memq buffer buffers)))) 1051 (setq next-buffer (nth 1 (memq buffer buffers))))
1093 (when buffers ; Ignore bufferless clients. 1052 (when buffers ; Ignore bufferless clients.
1094 (setq buffers (delq buffer buffers)) 1053 (setq buffers (delq buffer buffers))
1095 ;; Delete all dead buffers from CLIENT. 1054 ;; Delete all dead buffers from PROC.
1096 (dolist (b buffers) 1055 (dolist (b buffers)
1097 (and (bufferp b) 1056 (and (bufferp b)
1098 (not (buffer-live-p b)) 1057 (not (buffer-live-p b))
1099 (setq buffers (delq b buffers)))) 1058 (setq buffers (delq b buffers))))
1100 (server-client-set client 'buffers buffers) 1059 (process-put proc 'buffers buffers)
1101 ;; If client now has no pending buffers, 1060 ;; If client now has no pending buffers,
1102 ;; tell it that it is done, and forget it entirely. 1061 ;; tell it that it is done, and forget it entirely.
1103 (unless buffers 1062 (unless buffers
1104 (server-log "Close" client) 1063 (server-log "Close" proc)
1105 (server-delete-client client))))) 1064 (server-delete-client proc)))))
1106 (when (and (bufferp buffer) (buffer-name buffer)) 1065 (when (and (bufferp buffer) (buffer-name buffer))
1107 ;; We may or may not kill this buffer; 1066 ;; We may or may not kill this buffer;
1108 ;; if we do, do not call server-buffer-done recursively 1067 ;; if we do, do not call server-buffer-done recursively
1109 ;; from kill-buffer-hook. 1068 ;; from kill-buffer-hook.
1110 (let ((server-kill-buffer-running t)) 1069 (let ((server-kill-buffer-running t))
1169 (defun server-kill-buffer-query-function () 1128 (defun server-kill-buffer-query-function ()
1170 "Ask before killing a server buffer." 1129 "Ask before killing a server buffer."
1171 (or (not server-buffer-clients) 1130 (or (not server-buffer-clients)
1172 (let ((res t)) 1131 (let ((res t))
1173 (dolist (proc server-buffer-clients res) 1132 (dolist (proc server-buffer-clients res)
1174 (let ((client (server-client proc))) 1133 (when (and (memq proc server-clients)
1175 (when (and client (eq (process-status proc) 'open)) 1134 (eq (process-status proc) 'open))
1176 (setq res nil))))) 1135 (setq res nil))))
1177 (yes-or-no-p (format "Buffer `%s' still has clients; kill it? " 1136 (yes-or-no-p (format "Buffer `%s' still has clients; kill it? "
1178 (buffer-name (current-buffer)))))) 1137 (buffer-name (current-buffer))))))
1179 1138
1180 (defun server-kill-emacs-query-function () 1139 (defun server-kill-emacs-query-function ()
1181 "Ask before exiting Emacs it has live clients." 1140 "Ask before exiting Emacs it has live clients."
1182 (or (not server-clients) 1141 (or (not server-clients)
1183 (let (live-client) 1142 (let (live-client)
1184 (dolist (client server-clients live-client) 1143 (dolist (proc server-clients live-client)
1185 (when (memq t (mapcar 'buffer-live-p (server-client-get 1144 (when (memq t (mapcar 'buffer-live-p (process-get
1186 client 'buffers))) 1145 proc 'buffers)))
1187 (setq live-client t)))) 1146 (setq live-client t))))
1188 (yes-or-no-p "This Emacs session has clients; exit anyway? "))) 1147 (yes-or-no-p "This Emacs session has clients; exit anyway? ")))
1189 1148
1190 (defvar server-kill-buffer-running nil 1149 (defvar server-kill-buffer-running nil
1191 "Non-nil while `server-kill-buffer' or `server-buffer-done' is running.") 1150 "Non-nil while `server-kill-buffer' or `server-buffer-done' is running.")
1234 done that." 1193 done that."
1235 (if (null next-buffer) 1194 (if (null next-buffer)
1236 (progn 1195 (progn
1237 (let ((rest server-clients)) 1196 (let ((rest server-clients))
1238 (while (and rest (not next-buffer)) 1197 (while (and rest (not next-buffer))
1239 (let ((client (car rest))) 1198 (let ((proc (car rest)))
1240 ;; Only look at frameless clients. 1199 ;; Only look at frameless clients.
1241 (when (not (server-client-get client 'frame)) 1200 (when (not (process-get proc 'frame))
1242 (setq next-buffer (car (server-client-get client 'buffers)))) 1201 (setq next-buffer (car (process-get proc 'buffers))))
1243 (setq rest (cdr rest))))) 1202 (setq rest (cdr rest)))))
1244 (and next-buffer (server-switch-buffer next-buffer killed-one)) 1203 (and next-buffer (server-switch-buffer next-buffer killed-one))
1245 (unless (or next-buffer killed-one (window-dedicated-p (selected-window))) 1204 (unless (or next-buffer killed-one (window-dedicated-p (selected-window)))
1246 ;; (switch-to-buffer (other-buffer)) 1205 ;; (switch-to-buffer (other-buffer))
1247 (message "No server buffers remain to edit"))) 1206 (message "No server buffers remain to edit")))
1290 1249
1291 With prefix arg, silently save all file-visiting buffers, then kill. 1250 With prefix arg, silently save all file-visiting buffers, then kill.
1292 1251
1293 If emacsclient was started with a list of filenames to edit, then 1252 If emacsclient was started with a list of filenames to edit, then
1294 only these files will be asked to be saved." 1253 only these files will be asked to be saved."
1295 (let ((buffers (server-client-get proc 'buffers))) 1254 (let ((buffers (process-get proc 'buffers)))
1296 ;; If client is bufferless, emulate a normal Emacs session 1255 ;; If client is bufferless, emulate a normal Emacs session
1297 ;; exit and offer to save all buffers. Otherwise, offer to 1256 ;; exit and offer to save all buffers. Otherwise, offer to
1298 ;; save only the buffers belonging to the client. 1257 ;; save only the buffers belonging to the client.
1299 (save-some-buffers arg 1258 (save-some-buffers arg
1300 (if buffers 1259 (if buffers