如何异步运行 elisp 函数?
对于那些不知道的人来说, imenu 是 emacs 中的一个东西,它允许模式将一个或多个菜单项插入到菜单栏。最常见的用法是从下拉菜单中访问“目录”,以便用户可以快速跳转到文档中的函数或类或部分的声明等。
imenu 有几种不同的工作方式 -在第一种也是更常用的方式中,主要模式向 imenu 提供正则表达式,并且 imenu 使用这些正则表达式来执行缓冲区扫描并构建索引。主要模式通过将正则表达式列表放入 imenu-generic-expression 中来设置此功能。第二种方法是让主模式执行自己的扫描。它可以通过将变量 imenu-create-index-function 设置为 themode 定义的函数名称来实现此目的,该函数返回包含目录的列表。
我正在执行后者 - imenu-create-index-function
- 但有时 fn 需要很长时间才能运行,比如 3 或 4 秒或更长时间,这会冻结 UI。如果我使操作异步,那就可以解决这个问题。
我了解异步进程。扫描逻辑是在elisp中实现的。是否可以在异步进程中运行 elisp?如果是这样,怎么办?
或者,有没有一种方法可以在 emacs 中异步运行常规 elisp,而不需要诉诸异步进程?
我认为字体锁定的方式是,它在空闲时显示字体。它每次保持状态和字体化一点,总是记住它停止的地方,还有什么需要字体化,自上次字体化运行以来发生了什么变化,等等。我的理解正确吗?也许我可以使用这种渐进的方法。
建议?
for those who don't know, imenu is a thing in emacs that lets a mode insert one or more menu items into the menu bar. The most common usage is to make a "table of contents" accessible from a drop-down menu, so the user can quickly jump to declarations of functions or classes or sections in a document, etc.
imenu has a couple different ways of working - in the first and more commonly used way, a major mode provides regexps to imenu, and imenu uses those regexps to perform the scan of the buffer and build the index. A major mode sets this up by putting the list of regexps into imenu-generic-expression
. The second way is for the major mode to perform its own scan. It can do this by instead setting the variable imenu-create-index-function
to the name of a function defined by themode, which returns a list containing the table of contents.
I'm doing the latter - imenu-create-index-function
- but sometimes the fn takes a looong time to run, say 3 or 4 seconds or more, which freezes the UI. If I make the operation asynchronous, that would solve that problem.
I know about asynch processes. The scan logic is implemented in elisp. Is it possible to run elisp in an asynch process? If so, how?
Or, is there a way to run regular elisp asynchronously in emacs, without resorting to an asynch process?
I think the way font-lock does it is, it fontifies on idle. It keeps state and fontifies a little at a time, always remembering where it left off, what else needs to be fontified, what has changed since the last fontification run, etc. Is my understanding correct? Maybe I could use this incremental approach .
Recommendations?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
要异步运行 elisp,您可以使用
run-with-idle-timer
或run-with-timer
。我想您会想要idle
版本。检查文档链接以获取更多详细信息。注意:如果代码需要 3 或 4 秒才能运行,它仍然需要那么长的时间(并且在运行时冻结您的 Emacs),因此如果您可以将工作分解成足够小的块,那么它只需要 0.5 秒或所以在某个时候,这可能会很有效。
我一直使用的一个软件包,
pabbrev.el
,非常好地使用空闲计时器 - 我从来没有注意到它正在运行。这可能是一个很好的包,可以检查它如何分解工作(它扫描所有打开的缓冲区并建立词频列表)。To run elisp asynchronously you can use either
run-with-idle-timer
orrun-with-timer
. I imagine you'll want theidle
version. Check the documentation links for more details.Note: If the code takes 3 or 4 seconds to run, it'll still take that long (and freeze your Emacs while it runs), so if you can break the work up into small enough chunks that it only takes .5 seconds or so at a time, that might work well.
One package that I use all the time,
pabbrev.el
, uses idle timers really well - I never notice it running. That might be a good package to examine to see how it breaks up the work (it is scanning all open buffers and building up a word frequency list).TreyJackson 和 jeremiahd 发布的答案在 2011 年就有效。现在,在 2018 年,这里是 异步进程。
The answers posted by TreyJackson and jeremiahd were valid back in year 2011. Now, in 2018, here is a link to the emacs documentation for asynchronous processes.
您可以通过以批处理模式生成 emacs 作为进程来在异步进程中运行 elisp,请参阅 http://www.emacswiki.org/emacs/BatchMode。 emacswiki.org/emacs/BatchMode 。除此之外,据我所知基本上就没有什么了。
它看起来像 http://nschum.de/src/emacs/async-eval/ 基本上包含了执行此操作所需的样板。不知道它是否得到积极维护或其他什么。
You can run elisp in an asynch process by spawning emacs in batch mode as the process, see http://www.emacswiki.org/emacs/BatchMode . Other than that, there's basically nothing as far as I know.
It looks like http://nschum.de/src/emacs/async-eval/ basically wraps the boilerplate necessary to do this. No clue if it's actively maintained or anything though.