diff options
| author | Stefan Monnier | 2002-09-27 17:43:29 +0000 |
|---|---|---|
| committer | Stefan Monnier | 2002-09-27 17:43:29 +0000 |
| commit | 44a56b29e7d83b339a5ffba008ff56b298f587d3 (patch) | |
| tree | 893f480e7292e85c4fe7350a5da19b591dfa1a9e | |
| parent | 124e448b98102b036d24c43c1b4d55a26682084d (diff) | |
| download | emacs-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.el | 126 |
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. |
| 306 | FILES is an alist whose elements are (FILENAME LINENUMBER COLUMNNUMBER). | 341 | FILES is an alist whose elements are (FILENAME LINENUMBER COLUMNNUMBER). |
| 307 | NOWAIT non-nil means this client is not waiting for the results, | 342 | NOWAIT non-nil means this client is not waiting for the results, |
| 308 | so don't mark these buffers specially, just visit them normally." | 343 | so 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 |