【问题标题】:Emacs -- creating / deleting a `buffer-local` repeating idle-timerEmacs——创建/删除一个`buffer-local`重复空闲定时器
【发布时间】:2014-06-03 05:36:58
【问题描述】:

我有一个使用重复空闲计时器的次要模式:

(timer-activate-when-idle
    (run-with-idle-timer 0.2 t 'function-name))

我正在尝试找出处理在多个缓冲区中处于活动状态的相同次要模式的最佳方法,以及如何在终止缓冲区或停用次要模式而不影响其他缓冲区时取消计时器。

如果可能的话,我首选的处理方法是创建一个 buffer-local 空闲计时器并为其分配一个唯一的名称/标识以便取消。如果这种方法是可行的,那么一个例子将不胜感激。

我最不喜欢处理这个问题的方法是遍历所有打开的缓冲区,以确定这个特定的次要模式是否在其中任何一个中处于活动状态,如果没有,则取消计时器。换句话说,将有一个计时器为所有缓冲区提供服务。

对于如何处理这种情况的任何其他想法将不胜感激。

[注意:我知道我可以设置一个条件来阻止计时器采取任何行动(例如,如果不是次要模式 xyz),但是,我喜欢在有不再需要特定的计时器。]

【问题讨论】:

    标签: emacs elisp


    【解决方案1】:

    嗯,你几乎可以按照你的描述去做。

    (defvar-local my-local-timer nil "Buffer-local timer.")
    
    (defun do-something-with (buf)
      "Callback function for `my-local-timer'."
      (when (buffer-live-p buf)
        (with-current-buffer buf
          ...)))
    
    (setq my-local-timer
          (run-with-idle-timer 0.2 t 'do-something-with (current-buffer)))
    
    (add-hook 'kill-buffer-hook
              (lambda () 
                (when (timerp my-local-timer) 
                  (cancel-timer my-local-timer))))
    

    定时器对象被添加到timer-idle-list,变量只是为了在你想修改/取消它时可以通过名称访问它。因此,变量为缓冲区本地没有问题(除非您设法在不取消计时器的情况下终止缓冲区)。

    您是否实际上想要为每个缓冲区运行一个单独的计时器是另一回事,但如果您愿意(或需要),您当然可以这样做,而且可能会减少内务处理这样做。

    如果您选择单定时器路由,但您不希望循环遍历 所有 缓冲区,您可以简单地维护一个感兴趣的缓冲区列表(启用该模式可以添加当前缓冲区; 禁用该模式可以将其删除),然后您可以对其进行迭代。由于存在列表可能会留下陈旧条目的方法,因此您的计时器函数会想要检查每个缓冲区是否有效,并且模式变量是否仍然设置,并删除无效条目。如果列表为空,您可以取消计时器。

    【讨论】:

    • 非常感谢您的示例和解释-非常感谢! :)
    • 如果您要从 kill-buffer-hook 的列表中删除死缓冲区,为什么需要 buffer-live-p?你说有办法,但我很好奇它们是什么。
    • 我认为该评论专门针对在启用/禁用次要模式时从列表中添加/删除项目的想法,而不是使用kill-buffer-hook。使用那个钩子 as well 可能就足够了。 (也就是说,验证某个任意计时器驱动回调的缓冲区参数对我来说似乎不是一个的想法;但是我不确定我是否知道一个示例失败案例我写这篇文章的时间。)
    猜你喜欢
    • 2014-07-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多