[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.
- A programming puzzle with buffer-local hooks,
Clément Pit-Claudel <=