当服务器繁忙时,如何从emacsclient内部向emacs发送C-g/quit信号?



在我当前的设置中,我在引导时运行emacs --daemon,然后使用emacsclient来工作。然而,我注意到一个问题。当一个复杂的处理块正在发生时,C-g停止工作:复杂的工作不能提前停止或终止。据我所知,这是因为emacs客户机在处理来自客户机的任何输入之前需要等待服务器的确认。因此,C-g在我最需要它的时候无法工作——以摆脱耗时或可能具有破坏性的进程。

是否有解决这个问题的方法,或者告诉服务器进程"停止那个!"?手册的"退出"或"紧急逃生"部分似乎没有提到这个问题的存在——所以这也有可能是我做错了什么。如果是这样,我做错了什么?

如果答案是"不,没有办法做你想做的事;emacsclient进程无法应对服务器被阻塞了一段重要的时间,"我会标记为接受的答案,指出在代码或文档中,答案可以有:我还没能找到这样的事情。(

到目前为止,我发现唯一有效的方法是使用命令行kill向繁忙的emacs进程发送SIGUSR2信号—无论它是否作为服务器运行(使用--daemon)。这将不会强制终止emacs进程,同时能够中断它正在做的事情。让我们尝试一个示例来中断在emacs服务器上运行的sleep-for循环。(是的,sleep-for可以被C-g打破,但这只是一个例子。当emacs不响应键盘命令时,它可以在一些情况下工作。

首先,启动emacs服务器,然后使用emacsclient连接它,输入M-: (sleep-for 120)。现在转到另一个终端,使用命令行查找服务器的进程ID: ps x|grep 'emacs.*--daemon'。假设我们在这里找到的PID是12345。现在使用终端将其断开:

kill -USR2 12345

我们现在应该看到sleep-for循环中断。在某些情况下,我需要多次发送此信号。

还要注意SIGUSR1不起作用,因此建议使用SIGUSR2,这可能只适用于v24以上的Emacs版本。希望这对你有帮助!

不幸的是,我不认为有一个优雅的解决方案。一种可能性是创建一个空闲的emacsclient会话,隐藏在tmux/screen会话中,您可以将其调出,然后在那里按下C-g。但这有点恶心。

最新更新