![当 control-g 在非常大的文件中不起作用时,如何中断 emacs?](https://linux22.com/image/1376770/%E5%BD%93%20control-g%20%E5%9C%A8%E9%9D%9E%E5%B8%B8%E5%A4%A7%E7%9A%84%E6%96%87%E4%BB%B6%E4%B8%AD%E4%B8%8D%E8%B5%B7%E4%BD%9C%E7%94%A8%E6%97%B6%EF%BC%8C%E5%A6%82%E4%BD%95%E4%B8%AD%E6%96%AD%20emacs%EF%BC%9F.png)
在 Emacs 中查看非常大(例如 128MB)的文件并跳转到文件末尾时,我遇到了某种 O(n^2) 或更糟糕的行为。我认为这可能与我的着色算法有关,该算法根据上下文为文本着色。如果我输入 control-g(键盘退出),操作不会受到影响。我想以某种方式恢复我的 emacs 会话,而不是直接终止它。我尝试发送 SIGINT,但 emacs 刚刚退出。我可以发送任何信号,或者以其他方式(也许在调试器中)强制正在运行的任何操作放弃并将控制权返回给我?
答案1
我怀疑这是字体锁定模式。这可能只对可见部分起作用。它可能正在复制内存中的数据。
sigusr1
sigusr2
这些事件是在 Emacs 进程收到信号
SIGUSR1
和时生成的SIGUSR2
。它们不包含其他数据,因为信号不携带其他信息。它们可用于调试(请参阅错误调试)。
我不知道它会做什么(或者您正在运行哪个版本的 emacs)但您可以尝试一个可能非破坏性的信号(USR1 或 USR2)。
$ kill -USR1进程号
或者你可以去睡觉,看看它是否恢复。
答案2
这是我对类似问题的回答,希望对您有所帮助:https://stackoverflow.com/a/47070702/3818556
到目前为止,我发现唯一可行的方法是SIGUSR2
使用命令行向繁忙的 emacs 进程发送信号kill
——无论它是否作为服务器运行(使用--daemon
)。这不会强制终止 emacs 进程,但能够中断它正在执行的操作。让我们尝试一个例子来中断sleep-for
在 emacs 服务器上运行的循环。(是的,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 版本。希望这能有所帮助!
答案3
我不知道 emacs 是否进行任何信号处理,但您可以通过放入server-start
~/.emacs 文件来使用 Emacs 服务器,这样您就可以在正在运行的 emacs 实例上执行 RPC。
然后,当您想杀死 emacs 并写入时,您可以从 shell 中调用emacsclient -e '(save-buffers-kill-emacs t)'
。