Make minor mode ARG work as documented

* lisp/emacs-lisp/easy-mmode.el (easy-mmode--arg-docstring):
Clarify when minor modes are switched on/off when called from lisp
(bug#44341).
(define-minor-mode): Make calls from Lisp switch the mode on/off
as documented.
This commit is contained in:
Lars Ingebrigtsen 2020-11-01 15:00:36 +01:00
parent ecec9a259b
commit 2a4b0da28c
2 changed files with 40 additions and 9 deletions

View file

@ -84,10 +84,13 @@ replacing its case-insensitive matches with the literal string in LIGHTER."
(defconst easy-mmode--arg-docstring
"
If called interactively, enable %s if ARG is positive, and
disable it if ARG is zero or negative. If called from Lisp,
also enable the mode if ARG is omitted or nil, and toggle it
if ARG is `toggle'; disable the mode otherwise.
If called interactively, toggle `%s'. If the prefix argument is
positive, enable the mode, and if it is zero or negative, disable
the mode.
If called from Lisp, toggle the mode if if ARG is `toggle'.
Enable the mode if ARG is nil, omitted, or is a positive number.
All other values will disable the mode.
The mode's hook is called both when the mode is enabled and when
it is disabled.")
@ -301,13 +304,20 @@ or call the function `%s'."))))
,(easy-mmode--mode-docstring doc pretty-name keymap-sym)
;; Use `toggle' rather than (if ,mode 0 1) so that using
;; repeat-command still does the toggling correctly.
(interactive (list (or current-prefix-arg 'toggle)))
(interactive (list (if current-prefix-arg
(prefix-numeric-value current-prefix-arg)
'toggle)))
(let ((,last-message (current-message)))
(,@setter
(if (eq arg 'toggle)
(not ,getter)
;; A nil argument also means ON now.
(> (prefix-numeric-value arg) 0)))
(cond ((eq arg 'toggle)
(not ,getter))
((and (numberp arg)
(> arg 0))
t)
((eq arg nil)
t)
(t
nil)))
,@body
;; The on/off hooks are here for backward compatibility only.
(run-hooks ',hook (if ,getter ',hook-on ',hook-off))

View file

@ -44,6 +44,27 @@
'(c-mode (not message-mode mail-mode) text-mode))
t))))
(ert-deftest easy-mmode--minor-mode ()
(with-temp-buffer
(define-minor-mode test-mode "A test.")
(should (eq test-mode nil))
(test-mode t)
(should (eq test-mode nil))
(test-mode nil)
(should (eq test-mode t))
(test-mode -33)
(should (eq test-mode nil))
(test-mode 33)
(should (eq test-mode t))
(test-mode 0)
(should (eq test-mode nil))
(test-mode 'toggle)
(should (eq test-mode t))
(test-mode 'toggle)
(should (eq test-mode nil))
(test-mode "what")
(should (eq test-mode nil))))
(provide 'easy-mmode-tests)
;;; easy-mmode-tests.el ends here