1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2026-01-03 10:31:37 -08:00

Tag themes with properties

* doc/emacs/custom.texi (Custom Themes): Document 'theme-choose-variant'.
* doc/lispref/customize.texi (Custom Themes): Document the new
optional argument to 'deftheme'.
(Autoload): Mention that 'deftheme' is not copied verbatim.
* etc/themes/adwaita-theme.el (adwaita): Add properties.
* etc/themes/deeper-blue-theme.el (deeper-blue): Add properties.
* etc/themes/dichromacy-theme.el (dichromacy): Add properties.
* etc/themes/light-blue-theme.el (light-blue): Add properties.
* etc/themes/manoj-dark-theme.el (manoj-dark): Add properties.
* etc/themes/misterioso-theme.el (misterioso): Add properties.
* etc/themes/tango-dark-theme.el (tango-dark): Add properties.
* etc/themes/tango-theme.el (tango): Add properties.
* etc/themes/tsdh-dark-theme.el (tsdh-dark): Add properties.
* etc/themes/tsdh-light-theme.el (tsdh-light): Add properties.
* etc/themes/wheatgrass-theme.el (wheatgrass): Add properties.
* etc/themes/whiteboard-theme.el (whiteboard): Add properties.
* etc/themes/wombat-theme.el (wombat): Add properties.
* etc/themes/modus-operandi-theme.el: Add properties.
* etc/themes/modus-vivendi-theme.el: Add properties.
* etc/themes/leuven-dark-theme.el (leuven-dark): Add properties.
* etc/themes/leuven-theme.el (leuven): Add properties.
* lisp/custom.el (deftheme): Allow for optional arguments to set the
property list.
(custom-declare-theme): Accept the same optional arguments as 'deftheme'.
(theme-list-variants): Add new function.
(theme-choose-variant): Add new command for switching between members
of a theme family.
(toggle-theme): Add an alias for 'theme-choose-variant'.
* lisp/emacs-lisp/loaddefs-gen.el (loaddefs-generate--make-autoload):
Handle 'defcustom's by extracting the properties.  (Bug#57639)
This commit is contained in:
Philip Kaludercic 2022-09-17 20:11:42 +02:00
parent 9fcd59a978
commit da2e6da722
No known key found for this signature in database
GPG key ID: F2C3CC513DB89F66
22 changed files with 179 additions and 26 deletions

View file

@ -667,6 +667,16 @@ type @kbd{M-x disable-theme}.
the @file{*Custom Themes*} buffer; or type @kbd{M-x describe-theme} the @file{*Custom Themes*} buffer; or type @kbd{M-x describe-theme}
anywhere in Emacs and enter the theme name. anywhere in Emacs and enter the theme name.
@findex theme-choose-variant
Some themes have variants (most often just two: light and dark). You
can switch to another variant using @kbd{M-x theme-choose-variant}.
If the currently active theme has only one other variant, it will be
selected; if there are more variants, the command will prompt you
which one to switch to.
Note that @code{theme-choose-variant} only works if a single theme
is active.
@node Creating Custom Themes @node Creating Custom Themes
@subsection Creating Custom Themes @subsection Creating Custom Themes
@cindex custom themes, creating @cindex custom themes, creating

View file

@ -1428,12 +1428,32 @@ emacs, The GNU Emacs Manual}.)
be a call to @code{deftheme}, and the last form should be a call to be a call to @code{deftheme}, and the last form should be a call to
@code{provide-theme}. @code{provide-theme}.
@defmac deftheme theme &optional doc @defmac deftheme theme &optional doc &rest properties
This macro declares @var{theme} (a symbol) as the name of a Custom This macro declares @var{theme} (a symbol) as the name of a Custom
theme. The optional argument @var{doc} should be a string describing theme. The optional argument @var{doc} should be a string describing
the theme; this is the description shown when the user invokes the the theme; this is the description shown when the user invokes the
@code{describe-theme} command or types @kbd{?} in the @samp{*Custom @code{describe-theme} command or types @kbd{?} in the @samp{*Custom
Themes*} buffer. Themes*} buffer. The remaining arguments @var{properties} are used
pass a property list with theme attributes.
The following attributes are supported:
@table @code
@item :family
A symbol designating what ``family'' a theme belongs to. A
@dfn{family} of themes is a set of similar themes that differ by minor
aspects, such as face colors that are meant for the light vs dark
background of the frame.
@item :kind
A symbol. If a theme is enabled and this property has the value
@code{color-scheme}, then the @code{theme-choose-variant} command will
look for other available themes that belong to the same family in
order to switch the themes. Other values are currently unspecified
and should not be used.
@item :background-mode
A symbol, either @code{light} or @code{dark}. This attribute is
currently unused, but should still be specified.
@end table
Two special theme names are disallowed (using them causes an error): Two special theme names are disallowed (using them causes an error):
@code{user} is a dummy theme that stores the user's direct @code{user} is a dummy theme that stores the user's direct

