3

I use emacs in the terminal, typically with many emacs instances running at once in different tabs. This is a perfect use case for emacsclient, but it has always had various glitches that have stopped me from using it. In particular, sometimes one client will "block" the other, preventing it from doing anything. It looks like things work better in emacs 24.4, but it still happens.

For instance, if I start two clients, and run M-g M-g in one, to get the "Goto line" entry, the other client will be completely locked down until I quit in the first one.

I am using emacs 24.4 compiled without windowed support in Mac OS X 10.10 (in iTerm 2). I can reproduce it by starting emacs --daemon -Q. If you want the exact emacs binary I am using, download Miniconda for OS X and run conda install -c asmeurer emacs.

5

No, you can't "prevent emacsclient from blocking other [emacsclient] instances", because that's not what's happening.

emacsclient isn't running any elisp at all, so it's not the cause of the blockage. The Emacs server is running the elisp code, and Emacs is single-threaded -- so if the server thread is blocked then none of the clients will be receiving any output. There's nothing that a client can do about that.

You can, as mentioned in the comments, run multiple independent servers side by side. The simplest way to do this is via the --daemon=NAME command line argument:

emacs --daemon=foo
emacs --daemon=bar
emacsclient --socket-name=foo
emacsclient --socket-name=bar

or short-cut it to:

emacsclient -a "" --socket-name=foo
emacsclient -a "" --socket-name=bar
| improve this answer | |
  • I guess this is workable. I can add export TTY=$(basename `tty`) in my bash profile and use --socket-name=$TTY. – asmeurer Nov 7 '14 at 17:25
  • A disadvantage here is that I no longer get any shared state if I open the same file in different instances. I would still very much appreciate an actual solution to this problem. – asmeurer Nov 7 '14 at 17:31
  • Even with this solution, emacsclient (or the server, whatever) will still sometimes completely block all clients, forcing me to find the PID for the server process and kill -9 it. – asmeurer Nov 7 '14 at 20:54
  • And just now I've got a server that even when I kill it, every time it restarts it immediately blocks, making it unusable. – asmeurer Nov 7 '14 at 21:18
  • There is certainly no solution to Emacs being single-threaded, short of re-writing it to be multi-threaded (and there are many good reasons why this has never happened). – phils Nov 9 '14 at 5:35
2

Got it! Good news is it works perfectly to have the minibuffer active in one window and type in another*. Bad news is it requires recompiling emacs, as it's the C-implementation of read_minibuf which forces single-kboard. It's probably possible to reimplement the minibuffer largely in elisp, intercepting most calls to it, but that would be somewhat complex...

Anyway, with emacs-26, the line to comment is src/minibuf.c:480,

temporarily_switch_to_single_kboard (XFRAME (mini_frame));

*I've tested it some, no promises it won't break things in subtle ways. Also note that the minibuffer uses a single, global input state, so opening the mini buffer closes any mini buffers opened in other frames. If you enable recursive-minibuffers, you do get your partial command back when the other person is done, but there's still likely to be some odd behaviour. Also, things like find-file use switch_to_single_kboard too.

I'll probably follow up on the mailing list to see if this can get turned into a proper customizable variable, possibly disabling all switch_to_single_kboard calls, as it's a must for sharing an emacs instance on a joint project.

If you want to disable single-keyboard mode everywhere, insert return; on a new line at src/keyboard.c:883.

As requested, a diff...

*** src/minibuf.c       2020-02-20 17:27:13.472345220 -0800
--- src.orig/minibuf.c  2020-02-20 17:26:20.164343599 -0800
***************
*** 478,482 ****
      Fraise_frame (mini_frame);

<   //temporarily_switch_to_single_kboard (XFRAME (mini_frame));

    /* We have to do this after saving the window configuration
--- 478,482 ----
      Fraise_frame (mini_frame);

>   temporarily_switch_to_single_kboard (XFRAME (mini_frame));

        /* We have to do this after saving the window configuration

And the other diff

*** src/keyboard.c      2020-02-20 17:27:01.452344855 -0800
--- src.orig/keyboard.c 2020-02-20 17:26:15.040343443 -0800
***************
*** 881,885 ****
  temporarily_switch_to_single_kboard (struct frame *f)
  {
<   return false;
    bool was_locked = single_kboard;
--- 881,884 ----
| improve this answer | |
  • 1
    That sounds like something I won't be trying :) Could you please show actual diffs in your answer? Only showing line numbers isn't nearly as useful. – phils Feb 20 at 5:38
  • Note that this produces poor results in emacs-27 (and probably later), since partial commands are stored (and completed) globally. Then again, that's an issue even without unlocking multi-keyboard mode in the minibuffer. – Perkins Feb 22 at 18:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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