I'm working on an Emacs minor mode, and I'd like it to apply only when the major mode is a certain mode (i.e. js-mode
). In other words, when I activate my-super-mode, I'd like the keymap it defines to be available in all JS buffers (like it was global) but without affecting non-js buffers.
I know it's possible via hooks but I'd like to avoid this solution. Ideally my minor mode would be activated only when needed via M-x (and when activated it should be in effect in all JS buffers). Possible?
One solution that comes to mind is to define a buffer-local minor mode that implements the actual functionality, but is not invoked directly by the user and its name prefixed by an internal prefix to prevent accidental triggering:
(define-minor-mode my--mode
"Mode implementing blah, invoke it with M-x my-super-mode."
nil " Super" nil
;; mode definition goes here, including keymaps, etc.
)
The public mode invoked by the user is global. When switched on or off, it automatically switches the internal mode in all existing and future JS buffers:
(defun my--mode-set-maybe ()
(my--mode (if my-super-mode 1 0)))
(define-minor-mode my-super-mode
"Super mode, only in effect in JS buffers."
nil "" nil
:global t
(dolist (buf (buffer-list))
(with-current-buffer buf
(my--mode-set-maybe))))
(add-hook 'js-mode-hook 'my--mode-set-maybe)