I would like to use an idle timer that is local to the current buffer in one of my packages. However, I can't seem to find out how.

How can I create (or fake) the behavior of a buffer local idle timer? Is the only way to call a function that checks (current-buffer)?

  • 3
    Here is a link to a related thread entitled Emacs — creating / deleting a buffer-local repeating idle-timer: stackoverflow.com/questions/24007822/… – lawlist May 19 '15 at 22:07
  • Ah, thank you. What does common etiquette dictate I do now? – PythonNut May 19 '15 at 22:19
  • 1
    Try out the solution in the related thread -- if it doesn't work entirely to your satisfaction, then clarify your question. If it works for your needs, then you can make the decision how to handle it. There are some people who prefer to treat this forum as a separate entity when classifying a thread as a duplicate, whereas other people would prefer that it be marked as a duplicate (if an answer exists in another forum) or deleted. In either case, you may need to spend some time trying out the solution in various contexts before you are sure it adequately addresses your needs. – lawlist May 19 '15 at 22:22
  • 1
    If it works for you, please post an answer here with appropriate reference to the other one. Closing or deleting this question would deprive our nice experts (who might not be on SO) of the chance to provide a better answer. – Malabarba May 20 '15 at 9:10
  • At minimum it would be helpful to ensure that both Q&As are cross-referenced via comments. Personally I feel that if strong answers already exist on another site in the network, you should endeavour to boost/strengthen that location as the source of answers to this question, rather than risk splitting the solutions across multiple locations (which is detrimental to the people searching for them). (edit: Ah, this comment was written before I actually followed the link. I didn't realise it was referring to one of my answers! FWIW I wasn't attempting to suggest that my answer was definitive.) – phils Jul 19 '15 at 10:32

(defun run-with-local-idle-timer (secs repeat function &rest args)
  "Like `run-with-idle-timer', but always runs in the `current-buffer'.

Cancels itself, if this buffer was killed."
  (let* (;; Chicken and egg problem.
         (fns (make-symbol "local-idle-timer"))
         (timer (apply 'run-with-idle-timer secs repeat fns args))
         (fn `(lambda (&rest args)
                (if (not (buffer-live-p ,(current-buffer)))
                    (cancel-timer ,timer)
                  (with-current-buffer ,(current-buffer)
                    (apply (function ,function) args))))))
    (fset fns fn)
  • Finally managed to try this out, and it works beautifully (albeit a bit hackishly). – PythonNut Nov 2 '15 at 19:01
(set (make-local-variable 'my-timer)
  • I admit, I'm not entirely sure what to make of this... – PythonNut May 20 '15 at 16:17
  • @PythonNut Completed form will return an idle-timer object, which is buffer-local - that's what you asked for. – Andreas Röhler May 20 '15 at 17:33

If you mean a way to run some code with idle timer in such a way that the passed code runs in the original buffer, maybe you can adapt the following snippet that I am currently using. Please keep in mind that this snippet assumes that it is placed in an *.el file with lexical binding.

(defun my-delayed-tex-font-lock ()
  (let ((here (current-buffer)))
     10 nil
     (lambda ()
       (with-current-buffer here
(add-hook 'TeX-mode-hook 'my-delayed-tex-font-lock)

What this snippet does is make my function my-tex-font-lock run after ten seconds of idle time for each TeX file buffer. When I open alice.tex, quickly switch to bob.txt and wait for ten seconds doing nothing, then my-tex-font-lock will kick in and it will affect the alice.tex buffer but not bob.txt.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.