Brighid McDonnell
Brighid McDonnell

Reputation: 4343

How can I send a C-g/quit signal to emacs from within emacsclient when the server is busy?

In my current setup, I run emacs --daemon on boot and thereafter use emacsclient to do work. However, I've noticed a problem with this. When a complex chunk of processing is happening, C-g stops working: the complex work can't be halted or terminated early. As far as I can tell, this is because an emacs client needs to wait to be acknowledged by the server before any input from the client is processed. As a result, C-g won't work when I most need it - to bail out of processes that are time-consuming or possibly destructive.

Are there any workarounds to this, or a way to tell the server process "stop that!"? Nothing in the Quitting or Emergency Escape sections of the manual seems to acknowledge that this problem exists - so it's also possible that this is the result of me doing something wrong. If so, what am I doing wrong?

If the answer is "no, there is no way to do what you want; emacsclient processes can't cope with the server being blocked for a nontrivial amount of time," I'll mark as accepted the answer that points out in code or documention where that answer can be had: I haven't been able to find such a thing. :(

Upvotes: 1

Views: 1208

Answers (2)

Luke Lee
Luke Lee

Reputation: 301

So far the only way I found ever working is to send a SIGUSR2 signal to the busy emacs process using command line kill -- no matter if it's running as a server (with --daemon) or not. This will not force terminating the emacs process while being able to interrupt what it's doing. Let's try an example to break a sleep-for loop running on emacs server. (Yes, sleep-for can be break by C-g but this is just an example. It worked on some cases when emacs does not respond to keyboard commands.)

First, start emacs server then use emacsclient connect to it, enter M-: (sleep-for 120). Now go to another terminal and find the process ID of the server using command line: ps x|grep 'emacs.*--daemon'. Assuming the PID we found here is 12345. Now use the terminal to break it:

kill -USR2 12345

We should now see the sleep-for loop interrupted. On some cases I need to send this signal multiple times.

Also notice that SIGUSR1 does not work so SIGUSR2 is recommended, and this might only work on Emacs versions greater than v24. Hope this helps!

Upvotes: 7

Eric Johnson
Eric Johnson

Reputation: 826

Unfortunately, I don't think there's an elegant solution. One possibility is to create a spare emacsclient session tucked away in a tmux/screen session that you can bring back up and then punch in C-g there. But that's kind of gross.

Upvotes: -1

Related Questions