如何异步运行elisp函数?

13

对于那些不知道的人,imenu是emacs中的一个功能,允许模式将一个或多个菜单项插入到菜单栏中。最常见的用法是从下拉菜单中让“目录”可访问,这样用户可以快速跳转到函数、类或文档中的章节声明等。

imenu有几种不同的工作方式 - 在第一种更常用的方式中,主模式提供正则表达式给imenu,imenu使用这些正则表达式来扫描缓冲区并构建索引。通过将正则表达式列表放入imenu-generic-expression中来设置此项。第二种方式是让主模式执行它自己的扫描。它可以通过将变量imenu-create-index-function设置为该模式定义的函数名称来完成。该函数返回包含目录的列表。

我正在进行后者- imenu-create-index-function- 但是有时候这个函数需要很长时间运行,比如3到4秒甚至更长时间,这会导致界面冻结。如果我将操作做成异步的,那么就可以解决这个问题。

我知道异步进程。扫描逻辑是在elisp中实现的。是否可以在异步进程中运行elisp?如果可以,怎么做?

或者,是否有一种方法可以在emacs中异步地运行常规elisp,而不用诉诸于异步进程?

我认为字体锁定所做的方式是在空闲时进行字体锁定。它保持状态并逐步进行字体锁定,始终记住上次离开的位置、需要进行字体锁定的其他内容、自上次字体锁定运行以来发生了什么变化等。我理解得对吗?也许我可以使用这个增量方法。

有什么建议吗?

3个回答

11

要异步运行elisp,您可以使用run-with-idle-timerrun-with-timer。 我想您可能需要使用idle版本。有关更多详细信息,请查看文档链接。

注意:如果代码需要3或4秒钟才能运行,它仍将需要相同的时间(并在运行时冻结Emacs),因此如果您可以将工作分解成每次只需0.5秒左右的小块,那可能会很好。

我经常使用的一个包pabbrev.el非常好地使用了空闲计时器-我从未注意到它正在运行。这可能是一个好的包,可以检查它如何分解工作(它正在扫描所有打开的缓冲区并建立单词频率列表)。


2
现在,2018年,emacs记录了以下内容:http://www.gnu.org/software/emacs/manual/html_node/elisp/Asynchronous-Processes.html#Asynchronous-Processes - user1404316

4

TreyJackson和jeremiahd在2011年发布的答案是有效的。现在是2018年,这里有一个链接到emacs文档中关于异步进程的内容。


2
该部分仅记录了如何异步使用外部进程,而不是如何异步评估elisp代码。 - dalanicolai
1
@dalanicolai 是正确的。问题是关于如何异步运行elisp,而不是外部进程。这个答案既误导又没有回答问题。我很少会给负面评价。 - eeowaa

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接