diff options
| author | Karoly Lorentey | 2004-02-19 23:55:51 +0000 |
|---|---|---|
| committer | Karoly Lorentey | 2004-02-19 23:55:51 +0000 |
| commit | 77134727c9430ee77bff150206fce33f2045dfc0 (patch) | |
| tree | 4d288cd6b33a8f3ca914edbdbf8eed5d06e759a9 | |
| parent | bfdfad9294d072ad12b670d23912998f7e439394 (diff) | |
| download | emacs-77134727c9430ee77bff150206fce33f2045dfc0.tar.gz emacs-77134727c9430ee77bff150206fce33f2045dfc0.zip | |
Added -w option to emacsclient for opening a new X frame.
lib-src/emacsclient.c (window_system): New variable.
(frame): Renamed to tty for consistency with the option name.
(longopts, print_help_and_exit): Added -w option. (Suggested by Ami
Fischman <ami at fischman dot org>.
(decode_options): Initialize display to $DISPLAY. Handle -w option.
(main): Implement the -w option. Changed to a more elaborate protocol
between Emacs and emacsclient, in preparation to suspend support.
lisp/server.el (server-frames): New variable.
(server-handle-delete-frame): New function.
(server-start): Add it to delete-frame-functions.
(server-select-display): Don't make the new frame invisible.
(server-with-errors-reported): New macro for brevity.
(server-process-filter): Implement the "-window-system" command.
Use server-with-errors-reported. Fixed regexp for +line:column syntax.
Use the new protocol.
git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-83
| -rw-r--r-- | lib-src/emacsclient.c | 65 | ||||
| -rw-r--r-- | lisp/server.el | 144 |
2 files changed, 138 insertions, 71 deletions
diff --git a/lib-src/emacsclient.c b/lib-src/emacsclient.c index 771eeac05e6..90224fe51ee 100644 --- a/lib-src/emacsclient.c +++ b/lib-src/emacsclient.c | |||
| @@ -70,11 +70,14 @@ int nowait = 0; | |||
| 70 | /* Nonzero means args are expressions to be evaluated. --eval. */ | 70 | /* Nonzero means args are expressions to be evaluated. --eval. */ |
| 71 | int eval = 0; | 71 | int eval = 0; |
| 72 | 72 | ||
| 73 | /* Nonzero means open a new graphical frame. */ | ||
| 74 | int window_system = 0; | ||
| 75 | |||
| 73 | /* The display on which Emacs should work. --display. */ | 76 | /* The display on which Emacs should work. --display. */ |
| 74 | char *display = NULL; | 77 | char *display = NULL; |
| 75 | 78 | ||
| 76 | /* Nonzero means open a new Emacs frame on the current terminal. */ | 79 | /* Nonzero means open a new Emacs frame on the current terminal. */ |
| 77 | int frame = 0; | 80 | int tty = 0; |
| 78 | 81 | ||
| 79 | /* If non-NULL, the name of an editor to fallback to if the server | 82 | /* If non-NULL, the name of an editor to fallback to if the server |
| 80 | is not running. --alternate-editor. */ | 83 | is not running. --alternate-editor. */ |
| @@ -92,6 +95,7 @@ struct option longopts[] = | |||
| 92 | { "help", no_argument, NULL, 'H' }, | 95 | { "help", no_argument, NULL, 'H' }, |
| 93 | { "version", no_argument, NULL, 'V' }, | 96 | { "version", no_argument, NULL, 'V' }, |
| 94 | { "tty", no_argument, NULL, 't' }, | 97 | { "tty", no_argument, NULL, 't' }, |
| 98 | { "window-system", no_argument, NULL, 'w' }, | ||
| 95 | { "alternate-editor", required_argument, NULL, 'a' }, | 99 | { "alternate-editor", required_argument, NULL, 'a' }, |
| 96 | { "socket-name", required_argument, NULL, 's' }, | 100 | { "socket-name", required_argument, NULL, 's' }, |
| 97 | { "display", required_argument, NULL, 'd' }, | 101 | { "display", required_argument, NULL, 'd' }, |
| @@ -107,11 +111,12 @@ decode_options (argc, argv) | |||
| 107 | char **argv; | 111 | char **argv; |
| 108 | { | 112 | { |
| 109 | alternate_editor = getenv ("ALTERNATE_EDITOR"); | 113 | alternate_editor = getenv ("ALTERNATE_EDITOR"); |
| 114 | display = getenv ("DISPLAY"); | ||
| 110 | 115 | ||
| 111 | while (1) | 116 | while (1) |
| 112 | { | 117 | { |
| 113 | int opt = getopt_long (argc, argv, | 118 | int opt = getopt_long (argc, argv, |
| 114 | "VHnea:s:d:t", longopts, 0); | 119 | "VHnea:s:d:tw", longopts, 0); |
| 115 | 120 | ||
| 116 | if (opt == EOF) | 121 | if (opt == EOF) |
| 117 | break; | 122 | break; |
| @@ -149,7 +154,13 @@ decode_options (argc, argv) | |||
| 149 | break; | 154 | break; |
| 150 | 155 | ||
| 151 | case 't': | 156 | case 't': |
| 152 | frame = 1; | 157 | tty = 1; |
| 158 | window_system = 0; | ||
| 159 | break; | ||
| 160 | |||
| 161 | case 'w': | ||
| 162 | window_system = 1; | ||
| 163 | tty = 0; | ||
| 153 | break; | 164 | break; |
| 154 | 165 | ||
| 155 | case 'H': | 166 | case 'H': |
| @@ -163,11 +174,10 @@ decode_options (argc, argv) | |||
| 163 | } | 174 | } |
| 164 | } | 175 | } |
| 165 | 176 | ||
| 166 | if (frame) { | 177 | if (tty) { |
| 167 | nowait = 0; | 178 | nowait = 0; |
| 168 | display = 0; | 179 | display = 0; |
| 169 | } | 180 | } |
| 170 | |||
| 171 | } | 181 | } |
| 172 | 182 | ||
| 173 | void | 183 | void |
| @@ -182,6 +192,7 @@ The following OPTIONS are accepted:\n\ | |||
| 182 | -V, --version Just print a version info and return\n\ | 192 | -V, --version Just print a version info and return\n\ |
| 183 | -H, --help Print this usage information message\n\ | 193 | -H, --help Print this usage information message\n\ |
| 184 | -t, --tty Open a new Emacs frame on the current terminal\n\ | 194 | -t, --tty Open a new Emacs frame on the current terminal\n\ |
| 195 | -w, --window-system Open a new graphical Emacs frame\n\ | ||
| 185 | -n, --no-wait Don't wait for the server to return\n\ | 196 | -n, --no-wait Don't wait for the server to return\n\ |
| 186 | -e, --eval Evaluate the FILE arguments as ELisp expressions\n\ | 197 | -e, --eval Evaluate the FILE arguments as ELisp expressions\n\ |
| 187 | -d, --display=DISPLAY Visit the file in the given display\n\ | 198 | -d, --display=DISPLAY Visit the file in the given display\n\ |
| @@ -272,16 +283,6 @@ fail (void) | |||
| 272 | 283 | ||
| 273 | int emacs_pid; | 284 | int emacs_pid; |
| 274 | 285 | ||
| 275 | #ifdef nec_ews_svr4 | ||
| 276 | extern char *_sobuf ; | ||
| 277 | #else | ||
| 278 | #if defined (USG) || defined (DGUX) | ||
| 279 | unsigned char _sobuf[BUFSIZ+8]; | ||
| 280 | #else | ||
| 281 | char _sobuf[BUFSIZ]; | ||
| 282 | #endif | ||
| 283 | #endif | ||
| 284 | |||
| 285 | /* A signal handler that passes the signal to the Emacs process. | 286 | /* A signal handler that passes the signal to the Emacs process. |
| 286 | Useful for SIGWINCH. */ | 287 | Useful for SIGWINCH. */ |
| 287 | 288 | ||
| @@ -395,7 +396,7 @@ main (argc, argv) | |||
| 395 | /* Process options. */ | 396 | /* Process options. */ |
| 396 | decode_options (argc, argv); | 397 | decode_options (argc, argv); |
| 397 | 398 | ||
| 398 | if ((argc - optind < 1) && !eval && !frame) | 399 | if ((argc - optind < 1) && !eval && !tty && !window_system) |
| 399 | { | 400 | { |
| 400 | fprintf (stderr, "%s: file name or argument required\n", progname); | 401 | fprintf (stderr, "%s: file name or argument required\n", progname); |
| 401 | fprintf (stderr, "Try `%s --help' for more information\n", progname); | 402 | fprintf (stderr, "Try `%s --help' for more information\n", progname); |
| @@ -574,7 +575,7 @@ To start the server in Emacs, type \"M-x server-start\".\n", | |||
| 574 | fprintf (out, " "); | 575 | fprintf (out, " "); |
| 575 | } | 576 | } |
| 576 | 577 | ||
| 577 | if (frame) | 578 | if (tty) |
| 578 | { | 579 | { |
| 579 | char *tty_name = ttyname (fileno (stdin)); | 580 | char *tty_name = ttyname (fileno (stdin)); |
| 580 | if (! tty_name) | 581 | if (! tty_name) |
| @@ -588,6 +589,9 @@ To start the server in Emacs, type \"M-x server-start\".\n", | |||
| 588 | quote_file_name (getenv("TERM"), out); | 589 | quote_file_name (getenv("TERM"), out); |
| 589 | fprintf (out, " "); | 590 | fprintf (out, " "); |
| 590 | } | 591 | } |
| 592 | |||
| 593 | if (window_system) | ||
| 594 | fprintf (out, "-window-system "); | ||
| 591 | 595 | ||
| 592 | if ((argc - optind > 0)) | 596 | if ((argc - optind > 0)) |
| 593 | { | 597 | { |
| @@ -617,7 +621,7 @@ To start the server in Emacs, type \"M-x server-start\".\n", | |||
| 617 | } | 621 | } |
| 618 | else | 622 | else |
| 619 | { | 623 | { |
| 620 | if (!frame) | 624 | if (!tty && !window_system) |
| 621 | { | 625 | { |
| 622 | while ((str = fgets (string, BUFSIZ, stdin))) | 626 | while ((str = fgets (string, BUFSIZ, stdin))) |
| 623 | { | 627 | { |
| @@ -636,7 +640,7 @@ To start the server in Emacs, type \"M-x server-start\".\n", | |||
| 636 | return 0; | 640 | return 0; |
| 637 | } | 641 | } |
| 638 | 642 | ||
| 639 | if (!eval && !frame) | 643 | if (!eval && !tty) |
| 640 | { | 644 | { |
| 641 | printf ("Waiting for Emacs..."); | 645 | printf ("Waiting for Emacs..."); |
| 642 | needlf = 2; | 646 | needlf = 2; |
| @@ -646,18 +650,29 @@ To start the server in Emacs, type \"M-x server-start\".\n", | |||
| 646 | /* Now, wait for an answer and print any messages. */ | 650 | /* Now, wait for an answer and print any messages. */ |
| 647 | while ((str = fgets (string, BUFSIZ, in))) | 651 | while ((str = fgets (string, BUFSIZ, in))) |
| 648 | { | 652 | { |
| 649 | if (frame) | 653 | if (strprefix ("-emacs-pid ", str)) |
| 650 | { | 654 | { |
| 651 | if (strprefix ("emacs-pid ", str)) | 655 | emacs_pid = strtol (string + strlen ("-emacs-pid"), NULL, 10); |
| 652 | { | 656 | } |
| 653 | emacs_pid = strtol (string + strlen ("emacs-pid"), NULL, 10); | 657 | else if (strprefix ("-print ", str)) |
| 654 | } | 658 | { |
| 659 | if (needlf == 2) | ||
| 660 | printf ("\n"); | ||
| 661 | printf ("%s", str + strlen ("-print ")); | ||
| 662 | needlf = str[0] == '\0' ? needlf : str[strlen (str) - 1] != '\n'; | ||
| 663 | } | ||
| 664 | else if (strprefix ("-error ", str)) | ||
| 665 | { | ||
| 666 | if (needlf == 2) | ||
| 667 | printf ("\n"); | ||
| 668 | printf ("*ERROR*: %s", str + strlen ("-print ")); | ||
| 669 | needlf = str[0] == '\0' ? needlf : str[strlen (str) - 1] != '\n'; | ||
| 655 | } | 670 | } |
| 656 | else | 671 | else |
| 657 | { | 672 | { |
| 658 | if (needlf == 2) | 673 | if (needlf == 2) |
| 659 | printf ("\n"); | 674 | printf ("\n"); |
| 660 | printf ("%s", str); | 675 | printf ("*ERROR*: Unknown message: %s", str); |
| 661 | needlf = str[0] == '\0' ? needlf : str[strlen (str) - 1] != '\n'; | 676 | needlf = str[0] == '\0' ? needlf : str[strlen (str) - 1] != '\n'; |
| 662 | } | 677 | } |
| 663 | } | 678 | } |
diff --git a/lisp/server.el b/lisp/server.el index 6d59b0d69c7..82f4ec26606 100644 --- a/lisp/server.el +++ b/lisp/server.el | |||
| @@ -111,8 +111,18 @@ When a buffer is marked as \"done\", it is removed from this list.") | |||
| 111 | Each element is (CLIENTID TTY) where CLIENTID is a string | 111 | Each element is (CLIENTID TTY) where CLIENTID is a string |
| 112 | that can be given to the server process to identify a client. | 112 | that can be given to the server process to identify a client. |
| 113 | TTY is the name of the tty device. | 113 | TTY is the name of the tty device. |
| 114 | When all the buffers of the client are marked as \"done\", | 114 | |
| 115 | the frame is deleted.") | 115 | When all frames on the device are deleted, the server quits the |
| 116 | connection to the client, and vice versa.") | ||
| 117 | |||
| 118 | (defvar server-frames nil | ||
| 119 | "List of current window-system frames used by the server. | ||
| 120 | Each element is (CLIENTID FRAME) where CLIENTID is a string | ||
| 121 | that can be given to the server process to identify a client. | ||
| 122 | FRAME is the frame that was opened by the client. | ||
| 123 | |||
| 124 | When the frame is deleted, the server closes the connection to | ||
| 125 | the client, and vice versa.") | ||
| 116 | 126 | ||
| 117 | (defvar server-buffer-clients nil | 127 | (defvar server-buffer-clients nil |
| 118 | "List of client ids for clients requesting editing of current buffer.") | 128 | "List of client ids for clients requesting editing of current buffer.") |
| @@ -211,7 +221,7 @@ are done with it in the server.") | |||
| 211 | (server-log (format "Status changed to %s" (process-status proc)) proc)) | 221 | (server-log (format "Status changed to %s" (process-status proc)) proc)) |
| 212 | 222 | ||
| 213 | (defun server-handle-delete-tty (tty) | 223 | (defun server-handle-delete-tty (tty) |
| 214 | "Delete the client connection when the emacsclient frame is deleted." | 224 | "Delete the client connection when the emacsclient terminal device is closed." |
| 215 | (dolist (entry server-ttys) | 225 | (dolist (entry server-ttys) |
| 216 | (let ((proc (nth 0 entry)) | 226 | (let ((proc (nth 0 entry)) |
| 217 | (term (nth 1 entry))) | 227 | (term (nth 1 entry))) |
| @@ -224,6 +234,20 @@ are done with it in the server.") | |||
| 224 | ;; `emacsclient -t -e '(delete-frame)'' correctly. | 234 | ;; `emacsclient -t -e '(delete-frame)'' correctly. |
| 225 | (setq server-clients (delq client server-clients)))))))) | 235 | (setq server-clients (delq client server-clients)))))))) |
| 226 | 236 | ||
| 237 | (defun server-handle-delete-frame (frame) | ||
| 238 | "Delete the client connection when the emacsclient frame is deleted." | ||
| 239 | (dolist (entry server-frames) | ||
| 240 | (let ((proc (nth 0 entry)) | ||
| 241 | (f (nth 1 entry))) | ||
| 242 | (when (equal frame f) | ||
| 243 | (let ((client (assq proc server-clients))) | ||
| 244 | (setq server-frames (delq entry server-frames)) | ||
| 245 | (delete-process (car client)) | ||
| 246 | (when (assq proc server-clients) | ||
| 247 | ;; This seems to be necessary to handle | ||
| 248 | ;; `emacsclient -t -e '(delete-frame)'' correctly. | ||
| 249 | (setq server-clients (delq client server-clients)))))))) | ||
| 250 | |||
| 227 | (defun server-select-display (display) | 251 | (defun server-select-display (display) |
| 228 | ;; If the current frame is on `display' we're all set. | 252 | ;; If the current frame is on `display' we're all set. |
| 229 | (unless (equal (frame-parameter (selected-frame) 'display) display) | 253 | (unless (equal (frame-parameter (selected-frame) 'display) display) |
| @@ -235,14 +259,14 @@ are done with it in the server.") | |||
| 235 | ;; and select it. | 259 | ;; and select it. |
| 236 | (unless (equal (frame-parameter (selected-frame) 'display) display) | 260 | (unless (equal (frame-parameter (selected-frame) 'display) display) |
| 237 | (select-frame | 261 | (select-frame |
| 238 | (make-frame-on-display | 262 | (make-frame-on-display display))))) |
| 239 | display | ||
| 240 | ;; This frame is only there in place of an actual "current display" | 263 | ;; This frame is only there in place of an actual "current display" |
| 241 | ;; setting, so we want it to be as unobtrusive as possible. That's | 264 | ;; setting, so we want it to be as unobtrusive as possible. That's |
| 242 | ;; what the invisibility is for. The minibuffer setting is so that | 265 | ;; what the invisibility is for. The minibuffer setting is so that |
| 243 | ;; we don't end up displaying a buffer in it (which noone would | 266 | ;; we don't end up displaying a buffer in it (which noone would |
| 244 | ;; notice). | 267 | ;; notice). |
| 245 | '((visibility . nil) (minibuffer . only))))))) | 268 | ;; XXX I have found this behaviour to be surprising and annoying. -- Lorentey |
| 269 | ;; '((visibility . nil) (minibuffer . only))))))) | ||
| 246 | 270 | ||
| 247 | (defun server-unquote-arg (arg) | 271 | (defun server-unquote-arg (arg) |
| 248 | (replace-regexp-in-string | 272 | (replace-regexp-in-string |
| @@ -301,6 +325,7 @@ Prefix arg means just kill any existing server communications subprocess." | |||
| 301 | (server-log (message "Restarting server"))) | 325 | (server-log (message "Restarting server"))) |
| 302 | (letf (((default-file-modes) ?\700)) | 326 | (letf (((default-file-modes) ?\700)) |
| 303 | (add-to-list 'delete-tty-after-functions 'server-handle-delete-tty) | 327 | (add-to-list 'delete-tty-after-functions 'server-handle-delete-tty) |
| 328 | (add-to-list 'delete-frame-functions 'server-handle-delete-frame) | ||
| 304 | (setq server-process | 329 | (setq server-process |
| 305 | (make-network-process | 330 | (make-network-process |
| 306 | :name "server" :family 'local :server t :noquery t | 331 | :name "server" :family 'local :server t :noquery t |
| @@ -324,6 +349,17 @@ Server mode runs a process that accepts commands from the | |||
| 324 | ;; nothing if there is one (for multiple Emacs sessions)? | 349 | ;; nothing if there is one (for multiple Emacs sessions)? |
| 325 | (server-start (not server-mode))) | 350 | (server-start (not server-mode))) |
| 326 | 351 | ||
| 352 | (defmacro server-with-errors-reported (&rest forms) | ||
| 353 | "Evaluate FORMS; if an error occurs, report it to the client | ||
| 354 | and return nil. Otherwise, return the result of the last form. | ||
| 355 | For use in server-process-filter only." | ||
| 356 | `(condition-case err | ||
| 357 | (progn ,@forms) | ||
| 358 | (error (ignore-errors | ||
| 359 | (process-send-string | ||
| 360 | proc (concat "-error " (error-message-string err))) | ||
| 361 | (setq request ""))))) | ||
| 362 | |||
| 327 | (defun server-process-filter (proc string) | 363 | (defun server-process-filter (proc string) |
| 328 | "Process a request from the server to edit some files. | 364 | "Process a request from the server to edit some files. |
| 329 | PROC is the server process. Format of STRING is \"PATH PATH PATH... \\n\"." | 365 | PROC is the server process. Format of STRING is \"PATH PATH PATH... \\n\"." |
| @@ -339,7 +375,7 @@ PROC is the server process. Format of STRING is \"PATH PATH PATH... \\n\"." | |||
| 339 | (coding-system (and default-enable-multibyte-characters | 375 | (coding-system (and default-enable-multibyte-characters |
| 340 | (or file-name-coding-system | 376 | (or file-name-coding-system |
| 341 | default-file-name-coding-system))) | 377 | default-file-name-coding-system))) |
| 342 | client nowait eval newframe | 378 | client nowait eval newframe display |
| 343 | registered ; t if the client is already added to server-clients. | 379 | registered ; t if the client is already added to server-clients. |
| 344 | (files nil) | 380 | (files nil) |
| 345 | (lineno 1) | 381 | (lineno 1) |
| @@ -353,37 +389,53 @@ PROC is the server process. Format of STRING is \"PATH PATH PATH... \\n\"." | |||
| 353 | (cond | 389 | (cond |
| 354 | ((equal "-nowait" arg) (setq nowait t)) | 390 | ((equal "-nowait" arg) (setq nowait t)) |
| 355 | ((equal "-eval" arg) (setq eval t)) | 391 | ((equal "-eval" arg) (setq eval t)) |
| 392 | |||
| 356 | ((and (equal "-display" arg) (string-match "\\([^ ]*\\) " request)) | 393 | ((and (equal "-display" arg) (string-match "\\([^ ]*\\) " request)) |
| 357 | (let ((display (server-unquote-arg (match-string 1 request)))) | 394 | (setq display (match-string 1 request) |
| 358 | (setq request (substring request (match-end 0))) | 395 | request (substring request (match-end 0)))) |
| 359 | (condition-case err | 396 | |
| 360 | (server-select-display display) | 397 | ;; Open a new X frame. |
| 361 | (error (process-send-string proc (nth 1 err)) | 398 | ((equal "-window-system" arg) |
| 362 | (setq request ""))))) | 399 | (server-with-errors-reported |
| 363 | ;; Open a new frame at the client. ARG is the name of the pseudo tty. | 400 | (let ((frame (make-frame-on-display |
| 401 | (or display | ||
| 402 | (frame-parameter nil 'display) | ||
| 403 | (getenv "DISPLAY") | ||
| 404 | (error "Please specify display"))))) | ||
| 405 | (push (list proc frame) server-frames) | ||
| 406 | (select-frame frame) | ||
| 407 | ;; This makes sure that `emacsclient -w -e '(delete-frame)'' works right. | ||
| 408 | (push client server-clients) | ||
| 409 | (setq registered t | ||
| 410 | newframe t)))) | ||
| 411 | |||
| 412 | ;; Open a new tty frame at the client. ARG is the name of the pseudo tty. | ||
| 364 | ((and (equal "-tty" arg) (string-match "\\([^ ]*\\) \\([^ ]*\\) " request)) | 413 | ((and (equal "-tty" arg) (string-match "\\([^ ]*\\) \\([^ ]*\\) " request)) |
| 365 | (let ((tty (server-unquote-arg (match-string 1 request))) | 414 | (let ((tty (server-unquote-arg (match-string 1 request))) |
| 366 | (type (server-unquote-arg (match-string 2 request)))) | 415 | (type (server-unquote-arg (match-string 2 request)))) |
| 367 | (setq request (substring request (match-end 0))) | 416 | (setq request (substring request (match-end 0))) |
| 368 | (condition-case err | 417 | (server-with-errors-reported |
| 369 | (let ((frame (make-frame-on-tty tty type))) | 418 | (let ((frame (make-frame-on-tty tty type))) |
| 370 | (setq server-ttys (cons (list (car client) (frame-tty-name frame)) server-ttys)) | 419 | (push (list (car client) (frame-tty-name frame)) server-ttys) |
| 371 | (process-send-string proc (concat "emacs-pid " (number-to-string (emacs-pid)) "\n")) | 420 | (process-send-string proc (concat "-emacs-pid " (number-to-string (emacs-pid)) "\n")) |
| 372 | (select-frame frame) | 421 | (select-frame frame) |
| 373 | ;; This makes sure that `emacsclient -t -e '(delete-frame)'' works right. | 422 | ;; This makes sure that `emacsclient -t -e '(delete-frame)'' works right. |
| 374 | (push client server-clients) | 423 | (push client server-clients) |
| 375 | (setq registered t | 424 | (setq registered t |
| 376 | newframe t)) | 425 | newframe t))))) |
| 377 | (error (process-send-string proc (concat (nth 1 err) "\n")) | 426 | |
| 378 | (setq request ""))))) | ||
| 379 | ;; ARG is a line number option. | 427 | ;; ARG is a line number option. |
| 380 | ((string-match "\\`\\+[0-9]+\\'" arg) | 428 | ((string-match "\\`\\+[0-9]+\\'" arg) |
| 381 | (setq lineno (string-to-int (substring arg 1)))) | 429 | (setq lineno (string-to-int (substring arg 1)))) |
| 430 | |||
| 382 | ;; ARG is line number:column option. | 431 | ;; ARG is line number:column option. |
| 383 | ((string-match "\\`+\\([0-9]+\\):\\([0-9]+\\)\\'" arg) | 432 | ((string-match "\\`\\+\\([0-9]+\\):\\([0-9]+\\)\\'" arg) |
| 384 | (setq lineno (string-to-int (match-string 1 arg)) | 433 | (setq lineno (string-to-int (match-string 1 arg)) |
| 385 | columnno (string-to-int (match-string 2 arg)))) | 434 | columnno (string-to-int (match-string 2 arg)))) |
| 435 | |||
| 436 | ;; ARG is a filename or a Lisp expression. | ||
| 386 | (t | 437 | (t |
| 438 | |||
| 387 | ;; Undo the quoting that emacsclient does | 439 | ;; Undo the quoting that emacsclient does |
| 388 | ;; for certain special characters. | 440 | ;; for certain special characters. |
| 389 | (setq arg (server-unquote-arg arg)) | 441 | (setq arg (server-unquote-arg arg)) |
| @@ -391,17 +443,14 @@ PROC is the server process. Format of STRING is \"PATH PATH PATH... \\n\"." | |||
| 391 | (if coding-system | 443 | (if coding-system |
| 392 | (setq arg (decode-coding-string arg coding-system))) | 444 | (setq arg (decode-coding-string arg coding-system))) |
| 393 | (if eval | 445 | (if eval |
| 394 | (condition-case err | 446 | (server-with-errors-reported |
| 395 | (let ((v (eval (car (read-from-string arg))))) | 447 | (let ((v (eval (car (read-from-string arg))))) |
| 396 | (when (and (not newframe) v) | 448 | (when (and (not newframe) v) |
| 397 | (with-temp-buffer | 449 | (with-temp-buffer |
| 398 | (let ((standard-output (current-buffer))) | 450 | (let ((standard-output (current-buffer))) |
| 399 | (pp v) | 451 | (pp v) |
| 400 | (process-send-region proc (point-min) (point-max)))))) | 452 | (process-send-string proc "-print ") |
| 401 | (error | 453 | (process-send-region proc (point-min) (point-max))))))) |
| 402 | (ignore-errors | ||
| 403 | (process-send-string | ||
| 404 | proc (concat "*Error* " (error-message-string err)))))) | ||
| 405 | 454 | ||
| 406 | ;; ARG is a file name. | 455 | ;; ARG is a file name. |
| 407 | ;; Collapse multiple slashes to single slashes. | 456 | ;; Collapse multiple slashes to single slashes. |
| @@ -409,6 +458,7 @@ PROC is the server process. Format of STRING is \"PATH PATH PATH... \\n\"." | |||
| 409 | (push (list arg lineno columnno) files)) | 458 | (push (list arg lineno columnno) files)) |
| 410 | (setq lineno 1) | 459 | (setq lineno 1) |
| 411 | (setq columnno 0))))) | 460 | (setq columnno 0))))) |
| 461 | |||
| 412 | (when files | 462 | (when files |
| 413 | (run-hooks 'pre-command-hook) | 463 | (run-hooks 'pre-command-hook) |
| 414 | (server-visit-files files client nowait) | 464 | (server-visit-files files client nowait) |
| @@ -506,15 +556,17 @@ FOR-KILLING if non-nil indicates that we are called from `kill-buffer'." | |||
| 506 | ;; If client now has no pending buffers, | 556 | ;; If client now has no pending buffers, |
| 507 | ;; tell it that it is done, and forget it entirely. | 557 | ;; tell it that it is done, and forget it entirely. |
| 508 | (unless (cdr client) | 558 | (unless (cdr client) |
| 509 | (let ((tty (assq (car client) server-ttys))) | 559 | (let ((tty (cadr (assq (car client) server-ttys))) |
| 510 | (if tty | 560 | (frame (cadr (assq (car client) server-frames)))) |
| 511 | ;; Be careful, if we delete the process before the | 561 | (cond |
| 512 | ;; tty, then the terminal modes will not be restored | 562 | ;; Be careful, if we delete the process before the |
| 513 | ;; correctly. | 563 | ;; tty, then the terminal modes will not be restored |
| 514 | (delete-tty (cadr tty)) | 564 | ;; correctly. |
| 515 | (delete-process (car client)) | 565 | (tty (delete-tty tty)) |
| 516 | (server-log "Close" (car client)) | 566 | (frame (delete-frame frame)) |
| 517 | (setq server-clients (delq client server-clients)))))) | 567 | (t (delete-process (car client)) |
| 568 | (server-log "Close" (car client)) | ||
| 569 | (setq server-clients (delq client server-clients))))))) | ||
| 518 | (setq old-clients (cdr old-clients))) | 570 | (setq old-clients (cdr old-clients))) |
| 519 | (if (and (bufferp buffer) (buffer-name buffer)) | 571 | (if (and (bufferp buffer) (buffer-name buffer)) |
| 520 | ;; We may or may not kill this buffer; | 572 | ;; We may or may not kill this buffer; |