View file

@ -662,7 +662,7 @@ and @code{define-overloadable-function} (see the commentary in
and @code{define-global-minor-mode}. and @code{define-global-minor-mode}.
@item Other definition types: @item Other definition types:
@code{defcustom}, @code{defgroup}, @code{defclass} @code{defcustom}, @code{defgroup}, @code{deftheme}, @code{defclass}
(@pxref{Top,EIEIO,,eieio,EIEIO}), and @code{define-skeleton} (@pxref{Top,EIEIO,,eieio,EIEIO}), and @code{define-skeleton}
(@pxref{Top,Autotyping,,autotype,Autotyping}). (@pxref{Top,Autotyping,,autotype,Autotyping}).
@end table @end table

View file

@ -21,10 +21,13 @@
;;; Code: ;;; Code:
;;;###theme-autoload
(deftheme adwaita (deftheme adwaita
"Face colors similar to the default theme of Gnome 3 (Adwaita). "Face colors similar to the default theme of Gnome 3 (Adwaita).
The colors are chosen to match Adwaita window decorations and the The colors are chosen to match Adwaita window decorations and the
default look of the Gnome 3 desktop.") default look of the Gnome 3 desktop."
:background-mode 'light
:kind 'color-scheme)
(let ((class '((class color) (min-colors 89)))) (let ((class '((class color) (min-colors 89))))
(custom-theme-set-faces (custom-theme-set-faces

View file

@ -21,8 +21,11 @@
;;; Code: ;;; Code:
;;;###theme-autoload
(deftheme deeper-blue (deftheme deeper-blue
"Face colors using a deep blue background.") "Face colors using a deep blue background."
:background-mode 'dark
:kind 'color-scheme)
(let ((class '((class color) (min-colors 89)))) (let ((class '((class color) (min-colors 89))))
(custom-theme-set-faces (custom-theme-set-faces

View file

@ -21,6 +21,7 @@
;;; Code: ;;; Code:
;;;###theme-autoload
(deftheme dichromacy (deftheme dichromacy
"Face colors suitable for red/green color-blind users. "Face colors suitable for red/green color-blind users.
The color palette is from B. Wong, Nature Methods 8, 441 (2011). The color palette is from B. Wong, Nature Methods 8, 441 (2011).
@ -28,7 +29,9 @@ It is intended to provide good variability while being easily
differentiated by individuals with protanopia or deuteranopia. differentiated by individuals with protanopia or deuteranopia.
Basic, Font Lock, Isearch, Gnus, Message, Flyspell, and Basic, Font Lock, Isearch, Gnus, Message, Flyspell, and
Ansi-Color faces are included.") Ansi-Color faces are included."
:background-mode 'light
:kind 'color-scheme)
(let ((class '((class color) (min-colors 89))) (let ((class '((class color) (min-colors 89)))
(orange "#e69f00") (orange "#e69f00")

View file

@ -5,7 +5,7 @@
;; Author: Fabrice Niessen <(concat "fniessen" at-sign "pirilampo.org")> ;; Author: Fabrice Niessen <(concat "fniessen" at-sign "pirilampo.org")>
;; Contributor: Thibault Polge <(concat "thibault" at-sign "thb.lt")> ;; Contributor: Thibault Polge <(concat "thibault" at-sign "thb.lt")>
;; URL: https://github.com/fniessen/emacs-leuven-dark-theme ;; URL: https://github.com/fniessen/emacs-leuven-dark-theme
;; Version: 20220202.1126 ;; Version: 20221010.1208
;; Keywords: color theme ;; Keywords: color theme
;; This file is part of GNU Emacs. ;; This file is part of GNU Emacs.
@ -93,11 +93,15 @@ CONTROL can be a number, nil, or t. When t, use DEFAULT-HEIGHT."
;;; Theme Faces. ;;; Theme Faces.
;;;###theme-autoload
(deftheme leuven-dark (deftheme leuven-dark
"Face colors with a light background. "Face colors with a light background.
Basic, Font Lock, Isearch, Gnus, Message, Org mode, Diff, Ediff, Basic, Font Lock, Isearch, Gnus, Message, Org mode, Diff, Ediff,
Flyspell, Semantic, and Ansi-Color faces are included -- and much Flyspell, Semantic, and Ansi-Color faces are included -- and much
more...") more..."
:background-mode 'dark
:family 'leuven
:kind 'color-scheme)
(let ((class '((class color) (min-colors 89))) (let ((class '((class color) (min-colors 89)))

View file

@ -4,7 +4,7 @@
;; Author: Fabrice Niessen <(concat "fniessen" at-sign "pirilampo.org")> ;; Author: Fabrice Niessen <(concat "fniessen" at-sign "pirilampo.org")>
;; URL: https://github.com/fniessen/emacs-leuven-theme ;; URL: https://github.com/fniessen/emacs-leuven-theme
;; Version: 20200513.1928 ;; Version: 20221010.1209
;; Keywords: color theme ;; Keywords: color theme
;; This file is part of GNU Emacs. ;; This file is part of GNU Emacs.
@ -74,11 +74,15 @@ CONTROL can be a number, nil, or t. When t, use DEFAULT-HEIGHT."
;;; Theme Faces. ;;; Theme Faces.
;;;###theme-autoload
(deftheme leuven (deftheme leuven
"Face colors with a light background. "Face colors with a light background.
Basic, Font Lock, Isearch, Gnus, Message, Org mode, Diff, Ediff, Basic, Font Lock, Isearch, Gnus, Message, Org mode, Diff, Ediff,
Flyspell, Semantic, and Ansi-Color faces are included -- and much Flyspell, Semantic, and Ansi-Color faces are included -- and much
more...") more..."
:background-mode 'light
:kind 'color-scheme
:family 'leuven)
(let ((class '((class color) (min-colors 89))) (let ((class '((class color) (min-colors 89)))

View file

@ -26,8 +26,11 @@
;;; Code: ;;; Code:
;;;###theme-autoload
(deftheme light-blue (deftheme light-blue
"Face colors utilizing a light blue background.") "Face colors utilizing a light blue background."
:background-mode 'light
:kind 'color-scheme)
(make-obsolete 'light-blue nil "29.1") (make-obsolete 'light-blue nil "29.1")

View file

@ -64,10 +64,13 @@
;;; Code: ;;; Code:
;;;###theme-autoload
(deftheme manoj-dark (deftheme manoj-dark
"Very high contrast faces with a black background. "Very high contrast faces with a black background.
This theme avoids subtle color variations, while avoiding the This theme avoids subtle color variations, while avoiding the
jarring angry fruit salad look to reduce eye fatigue.") jarring angry fruit salad look to reduce eye fatigue."
:background-mode 'dark
:kind 'color-scheme)
(custom-theme-set-faces (custom-theme-set-faces
'manoj-dark 'manoj-dark

View file

@ -21,8 +21,11 @@
;;; Code: ;;; Code:
;;;###theme-autoload
(deftheme misterioso (deftheme misterioso
"Predominantly blue/cyan faces on a dark cyan background.") "Predominantly blue/cyan faces on a dark cyan background."
:background-mode 'dark
:kind 'color-scheme)
(let ((class '((class color) (min-colors 89)))) (let ((class '((class color) (min-colors 89))))

View file

@ -71,4 +71,6 @@ which corresponds to a minimum contrast in relative luminance of
(provide-theme 'modus-operandi)) (provide-theme 'modus-operandi))
;;;###theme-autoload (put 'modus-operandi 'theme-properties '(:background-mode light :kind color-scheme :family modus))
;;; modus-operandi-theme.el ends here ;;; modus-operandi-theme.el ends here

View file

@ -71,4 +71,6 @@ which corresponds to a minimum contrast in relative luminance of
(provide-theme 'modus-vivendi)) (provide-theme 'modus-vivendi))
;;;###theme-autoload (put 'modus-vivendi 'theme-properties '(:background-mode dark :kind color-scheme :family modus))
;;; modus-vivendi-theme.el ends here ;;; modus-vivendi-theme.el ends here

View file

@ -27,10 +27,15 @@
;;; Code: ;;; Code:
;;;###theme-autoload
(deftheme tango-dark (deftheme tango-dark
"Face colors using the Tango palette (dark background). "Face colors using the Tango palette (dark background).
Basic, Font Lock, Isearch, Gnus, Message, Ediff, Flyspell, Basic, Font Lock, Isearch, Gnus, Message, Ediff, Flyspell,
Semantic, and Ansi-Color faces are included.") Semantic, and Ansi-Color faces are included."
:background-mode 'dark
:kind 'color-scheme
:family 'tango)
(let ((class '((class color) (min-colors 89))) (let ((class '((class color) (min-colors 89)))
;; Tango palette colors. ;; Tango palette colors.

View file

@ -27,10 +27,14 @@
;;; Code: ;;; Code:
;;;###theme-autoload
(deftheme tango (deftheme tango
"Face colors using the Tango palette (light background). "Face colors using the Tango palette (light background).
Basic, Font Lock, Isearch, Gnus, Message, Ediff, Flyspell, Basic, Font Lock, Isearch, Gnus, Message, Ediff, Flyspell,
Semantic, and Ansi-Color faces are included.") Semantic, and Ansi-Color faces are included."
:background-mode 'light
:kind 'color-scheme
:family 'tango)
(let ((class '((class color) (min-colors 89))) (let ((class '((class color) (min-colors 89)))
;; Tango palette colors. ;; Tango palette colors.

View file

@ -19,8 +19,12 @@
;;; Code: ;;; Code:
;;;###theme-autoload
(deftheme tsdh-dark (deftheme tsdh-dark
"A dark theme used and created by Tassilo Horn.") "A dark theme used and created by Tassilo Horn."
:background-mode 'dark
:kind 'color-scheme
:family 'tsdh)
(custom-theme-set-faces (custom-theme-set-faces
'tsdh-dark 'tsdh-dark

View file

@ -19,9 +19,13 @@
;;; Code: ;;; Code:
;;;###theme-autoload
(deftheme tsdh-light (deftheme tsdh-light
"A light Emacs theme. "A light Emacs theme.
Used and created by Tassilo Horn.") Used and created by Tassilo Horn."
:background-mode 'light
:kind 'color-scheme
:family 'tsdh)
(custom-theme-set-faces (custom-theme-set-faces
'tsdh-light 'tsdh-light

View file

@ -19,11 +19,14 @@
;;; Code: ;;; Code:
;;;###theme-autoload
(deftheme wheatgrass (deftheme wheatgrass
"High-contrast green/blue/brown faces on a black background. "High-contrast green/blue/brown faces on a black background.
Basic, Font Lock, Isearch, Gnus, and Message faces are included. Basic, Font Lock, Isearch, Gnus, and Message faces are included.
The default face foreground is wheat, with other faces in shades The default face foreground is wheat, with other faces in shades
of green, brown, and blue.") of green, brown, and blue."
:background-mode 'dark
:kind 'color-scheme)
(let ((class '((class color) (min-colors 89)))) (let ((class '((class color) (min-colors 89))))
(custom-theme-set-faces (custom-theme-set-faces

View file

@ -21,8 +21,11 @@
;;; Code: ;;; Code:
;;;###theme-autoload
(deftheme whiteboard (deftheme whiteboard
"Face colors similar to markers on a whiteboard.") "Face colors similar to markers on a whiteboard."
:background-mode 'light
:kind 'color-scheme)
(let ((class '((class color) (min-colors 89)))) (let ((class '((class color) (min-colors 89))))
(custom-theme-set-faces (custom-theme-set-faces

View file

@ -21,11 +21,14 @@
;;; Code: ;;; Code:
;;;###theme-autoload
(deftheme wombat (deftheme wombat
"Medium-contrast faces with a dark gray background. "Medium-contrast faces with a dark gray background.
Adapted, with permission, from a Vim color scheme by Lars H. Nielsen. Adapted, with permission, from a Vim color scheme by Lars H. Nielsen.
Basic, Font Lock, Isearch, Gnus, Message, and Ansi-Color faces Basic, Font Lock, Isearch, Gnus, Message, and Ansi-Color faces
are included.") are included."
:background-mode 'dark
:kind 'color-scheme)
(let ((class '((class color) (min-colors 89)))) (let ((class '((class color) (min-colors 89))))
(custom-theme-set-faces (custom-theme-set-faces

View file

@ -1152,9 +1152,11 @@ list, in which A occurs before B if B was defined with a
;; (provide-theme 'THEME) ;; (provide-theme 'THEME)
(defmacro deftheme (theme &optional doc) (defmacro deftheme (theme &optional doc &rest properties)
"Declare THEME to be a Custom theme. "Declare THEME to be a Custom theme.
The optional argument DOC is a doc string describing the theme. The optional argument DOC is a doc string describing the theme.
PROPERTIES are interpreted as a property list that will be stored
in the `theme-properties' property for THEME.
Any theme `foo' should be defined in a file called `foo-theme.el'; Any theme `foo' should be defined in a file called `foo-theme.el';
see `custom-make-theme-feature' for more information." see `custom-make-theme-feature' for more information."
@ -1164,18 +1166,25 @@ see `custom-make-theme-feature' for more information."
;; It is better not to use backquote in this file, ;; It is better not to use backquote in this file,
;; because that makes a bootstrapping problem ;; because that makes a bootstrapping problem
;; if you need to recompile all the Lisp files using interpreted code. ;; if you need to recompile all the Lisp files using interpreted code.
(list 'custom-declare-theme (list 'quote theme) (list 'quote feature) doc))) (list 'custom-declare-theme (list 'quote theme) (list 'quote feature) doc
(cons 'list properties))))
(defun custom-declare-theme (theme feature &optional doc) (defun custom-declare-theme (theme feature &optional doc properties)
"Like `deftheme', but THEME is evaluated as a normal argument. "Like `deftheme', but THEME is evaluated as a normal argument.
FEATURE is the feature this theme provides. Normally, this is a symbol FEATURE is the feature this theme provides. Normally, this is a
created from THEME by `custom-make-theme-feature'." symbol created from THEME by `custom-make-theme-feature'. The
optional argument DOC may contain the documentation for THEME.
The optional argument PROPERTIES may contain a property list of
attributes associated with THEME."
(unless (custom-theme-name-valid-p theme) (unless (custom-theme-name-valid-p theme)
(error "Custom theme cannot be named %S" theme)) (error "Custom theme cannot be named %S" theme))
(unless (memq theme custom-known-themes) (unless (memq theme custom-known-themes)
(push theme custom-known-themes)) (push theme custom-known-themes))
(put theme 'theme-feature feature) (put theme 'theme-feature feature)
(when doc (put theme 'theme-documentation doc))) (when doc
(put theme 'theme-documentation doc))
(when properties
(put theme 'theme-properties properties)))
(defun custom-make-theme-feature (theme) (defun custom-make-theme-feature (theme)
"Given a symbol THEME, create a new symbol by appending \"-theme\". "Given a symbol THEME, create a new symbol by appending \"-theme\".
@ -1372,6 +1381,58 @@ Return t if THEME was successfully loaded, nil otherwise."
(enable-theme theme)) (enable-theme theme))
t) t)
(defun theme-list-variants (theme &rest list)
"Return a list of theme variants for THEME.
By default this will use all known custom themes (see
`custom-available-themes') to check for variants. This can be
restricted if the optional argument LIST containing a list of
theme symbols to consider."
(let* ((properties (get theme 'theme-properties))
(family (plist-get properties :family)))
(seq-filter
(lambda (variant)
(and (eq (plist-get (get variant 'theme-properties) :family)
family)
(not (eq variant theme))))
(or list (custom-available-themes)))))
(defun theme-choose-variant (&optional no-confirm no-enable)
"Switch from the current theme to one of its variants.
The current theme will be disabled before variant is enabled. If
the current theme has only one variant, switch to that variant
without prompting, otherwise prompt for the variant to select.
See `load-theme' for the meaning of NO-CONFIRM and NO-ENABLE."
(interactive)
(let ((active-color-schemes
(seq-filter
(lambda (theme)
;; FIXME: As most themes currently do not have a `:kind'
;; tag, it is assumed that a theme is a color scheme by
;; default. This should be reconsidered in the future.
(memq (plist-get (get theme 'theme-properties) :kind)
'(color-scheme nil)))
custom-enabled-themes)))
(cond
((length= active-color-schemes 0)
(user-error "No theme is active, cannot toggle"))
((length> active-color-schemes 1)
(user-error "More than one theme active, cannot unambiguously toggle")))
(let* ((theme (car active-color-schemes))
(family (plist-get (get theme 'theme-properties) :family)))
(unless family
(error "Theme `%s' does not have any known variants" theme))
(let* ((variants (theme-list-variants theme))
(choice (cond
((null variants)
(error "`%s' has no variants" theme))
((length= variants 1)
(car variants))
((intern (completing-read "Load custom theme: " variants))))))
(disable-theme theme)
(load-theme choice no-confirm no-enable)))))
(defalias 'toggle-theme #'theme-choose-variant)
(defun custom-theme-load-confirm (hash) (defun custom-theme-load-confirm (hash)
"Query the user about loading a Custom theme that may not be safe. "Query the user about loading a Custom theme that may not be safe.
The theme should be in the current buffer. If the user agrees, The theme should be in the current buffer. If the user agrees,

View file

@ -283,6 +283,12 @@ expression, in which case we want to handle forms differently."
,@(when-let ((safe (plist-get props :safe))) ,@(when-let ((safe (plist-get props :safe)))
`((put ',varname 'safe-local-variable ,safe)))))) `((put ',varname 'safe-local-variable ,safe))))))
;; Extract theme properties.
((eq car 'deftheme)
(let* ((name (car-safe (cdr-safe form)))
(props (nthcdr 3 form)))
`(put ',name 'theme-properties (list ,@props))))
((eq car 'defgroup) ((eq car 'defgroup)
;; In Emacs this is normally handled separately by cus-dep.el, but for ;; In Emacs this is normally handled separately by cus-dep.el, but for
;; third party packages, it can be convenient to explicitly autoload ;; third party packages, it can be convenient to explicitly autoload