1

Just the other day I did

$ emacs -nw file1

Then later on I did ^Z to suspend it, and was back in the shell.

And then I wanted to do

$ emacsclient -n file2

and have file2 there, ready in emacs when I unsuspended emacs via the

$ %1

command.

To make a long story short, it didn't work out.

Yes, you might say, "Stop pretending it's 1987. Just open another window on your laptop." And yes, I could have just used C-x C-f to open file2 within emacs.

Yes, but I still want to know how to do the above emacsclient trick, all with only one shell.

1
  • 1
    Not just 1987. This question is useful if you are using a Linux virtual console, or a remote KVM console.
    – dcorking
    Commented Oct 13 at 8:32

2 Answers 2

3

Well I at least managed to return to emacs with "the file in my mouth" (think dogs fetching the newspaper.)

$ emacsclient -n file2& %1

Don't ask me why. It just works.

3

[Not an answer: the OP provided his own answer which works. This is just an explanation of why the original attempt didn't work out.]

After suspending the emacs process, you then execute emacsclient -n file2. That writes the message to the communication socket and waits for emacs to acknowledge receipt, but emacs does not respond. If you wait long enough, the client complains that the server is not responding and asks you to press C-c to put it out of its misery. If, before the timeout, you suspend the client with C-z, and bring back emacs with fg %1 (or its synonym %1), then emacs gets a backtrace:

Debugger entered--Lisp error: (cl-assertion-failed ((eq (match-end 0) (length string)) nil))
  cl--assertion-failed((eq (match-end 0) (length string)))
  server--process-filter-1(#<process server <3>> "-dir /home/nick/ -nowait -current-frame -tty /dev/pts/2 xterm-256color -file /tmp/foo2 \n-suspend \n")
  server--process-filter-all-pending()
  server-process-filter(#<process server <3>> "-dir /home/nick/ -nowait -current-frame -tty /dev/pts/2 xterm-256color -file /tmp/foo2 \n-suspend \n")

Note that the string that the process filter received from the client consists of two lines:

  • -dir /home/nick/ -nowait -current-frame -tty /dev/pts/2 xterm-256color -file /tmp/foo2
  • -suspend

Now if you look at the source of server--process-filter-1 (just press RET on the link in the backtrace) and read the code, you'll see the following:

          ...
          ;; In earlier versions of server.el (where we used an `emacsserver'                                                                                                     
          ;; process), there could be multiple lines.  Nowadays this is not                                                                                                       
          ;; supported any more.                                                                                                                                                  
          (cl-assert (eq (match-end 0) (length string)))
          ...

So it's the two-line message that is sent in the original attempt that's causing the failure.

By adding the & in the emacsclient invocation, you put it in the background without having to suspend it, so bringing the server back with %1 allows the server to read the (now single-line) command, acknowledge it allowing the emacsclient -n invocation to exit and then carry out the command.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.