Reverse theme rotation direction when called with a prefix

When calling modus-themes-rotate interactively and with a prefix
argument, reverse the sense of rotation from right to left among the
modus-themes-to-rotate.  Explicit calls to modus-themes-rotate can
pass a non-nil REVERSE argument to achieve the same for their THEMES.

* modus-themes.el: (modus-themes-rotate, modus-themes--rotate-p,
modus-themes--rotate, modus-themes--next-in-rotation):

Add an optional REVERSE argument to modus-themes-rotate.  When called
interactively this becomes the current prefix argument.  Replace
helper functions with a single modus-themes--next-in-rotation.  Update
doc strings.
This commit is contained in:
Jacob S. Gordon 2025-05-21 17:56:25 -04:00 committed by Protesilaos Stavrou
parent 01b78e587d
commit 21b77de155
No known key found for this signature in database
GPG key ID: 99BD6459CD5CA3EA

View file

@ -1262,34 +1262,31 @@ Disable other themes per `modus-themes-disable-other-themes'."
;;;;; Rotate through a list of themes
(defun modus-themes--rotate (themes)
"Rotate THEMES rightward such that the car is moved to the end."
(if (proper-list-p themes)
(let* ((index (seq-position themes (modus-themes--current-theme)))
(offset (1+ index)))
(append (nthcdr offset themes) (take offset themes)))
(error "The `%s' is not a list" themes)))
(defun modus-themes--rotate-p (themes)
"Return a new theme among THEMES if it is possible to rotate to it."
(if-let* ((new-theme (car (modus-themes--rotate themes))))
(if (eq new-theme (modus-themes--current-theme))
(car (modus-themes--rotate-p (modus-themes--rotate themes)))
new-theme)
(defun modus-themes--next-in-rotation (themes &optional reverse)
"Return a new theme among THEMES if it is possible to rotate to it.
The argument REVERSE controls the direction of rotation."
(if-let* ((index (seq-position themes (modus-themes--current-theme)))
(offset (mod (if reverse (1- index) (1+ index))
(length themes)))
(new-theme (nth offset themes)))
new-theme
(error "Cannot determine a theme among `%s'" themes)))
;;;###autoload
(defun modus-themes-rotate (themes)
(defun modus-themes-rotate (themes &optional reverse)
"Rotate to the next theme among THEMES.
When called interactively THEMES is the value of `modus-themes-to-rotate'.
When called interactively THEMES is the value of `modus-themes-to-rotate'
and REVERSE is the prefix argument.
If the current theme is already the next in line, then move to the one
after. Perform the rotation rightwards, such that the first element in
the list becomes the last. Do not modify THEMES in the process."
(interactive (list modus-themes-to-rotate))
after. The rotation is performed rightwards if REVERSE is nil (the
default), and leftwards if REVERSE is non-nil. Perform the rotation
such that the current element in the list becomes the last. Do not
modify THEMES in the process."
(interactive (list modus-themes-to-rotate current-prefix-arg))
(unless (proper-list-p themes)
"This is not a list of themes: `%s'" themes)
(let ((candidate (modus-themes--rotate-p themes)))
(let ((candidate (modus-themes--next-in-rotation themes reverse)))
(if (modus-themes--modus-p candidate)
(progn
(message "Rotating to `%s'" (propertize (symbol-name candidate) 'face 'success))