aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Monnier2002-09-27 17:43:29 +0000
committerStefan Monnier2002-09-27 17:43:29 +0000
commit44a56b29e7d83b339a5ffba008ff56b298f587d3 (patch)
tree893f480e7292e85c4fe7350a5da19b591dfa1a9e
parent124e448b98102b036d24c43c1b4d55a26682084d (diff)
downloademacs-44a56b29e7d83b339a5ffba008ff56b298f587d3.tar.gz
emacs-44a56b29e7d83b339a5ffba008ff56b298f587d3.zip
(server-select-display): New function.
(server-process-filter): Add support for `-display' and `-eval' args. (server-visit-files): Use save-current-buffer, push, and dolist. Add server-kill-buffer to kill-buffer-hook. (kill-buffer-hook): Don't modify globally. (server-switch-buffer): Be a bit more careful with multiple displays.
-rw-r--r--lisp/server.el126
1 files changed, 81 insertions, 45 deletions
diff --git a/lisp/server.el b/lisp/server.el
index 36829578b91..12d7c1290c2 100644
--- a/lisp/server.el
+++ b/lisp/server.el
@@ -32,9 +32,9 @@
32;; a server for other processes. 32;; a server for other processes.
33 33
34;; Load this library and do M-x server-edit to enable Emacs as a server. 34;; Load this library and do M-x server-edit to enable Emacs as a server.
35;; Emacs runs the program ../arch-lib/emacsserver as a subprocess 35;; Emacs opens up a socket for communication with clients. If there are no
36;; for communication with clients. If there are no client buffers to edit, 36;; client buffers to edit, server-edit acts like (switch-to-buffer
37;; server-edit acts like (switch-to-buffer (other-buffer)) 37;; (other-buffer))
38 38
39;; When some other program runs "the editor" to edit a file, 39;; When some other program runs "the editor" to edit a file,
40;; "the editor" can be the Emacs client program ../lib-src/emacsclient. 40;; "the editor" can be the Emacs client program ../lib-src/emacsclient.
@@ -178,6 +178,26 @@ are done with it in the server.")
178 (if ps (setq server-clients (delq ps server-clients)))) 178 (if ps (setq server-clients (delq ps server-clients))))
179 (server-log (format "Status changed to %s" (process-status proc)) proc)) 179 (server-log (format "Status changed to %s" (process-status proc)) proc))
180 180
181(defun server-select-display (display)
182 ;; If the current frame is on `display' we're all set.
183 (unless (equal (frame-parameter (selected-frame) 'display) display)
184 ;; Otherwise, look for an existing frame there and select it.
185 (dolist (frame (frame-list))
186 (when (equal (frame-parameter frame 'display) display)
187 (select-frame frame)))
188 ;; If there's no frame on that display yet, create a dummy one
189 ;; and select it.
190 (unless (equal (frame-parameter (selected-frame) 'display) display)
191 (select-frame
192 (make-frame-on-display
193 display
194 ;; This frame is only there in place of an actual "current display"
195 ;; setting, so we want it to be as unobtrusive as possible. That's
196 ;; what the invisibility is for. The minibuffer setting is so that
197 ;; we don't end up displaying a buffer in it (which noone would
198 ;; notice).
199 '((visibility . nil) (minibuffer . only)))))))
200
181(defun server-unquote-arg (arg) 201(defun server-unquote-arg (arg)
182 (replace-regexp-in-string 202 (replace-regexp-in-string
183 "&." (lambda (s) 203 "&." (lambda (s)
@@ -239,7 +259,7 @@ Prefix arg means just kill any existing server communications subprocess."
239 (coding-system (and default-enable-multibyte-characters 259 (coding-system (and default-enable-multibyte-characters
240 (or file-name-coding-system 260 (or file-name-coding-system
241 default-file-name-coding-system))) 261 default-file-name-coding-system)))
242 client nowait 262 client nowait eval
243 (files nil) 263 (files nil)
244 (lineno 1) 264 (lineno 1)
245 (columnno 0)) 265 (columnno 0))
@@ -252,6 +272,14 @@ Prefix arg means just kill any existing server communications subprocess."
252 (setq request (substring request (match-end 0))) 272 (setq request (substring request (match-end 0)))
253 (cond 273 (cond
254 ((equal "-nowait" arg) (setq nowait t)) 274 ((equal "-nowait" arg) (setq nowait t))
275 ((equal "-eval" arg) (setq eval t))
276 ((and (equal "-display" arg) (string-match "\\([^ ]*\\) " request))
277 (let ((display (server-unquote-arg (match-string 1 request))))
278 (setq request (substring request (match-end 0)))
279 (condition-case err
280 (server-select-display display)
281 (error (process-send-string proc (nth 1 err))
282 (setq request "")))))
255 ;; ARG is a line number option. 283 ;; ARG is a line number option.
256 ((string-match "\\`\\+[0-9]+\\'" arg) 284 ((string-match "\\`\\+[0-9]+\\'" arg)
257 (setq lineno (string-to-int (substring arg 1)))) 285 (setq lineno (string-to-int (substring arg 1))))
@@ -266,10 +294,17 @@ Prefix arg means just kill any existing server communications subprocess."
266 ;; Now decode the file name if necessary. 294 ;; Now decode the file name if necessary.
267 (if coding-system 295 (if coding-system
268 (setq arg (decode-coding-string arg coding-system))) 296 (setq arg (decode-coding-string arg coding-system)))
269 ;; ARG is a file name. 297 (if eval
270 ;; Collapse multiple slashes to single slashes. 298 (let ((v (eval (car (read-from-string arg)))))
271 (setq arg (command-line-normalize-file-name arg)) 299 (when v
272 (push (list arg lineno columnno) files) 300 (with-temp-buffer
301 (let ((standard-output (current-buffer)))
302 (pp v)
303 (process-send-region proc (point-min) (point-max))))))
304 ;; ARG is a file name.
305 ;; Collapse multiple slashes to single slashes.
306 (setq arg (command-line-normalize-file-name arg))
307 (push (list arg lineno columnno) files))
273 (setq lineno 1) 308 (setq lineno 1)
274 (setq columnno 0))))) 309 (setq columnno 0)))))
275 (when files 310 (when files
@@ -302,45 +337,44 @@ Prefix arg means just kill any existing server communications subprocess."
302 (move-to-column (1- column-number))))) 337 (move-to-column (1- column-number)))))
303 338
304(defun server-visit-files (files client &optional nowait) 339(defun server-visit-files (files client &optional nowait)
305 "Finds FILES and returns the list CLIENT with the buffers nconc'd. 340 "Find FILES and return the list CLIENT with the buffers nconc'd.
306FILES is an alist whose elements are (FILENAME LINENUMBER COLUMNNUMBER). 341FILES is an alist whose elements are (FILENAME LINENUMBER COLUMNNUMBER).
307NOWAIT non-nil means this client is not waiting for the results, 342NOWAIT non-nil means this client is not waiting for the results,
308so don't mark these buffers specially, just visit them normally." 343so don't mark these buffers specially, just visit them normally."
309 ;; Bind last-nonmenu-event to force use of keyboard, not mouse, for queries. 344 ;; Bind last-nonmenu-event to force use of keyboard, not mouse, for queries.
310 (let (client-record (last-nonmenu-event t) (obuf (current-buffer))) 345 (let ((last-nonmenu-event t) client-record)
311 ;; Restore the current buffer afterward, but not using save-excursion, 346 ;; Restore the current buffer afterward, but not using save-excursion,
312 ;; because we don't want to save point in this buffer 347 ;; because we don't want to save point in this buffer
313 ;; if it happens to be one of those specified by the server. 348 ;; if it happens to be one of those specified by the server.
314 (unwind-protect 349 (save-current-buffer
315 (while files 350 (dolist (file files)
316 ;; If there is an existing buffer modified or the file is 351 ;; If there is an existing buffer modified or the file is
317 ;; modified, revert it. If there is an existing buffer with 352 ;; modified, revert it. If there is an existing buffer with
318 ;; deleted file, offer to write it. 353 ;; deleted file, offer to write it.
319 (let* ((filen (car (car files))) 354 (let* ((filen (car file))
320 (obuf (get-file-buffer filen))) 355 (obuf (get-file-buffer filen)))
321 (push filen file-name-history) 356 (push filen file-name-history)
322 (if (and obuf (set-buffer obuf)) 357 (if (and obuf (set-buffer obuf))
323 (progn 358 (progn
324 (cond ((file-exists-p filen) 359 (cond ((file-exists-p filen)
325 (if (not (verify-visited-file-modtime obuf)) 360 (if (not (verify-visited-file-modtime obuf))
326 (revert-buffer t nil))) 361 (revert-buffer t nil)))
327 (t 362 (t
328 (if (y-or-n-p 363 (if (y-or-n-p
329 (concat "File no longer exists: " 364 (concat "File no longer exists: "
330 filen 365 filen
331 ", write buffer to file? ")) 366 ", write buffer to file? "))
332 (write-file filen)))) 367 (write-file filen))))
333 (setq server-existing-buffer t) 368 (setq server-existing-buffer t)
334 (server-goto-line-column (car files))) 369 (server-goto-line-column file))
335 (set-buffer (find-file-noselect filen)) 370 (set-buffer (find-file-noselect filen))
336 (server-goto-line-column (car files)) 371 (server-goto-line-column file)
337 (run-hooks 'server-visit-hook))) 372 (run-hooks 'server-visit-hook)))
338 (if (not nowait) 373 (unless nowait
339 (setq server-buffer-clients 374 ;; When the buffer is killed, inform the clients.
340 (cons (car client) server-buffer-clients))) 375 (add-hook 'kill-buffer-hook 'server-kill-buffer nil t)
341 (setq client-record (cons (current-buffer) client-record)) 376 (push (car client) server-buffer-clients))
342 (setq files (cdr files))) 377 (push (current-buffer) client-record)))
343 (set-buffer obuf))
344 (nconc client client-record))) 378 (nconc client client-record)))
345 379
346(defun server-buffer-done (buffer &optional for-killing) 380(defun server-buffer-done (buffer &optional for-killing)
@@ -462,8 +496,6 @@ specifically for the clients and did not exist before their request for it."
462(defvar server-kill-buffer-running nil 496(defvar server-kill-buffer-running nil
463 "Non-nil while `server-kill-buffer' or `server-buffer-done' is running.") 497 "Non-nil while `server-kill-buffer' or `server-buffer-done' is running.")
464 498
465;; When a buffer is killed, inform the clients.
466(add-hook 'kill-buffer-hook 'server-kill-buffer)
467(defun server-kill-buffer () 499(defun server-kill-buffer ()
468 ;; Prevent infinite recursion if user has made server-done-hook 500 ;; Prevent infinite recursion if user has made server-done-hook
469 ;; call kill-buffer. 501 ;; call kill-buffer.
@@ -531,9 +563,13 @@ Arg NEXT-BUFFER is a suggestion; if it is a live buffer, use it."
531 (select-window (next-window nil 'nomini 0))) 563 (select-window (next-window nil 'nomini 0)))
532 ;; Move to a non-dedicated window, if we have one. 564 ;; Move to a non-dedicated window, if we have one.
533 (when (window-dedicated-p (selected-window)) 565 (when (window-dedicated-p (selected-window))
534 (select-window (get-window-with-predicate 566 (select-window
535 (lambda (w) (not (window-dedicated-p w))) 567 (get-window-with-predicate
536 'nomini 'visible (selected-window)))) 568 (lambda (w)
569 (and (not (window-dedicated-p w))
570 (equal (frame-parameter (window-frame w) 'display)
571 (frame-parameter (selected-frame) 'display))))
572 'nomini 'visible (selected-window))))
537 (condition-case nil 573 (condition-case nil
538 (switch-to-buffer next-buffer) 574 (switch-to-buffer next-buffer)
539 ;; After all the above, we might still have ended up with 575 ;; After all the above, we might still have ended up with