emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

A programming puzzle with buffer-local hooks


From: Clément Pit-Claudel
Subject: A programming puzzle with buffer-local hooks
Date: Thu, 18 May 2017 11:10:04 -0400
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.1.1

Hey emacs-devel,

I'm writing a minor mode that shows notifications, but only if Emacs is in the 
background.  At first sight it looks simple enough:

    (defvar my--emacs-has-focus t)

    (defun my--notify-focus-in ()
      "Handle a focus-in event."
      (setq my--emacs-has-focus t))

    (defun my--notify-focus-out ()
      "Handle a focus-out event."
      (setq my--emacs-has-focus nil))

    (define-minor-mode my-notifying-mode
      "Maybe show notifications."
      :lighter " not"
      (cond
       (my-notifying-mode
        (add-hook 'focus-in-hook #'my--notify-focus-in)
        (add-hook 'focus-out-hook #'my--notify-focus-out))
       (t
        (remove-hook 'focus-in-hook #'my--notify-focus-in)
        (remove-hook 'focus-out-hook #'my--notify-focus-out))))

But now there's a trick: if the mode is disabled in one buffer (but not in 
others), it will remove its hook and break itself in all buffers in which it's 
still enabled.

The usual trick is to make the hook buffer local.  But this doesn't work here: 
making focus-in-hook buffer-local seems to cause it to run only if the buffer 
is current (or if the buffer's window is selected?).
I can think of two other tricks: reference counting (every time the mode is 
disabled, check whether it's enabled anywhere else), and never removing the 
hook.

Any better idea?

Thanks!
Clément.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]