Emacs - 创建/删除`buffer-local`重复空闲计时器

时间:2014-06-03 05:36:58

标签: emacs elisp

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

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

我试图找出处理多个缓冲区中相同的次模式的最佳方法,以及如何在杀死缓冲区或取消激活次模式时取消定时器而不影响其他缓冲区。

如果可能的话,我首选的方法是创建一个 buffer-local idle-timer并为其取消一个唯一的名称/标识。如果这种方法属于可能性范围,那么我们将非常感激一个例子。

我最不喜欢的方法是循环遍历所有打开的缓冲区,以确定这些特定的次模式是否在其中任何一个中都有效,如果没有,则取消定时器。换句话说,会有一个为所有缓冲区提供服务的计时器。

非常感谢有关如何处理这种情况的任何其他想法。

[注意:我意识到我可以放入一个阻止计时器采取任何行动的条件(例如,如果不是小模式xyz),但是,我喜欢在我自己之后整洁和清理不再需要特定的计时器。]

1 个答案:

答案 0 :(得分:9)

嗯,你几乎可以做你所描述的事情。

(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,并且该变量只是为了在您想要修改/取消它时可以按名称访问它。因此,变量是缓冲区本地没有问题(除非你设法在不取消定时器的情况下杀死缓冲区)。

实际是否希望每个缓冲区运行一个单独的计时器是另一回事,但如果你想(或需要),你当然可以这样做,并且可能这样做不那么管家。

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