Do things after selecting window24 Jan 2015
I saw this question today at Stack Overflow - Emacs: How to enable toolbar mode and menubar mode only under a certain mode?. Myself, I never use the menubar or the toolbar. But maybe it's just because it's useless in the modes to which I'm used to. What if there was an option to have the menu bar on just for a few select modes? For instance, if I decided that I want to learn Haskell tomorrow, I wouldn't mind to have the menu bar on for a while, especially if there was some useful stuff there in the menu.
I'm not aware of a convenient hook for this job; I tried
after-change-major-mode-hook, and it doesn't work when switching
windows. The universal
post-command-hook would be totally lame for this task.
Then it occurred to me, that
select-window has to be called
eventually in most circumstances. Even
This is what I came up with so far:
(defvar menubar-last (make-ring 20)) (ring-insert menubar-last "dummy") (defadvice select-window (after select-window-menubar activate) (unless (equal (buffer-name) (ring-ref menubar-last 0)) (ring-insert menubar-last (buffer-name)) (let ((yes-or-no (if (memq major-mode '(r-mode lisp-interaction-mode)) 1 -1))) (menu-bar-mode yes-or-no) (tool-bar-mode yes-or-no))))
The Ring trickery
It's necessary at least for
magit. Doing, for instance,
ll operation switches windows many times.
So I added a check that the current buffer isn't selected twice.
In Emacs, a ring is like a stack with a limited length: you push onto the head, and if the stack becomes too large, the stuff gets removed from the tail. Perfect for debugging this code, since I don't care what happened 20 window switches ago, I'm only interested in the most recent state. One small annoyance is that the following code will throw, if the ring is empty:
(ring-ref menubar-last 0)
I would prefer if it just returned
nil instead. Hence the trick of
menubar-last with a dummy item. Note that this
annoyance propagates to other areas:
(current-kill 0) will throw if
you haven't yet copied text since Emacs started.
I'm not sure if this code is more annoying than useful, but, at least, I learned something new while writing it, and I hope you did too. If you know of a better way to accomplish the original task, please do share.