This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
Hi!
How would find out if a minor mode is active with Emacs Lisp?
Specifically, I want to check if org-tree-slide-mode
is active or not.
For major modes, (eq 'org-mode major-mode)
seems to do what I want. I’ve looked for a minor-mode-p
function, but not found anything. I did find the minor-mode-alist
and minor-mode-list
variables, and I suppose I could use those. Still curious how others would solve this. I suppose the meta-question is which manual I should have read to figure this out from the built-in-docs.
Edit: minor-mode-list
seems to contain all the minor modes, not just the active minor modes. Not what I wanted.
I know very little of emacs, but I recall (due to being a Lisp-2) that you can eval minor modes as either values or functions; the value returns whether or not the mode is active and the function will either enable or disable it
When I try to evaluate
org-mode
as a value, I get this in *Messages*
:
eval: Symbol's value as variable is void: org-mode
Strangely, evaluating
org-tree-slide-mode
just gives me nil
.> Most minor modes also have a mode variable, with the same name as the mode command. Its value is non-`nil` if the mode is enabled, and nil
if it is disabled.
^^ what the manual says about minor modes. For major modes, it seems to mostly mention that major-mode
variable, which you can use to check the current major mode.
Here’s my final result:
(defun teod-org-slideshow-enable! ()
(interactive)
(when (eq 'org-mode major-mode)
(org-tree-slide-mode 1)
(text-scale-adjust -2))
nil)
(defun teod-org-slideshow-disable! ()
(interactive)
(when (eq 'org-mode major-mode)
(org-tree-slide-mode 0)
(text-mode)
(org-mode)
(text-scale-adjust 0)))
(defun teod-org-slideshow-toggle! ()
(interactive)
;; only if we're in org-mode ...
(if (eq 'org-mode major-mode)
(if org-tree-slide-mode
(teod-org-slideshow-disable!)
(teod-org-slideshow-enable!))
(message "Error: teod-org-slideshow-toggle! can only be run in org-mode buffers.")))
It seems to do what I want — though I’m still surprised about the different behavior for org-mode
and org-tree-slide-mode
.org-mode is a major mode while I guess org-tree-slide-mode is a minor mode(?)
Ah, ok, så it’s expected to be this way. Thanks a lot for explaining, and thanks for the pointers on minor modes! 🙏
I think you might be able to simplify your functions by using hooks; you can try something like (add-hook 'org-mode-hook #'teod-org-slideshow-enable)
.
> Every major mode, apart from Fundamental mode, defines a mode hook, a customizable list of Lisp functions to run each time the mode is enabled in a buffer.
https://www.gnu.org/software/emacs/manual/html_node/emacs/Major-Modes.html
that way you don't need to check which major mode is active within the function
(add-hook 'org-mode-hook #'teod-org-slideshow-enable)
Would this start teod-org-slide-show-enable!
every time I open an org-mode file? I’d still prefer to be able to edit org-mode files as text (not slideshows)ah, yes, you're correct
Maybe I could use org-tree-slide-mode-hook
, though.
But I’m not sure where to put my “run code when minor mode is disabled”.
https://emacs.stackexchange.com/a/47092 suggests that the minor mode hook is run both when entering and exiting the minor mode
oooh, nice. I’ll try a refactor. This looks cleaner, I don’t have to remember my own function names, and I can use the default key binding for org-tree-slide-mode
.
New code:
(defun teod-org-tree-slide-tweaks ()
"My own settings & tweaks for org-tree-slideshow-mode"
(if org-tree-slide-mode
(text-scale-adjust -2)
(progn
(text-mode)
(org-mode)
(text-scale-adjust 0))))
;; depth is 10 to make it happen /after/ other things.
(add-hook 'org-tree-slide-mode-hook 'teod-org-tree-slide-tweaks 10)
Much cleaner!
Thanks again for the discussion & pointers, @U0178V2SLAY!