584 |
;; and it is not in load-history yet. |
;; and it is not in load-history yet. |
585 |
((equal load "cus-edit")) |
((equal load "cus-edit")) |
586 |
(t (condition-case nil (load load) (error nil)))))))) |
(t (condition-case nil (load load) (error nil)))))))) |
587 |
|
|
588 |
(defvar custom-known-themes '(user standard) |
(defvar custom-known-themes '(user standard) |
589 |
"Themes that have been defined with `deftheme'. |
"Themes that have been defined with `deftheme'. |
590 |
The default value is the list (user standard). The theme `standard' |
The default value is the list (user standard). The theme `standard' |
593 |
Additional themes declared with the `deftheme' macro will be added to |
Additional themes declared with the `deftheme' macro will be added to |
594 |
the front of this list.") |
the front of this list.") |
595 |
|
|
|
(defun custom-declare-theme (theme feature &optional doc &rest args) |
|
|
"Like `deftheme', but THEME is evaluated as a normal argument. |
|
|
FEATURE is the feature this theme provides. This symbol is created |
|
|
from THEME by `custom-make-theme-feature'." |
|
|
(add-to-list 'custom-known-themes theme) |
|
|
(put theme 'theme-feature feature) |
|
|
(when doc |
|
|
(put theme 'theme-documentation doc)) |
|
|
(while args |
|
|
(let ((arg (car args))) |
|
|
(setq args (cdr args)) |
|
|
(unless (symbolp arg) |
|
|
(error "Junk in args %S" args)) |
|
|
(let ((keyword arg) |
|
|
(value (car args))) |
|
|
(unless args |
|
|
(error "Keyword %s is missing an argument" keyword)) |
|
|
(setq args (cdr args)) |
|
|
(cond ((eq keyword :short-description) |
|
|
(put theme 'theme-short-description value)) |
|
|
((eq keyword :immediate) |
|
|
(put theme 'theme-immediate value)) |
|
|
((eq keyword :variable-set-string) |
|
|
(put theme 'theme-variable-set-string value)) |
|
|
((eq keyword :variable-reset-string) |
|
|
(put theme 'theme-variable-reset-string value)) |
|
|
((eq keyword :face-set-string) |
|
|
(put theme 'theme-face-set-string value)) |
|
|
((eq keyword :face-reset-string) |
|
|
(put theme 'theme-face-reset-string value))))))) |
|
|
|
|
|
(defmacro deftheme (theme &optional doc &rest args) |
|
|
"Declare custom theme THEME. |
|
|
The optional argument DOC is a doc string describing the theme. |
|
|
The remaining arguments should have the form |
|
|
|
|
|
[KEYWORD VALUE]... |
|
|
|
|
|
The following KEYWORD's are defined: |
|
|
|
|
|
:short-description |
|
|
VALUE is a short (one line) description of the theme. If not |
|
|
given, DOC is used. |
|
|
:immediate |
|
|
If VALUE is non-nil, variables specified in this theme are set |
|
|
immediately when loading the theme. |
|
|
:variable-set-string |
|
|
VALUE is a string used to indicate that a variable takes its |
|
|
setting from this theme. It is passed to FORMAT with the name |
|
|
of the theme as an additional argument. If not given, a |
|
|
generic description is used. |
|
|
:variable-reset-string |
|
|
VALUE is a string used in the case a variable has been forced |
|
|
to its value in this theme. It is passed to FORMAT with the |
|
|
name of the theme as an additional argument. If not given, a |
|
|
generic description is used. |
|
|
:face-set-string |
|
|
VALUE is a string used to indicate that a face takes its |
|
|
setting from this theme. It is passed to FORMAT with the name |
|
|
of the theme as an additional argument. If not given, a |
|
|
generic description is used. |
|
|
:face-reset-string |
|
|
VALUE is a string used in the case a face has been forced to |
|
|
its value in this theme. It is passed to FORMAT with the name |
|
|
of the theme as an additional argument. If not given, a |
|
|
generic description is used. |
|
|
|
|
|
Any theme `foo' should be defined in a file called `foo-theme.el'; |
|
|
see `custom-make-theme-feature' for more information." |
|
|
(let ((feature (custom-make-theme-feature theme))) |
|
|
;; It is better not to use backquote in this file, |
|
|
;; because that makes a bootstrapping problem |
|
|
;; if you need to recompile all the Lisp files using interpreted code. |
|
|
(nconc (list 'custom-declare-theme |
|
|
(list 'quote theme) |
|
|
(list 'quote feature) |
|
|
doc) args))) |
|
|
|
|
|
(defun custom-make-theme-feature (theme) |
|
|
"Given a symbol THEME, create a new symbol by appending \"-theme\". |
|
|
Store this symbol in the `theme-feature' property of THEME. |
|
|
Calling `provide-theme' to provide THEME actually puts `THEME-theme' |
|
|
into `features'. |
|
|
|
|
|
This allows for a file-name convention for autoloading themes: |
|
|
Every theme X has a property `provide-theme' whose value is \"X-theme\". |
|
|
\(require-theme X) then attempts to load the file `X-theme.el'." |
|
|
(intern (concat (symbol-name theme) "-theme"))) |
|
|
|
|
596 |
(defsubst custom-theme-p (theme) |
(defsubst custom-theme-p (theme) |
597 |
"Non-nil when THEME has been defined." |
"Non-nil when THEME has been defined." |
598 |
(memq theme custom-known-themes)) |
(memq theme custom-known-themes)) |
605 |
;;; Initializing. |
;;; Initializing. |
606 |
|
|
607 |
(defun custom-push-theme (prop symbol theme mode value) |
(defun custom-push-theme (prop symbol theme mode value) |
608 |
"Add (THEME MODE VALUE) to the list in property PROP of SYMBOL. |
"Record a value for face or variable SYMBOL in custom theme THEME. |
609 |
If the first element in that list is already (THEME ...), |
PROP is`theme-face' for a face, `theme-value' for a variable. |
610 |
discard it first. |
The value is specified by (THEME MODE VALUE), which is interpreted |
611 |
|
by `custom-theme-value'. |
612 |
|
|
613 |
MODE can be either the symbol `set' or the symbol `reset'. If it is the |
MODE can be either the symbol `set' or the symbol `reset'. If it is the |
614 |
symbol `set', then VALUE is the value to use. If it is the symbol |
symbol `set', then VALUE is the value to use. If it is the symbol |
615 |
`reset', then VALUE is the mode to query instead. |
`reset', then VALUE is another theme, whose value for this face or |
616 |
|
variable should be used. |
617 |
|
|
618 |
In the following example for the variable `goto-address-url-face', the |
In the following example for the variable `goto-address-url-face', the |
619 |
theme `subtle-hacker' uses the same value for the variable as the theme |
theme `subtle-hacker' uses the same value for the variable as the theme |
646 |
The user has not customized the face; had he done that, |
The user has not customized the face; had he done that, |
647 |
the list would contain an entry for the `user' theme, too. |
the list would contain an entry for the `user' theme, too. |
648 |
See `custom-known-themes' for a list of known themes." |
See `custom-known-themes' for a list of known themes." |
649 |
(let ((old (get symbol prop))) |
(let* ((old (get symbol prop)) |
650 |
(if (eq (car-safe (car-safe old)) theme) |
(setting (assq theme old))) |
651 |
(setq old (cdr old))) |
;; Alter an existing theme-setting for the symbol, |
652 |
(put symbol prop (cons (list theme mode value) old)))) |
;; or add a new one. |
653 |
|
(if setting |
654 |
|
(progn |
655 |
|
(setcar (cdr setting) mode) |
656 |
|
(setcar (cddr setting) value)) |
657 |
|
(put symbol prop (cons (list theme mode value) old))) |
658 |
|
;; Record, for each theme, all its settings. |
659 |
|
(put theme 'theme-settings |
660 |
|
(cons (list prop symbol theme mode value) |
661 |
|
(get theme 'theme-settings))))) |
662 |
|
|
663 |
(defvar custom-local-buffer nil |
(defvar custom-local-buffer nil |
664 |
"Non-nil, in a Customization buffer, means customize a specific buffer. |
"Non-nil, in a Customization buffer, means customize a specific buffer. |
665 |
If this variable is non-nil, it should be a buffer, |
If this variable is non-nil, it should be a buffer, |
868 |
(put symbol 'customized-value nil)) |
(put symbol 'customized-value nil)) |
869 |
;; Changed? |
;; Changed? |
870 |
(not (equal customized (get symbol 'customized-value))))) |
(not (equal customized (get symbol 'customized-value))))) |
871 |
|
|
872 |
|
;;; Defining themes. |
873 |
|
|
874 |
|
;; deftheme is used at the beginning of the file that records a theme. |
875 |
|
|
876 |
;;; Theme Manipulation |
(defmacro deftheme (theme &optional doc &rest args) |
877 |
|
"Declare custom theme THEME. |
878 |
|
The optional argument DOC is a doc string describing the theme. |
879 |
|
The remaining arguments should have the form |
880 |
|
|
881 |
|
[KEYWORD VALUE]... |
882 |
|
|
883 |
|
The following KEYWORD's are defined: |
884 |
|
|
885 |
|
:short-description |
886 |
|
VALUE is a short (one line) description of the theme. If not |
887 |
|
given, DOC is used. |
888 |
|
:immediate |
889 |
|
If VALUE is non-nil, variables specified in this theme are set |
890 |
|
immediately when loading the theme. |
891 |
|
:variable-set-string |
892 |
|
VALUE is a string used to indicate that a variable takes its |
893 |
|
setting from this theme. It is passed to FORMAT with the name |
894 |
|
of the theme as an additional argument. If not given, a |
895 |
|
generic description is used. |
896 |
|
:variable-reset-string |
897 |
|
VALUE is a string used in the case a variable has been forced |
898 |
|
to its value in this theme. It is passed to FORMAT with the |
899 |
|
name of the theme as an additional argument. If not given, a |
900 |
|
generic description is used. |
901 |
|
:face-set-string |
902 |
|
VALUE is a string used to indicate that a face takes its |
903 |
|
setting from this theme. It is passed to FORMAT with the name |
904 |
|
of the theme as an additional argument. If not given, a |
905 |
|
generic description is used. |
906 |
|
:face-reset-string |
907 |
|
VALUE is a string used in the case a face has been forced to |
908 |
|
its value in this theme. It is passed to FORMAT with the name |
909 |
|
of the theme as an additional argument. If not given, a |
910 |
|
generic description is used. |
911 |
|
|
912 |
|
Any theme `foo' should be defined in a file called `foo-theme.el'; |
913 |
|
see `custom-make-theme-feature' for more information." |
914 |
|
(let ((feature (custom-make-theme-feature theme))) |
915 |
|
;; It is better not to use backquote in this file, |
916 |
|
;; because that makes a bootstrapping problem |
917 |
|
;; if you need to recompile all the Lisp files using interpreted code. |
918 |
|
(nconc (list 'custom-declare-theme |
919 |
|
(list 'quote theme) |
920 |
|
(list 'quote feature) |
921 |
|
doc) |
922 |
|
args))) |
923 |
|
|
924 |
|
(defun custom-declare-theme (theme feature &optional doc &rest args) |
925 |
|
"Like `deftheme', but THEME is evaluated as a normal argument. |
926 |
|
FEATURE is the feature this theme provides. This symbol is created |
927 |
|
from THEME by `custom-make-theme-feature'." |
928 |
|
(add-to-list 'custom-known-themes theme) |
929 |
|
(put theme 'theme-feature feature) |
930 |
|
(when doc |
931 |
|
(put theme 'theme-documentation doc)) |
932 |
|
(while args |
933 |
|
(let ((arg (car args))) |
934 |
|
(setq args (cdr args)) |
935 |
|
(unless (symbolp arg) |
936 |
|
(error "Junk in args %S" args)) |
937 |
|
(let ((keyword arg) |
938 |
|
(value (car args))) |
939 |
|
(unless args |
940 |
|
(error "Keyword %s is missing an argument" keyword)) |
941 |
|
(setq args (cdr args)) |
942 |
|
(cond ((eq keyword :short-description) |
943 |
|
(put theme 'theme-short-description value)) |
944 |
|
((eq keyword :immediate) |
945 |
|
(put theme 'theme-immediate value)) |
946 |
|
((eq keyword :variable-set-string) |
947 |
|
(put theme 'theme-variable-set-string value)) |
948 |
|
((eq keyword :variable-reset-string) |
949 |
|
(put theme 'theme-variable-reset-string value)) |
950 |
|
((eq keyword :face-set-string) |
951 |
|
(put theme 'theme-face-set-string value)) |
952 |
|
((eq keyword :face-reset-string) |
953 |
|
(put theme 'theme-face-reset-string value))))))) |
954 |
|
|
955 |
|
(defun custom-make-theme-feature (theme) |
956 |
|
"Given a symbol THEME, create a new symbol by appending \"-theme\". |
957 |
|
Store this symbol in the `theme-feature' property of THEME. |
958 |
|
Calling `provide-theme' to provide THEME actually puts `THEME-theme' |
959 |
|
into `features'. |
960 |
|
|
961 |
|
This allows for a file-name convention for autoloading themes: |
962 |
|
Every theme X has a property `provide-theme' whose value is \"X-theme\". |
963 |
|
\(require-theme X) then attempts to load the file `X-theme.el'." |
964 |
|
(intern (concat (symbol-name theme) "-theme"))) |
965 |
|
|
966 |
|
;;; Loading themes. |
967 |
|
|
968 |
|
;; The variable and face settings of a theme are recorded in |
969 |
|
;; the `theme-settings' property of the theme name. |
970 |
|
;; This property's value is a list of elements, each of the form |
971 |
|
;; (PROP SYMBOL THEME MODE VALUE), where PROP is `theme-value' or `theme-face' |
972 |
|
;; and SYMBOL is the face or variable name. |
973 |
|
;; THEME is the theme name itself; that's redundant, but simplifies things. |
974 |
|
;; MODE is `set' or `reset'. |
975 |
|
;; If MODE is `set', then VALUE is an expression that specifies the |
976 |
|
;; theme's setting for SYMBOL. |
977 |
|
;; If MODE is `reset', then VALUE is another theme, |
978 |
|
;; and it means to use the value from that theme. |
979 |
|
|
980 |
|
;; Each variable has a `theme-value' property that describes all the |
981 |
|
;; settings of enabled themes that apply to it. |
982 |
|
;; Each face name has a `theme-face' property that describes all the |
983 |
|
;; settings of enabled themes that apply to it. |
984 |
|
;; The property value is a list of settings, each with the form |
985 |
|
;; (THEME MODE VALUE). THEME, MODE and VALUE are as above. |
986 |
|
|
987 |
|
;; When a theme is disabled, its settings are removed from the |
988 |
|
;; `theme-value' and `theme-face' properties, but the |
989 |
|
;; theme's own `theme-settings' property remains unchanged. |
990 |
|
|
991 |
(defvar custom-loaded-themes nil |
(defvar custom-loaded-themes nil |
992 |
"Themes in the order they are loaded.") |
"Custom themes that have been loaded.") |
993 |
|
|
994 |
(defcustom custom-theme-directory |
(defcustom custom-theme-directory |
995 |
(if (eq system-type 'ms-dos) |
(if (eq system-type 'ms-dos) |
1005 |
:version "22.1") |
:version "22.1") |
1006 |
|
|
1007 |
(defun custom-theme-loaded-p (theme) |
(defun custom-theme-loaded-p (theme) |
1008 |
"Return non-nil when THEME has been loaded." |
"Return non-nil if THEME has been loaded." |
1009 |
(memq theme custom-loaded-themes)) |
(memq theme custom-loaded-themes)) |
1010 |
|
|
1011 |
|
(defvar custom-enabled-themes '(user) |
1012 |
|
"Custom themes currently enabled, highest precedence first. |
1013 |
|
The first one is always `user'.") |
1014 |
|
|
1015 |
|
(defun custom-theme-enabled-p (theme) |
1016 |
|
"Return non-nil if THEME is enabled." |
1017 |
|
(memq theme custom-enabled-themes)) |
1018 |
|
|
1019 |
(defun provide-theme (theme) |
(defun provide-theme (theme) |
1020 |
"Indicate that this file provides THEME. |
"Indicate that this file provides THEME. |
1021 |
Add THEME to `custom-loaded-themes' and `provide' whatever |
Add THEME to `custom-loaded-themes', and `provide' whatever |
1022 |
is stored in THEME's property `theme-feature'. |
feature name is stored in THEME's property `theme-feature'. |
1023 |
|
|
1024 |
Usually the theme-feature property contains a symbol created |
Usually the `theme-feature' property contains a symbol created |
1025 |
by `custom-make-theme-feature'." |
by `custom-make-theme-feature'." |
1026 |
(custom-check-theme theme) |
(custom-check-theme theme) |
1027 |
(provide (get theme 'theme-feature)) |
(provide (get theme 'theme-feature)) |
1028 |
(setq custom-loaded-themes (nconc (list theme) custom-loaded-themes))) |
(push theme custom-loaded-themes) |
1029 |
|
;; Loading a theme also installs its settings, |
1030 |
|
;; so mark it as "enabled". |
1031 |
|
(push theme custom-enabled-themes) |
1032 |
|
;; `user' must always be the highest-precedence enabled theme. |
1033 |
|
;; Make that remain true. (This has the effect of making user settings |
1034 |
|
;; override the ones just loaded, too.) |
1035 |
|
(custom-enable-theme 'user)) |
1036 |
|
|
1037 |
(defun require-theme (theme) |
(defun require-theme (theme) |
1038 |
"Try to load a theme by requiring its feature. |
"Try to load a theme's settings from its file. |
1039 |
THEME's feature is stored in THEME's `theme-feature' property. |
This also enables the theme; use `custom-disable-theme' to disable it." |
1040 |
|
|
1041 |
|
;; THEME's feature is stored in THEME's `theme-feature' property. |
1042 |
|
;; Usually the `theme-feature' property contains a symbol created |
1043 |
|
;; by `custom-make-theme-feature'. |
1044 |
|
|
|
Usually the `theme-feature' property contains a symbol created |
|
|
by `custom-make-theme-feature'." |
|
1045 |
;; Note we do no check for validity of the theme here. |
;; Note we do no check for validity of the theme here. |
1046 |
;; This allows to pull in themes by a file-name convention |
;; This allows to pull in themes by a file-name convention |
1047 |
(let ((load-path (if (file-directory-p custom-theme-directory) |
(let ((load-path (if (file-directory-p custom-theme-directory) |
1049 |
load-path))) |
load-path))) |
1050 |
(require (or (get theme 'theme-feature) |
(require (or (get theme 'theme-feature) |
1051 |
(custom-make-theme-feature theme))))) |
(custom-make-theme-feature theme))))) |
1052 |
|
|
1053 |
(defun custom-remove-theme (spec-alist theme) |
;;; How to load and enable various themes as part of `user'. |
|
"Delete all elements from SPEC-ALIST whose car is THEME." |
|
|
(let ((elt (assoc theme spec-alist))) |
|
|
(while elt |
|
|
(setq spec-alist (delete elt spec-alist) |
|
|
elt (assoc theme spec-alist)))) |
|
|
spec-alist) |
|
|
|
|
|
(defun custom-do-theme-reset (theme) |
|
|
"Undo all settings defined by THEME. |
|
|
|
|
|
A variable remains unchanged if its property `theme-value' does not |
|
|
contain a value for THEME. A face remains unchanged if its property |
|
|
`theme-face' does not contain a value for THEME. In either case, all |
|
|
settings for THEME are removed from the property and the variable or |
|
|
face is set to the `user' theme. |
|
|
|
|
|
See `custom-known-themes' for a list of known themes." |
|
|
(let (spec-list) |
|
|
(mapatoms (lambda (symbol) |
|
|
;; This works even if symbol is both a variable and a |
|
|
;; face. |
|
|
(setq spec-list (get symbol 'theme-value)) |
|
|
(when spec-list |
|
|
(put symbol 'theme-value (custom-remove-theme spec-list theme)) |
|
|
(custom-theme-reset-internal symbol 'user)) |
|
|
(setq spec-list (get symbol 'theme-face)) |
|
|
(when spec-list |
|
|
(put symbol 'theme-face (custom-remove-theme spec-list theme)) |
|
|
(custom-theme-reset-internal-face symbol 'user)))))) |
|
1054 |
|
|
1055 |
(defun custom-theme-load-themes (by-theme &rest body) |
(defun custom-theme-load-themes (by-theme &rest body) |
1056 |
"Load the themes specified by BODY. |
"Load the themes specified by BODY. |
1057 |
Record them as required by theme BY-THEME. BODY is a sequence of either |
Record them as required by theme BY-THEME. |
1058 |
|
|
1059 |
|
BODY is a sequence of either |
1060 |
|
|
1061 |
THEME |
THEME |
1062 |
BY-THEME requires THEME |
Load THEME and enable it. |
1063 |
\(reset THEME) |
\(reset THEME) |
1064 |
Undo all the settings made by THEME |
Undo all the settings made by THEME |
1065 |
\(hidden THEME) |
\(hidden THEME) |
1066 |
Require THEME but hide it from the user |
Load THEME but do not enable it. |
1067 |
|
|
1068 |
All the themes loaded for BY-THEME are recorded in BY-THEME's property |
All the themes loaded for BY-THEME are recorded in BY-THEME's property |
1069 |
`theme-loads-themes'. Any theme loaded with the hidden predicate will |
`theme-loads-themes'." |
|
be given the property `theme-hidden' unless it has been loaded before. |
|
|
Whether a theme has been loaded before is determined by the function |
|
|
`custom-theme-loaded-p'." |
|
1070 |
(custom-check-theme by-theme) |
(custom-check-theme by-theme) |
1071 |
(let ((theme) |
(let ((themes-loaded (get by-theme 'theme-loads-themes))) |
1072 |
(themes-loaded (get by-theme 'theme-loads-themes))) |
(dolist (theme body) |
|
(while theme |
|
|
(setq theme (car body) |
|
|
body (cdr body)) |
|
1073 |
(cond ((and (consp theme) (eq (car theme) 'reset)) |
(cond ((and (consp theme) (eq (car theme) 'reset)) |
1074 |
(custom-do-theme-reset (cadr theme))) |
(custom-disable-theme (cadr theme))) |
1075 |
((and (consp theme) (eq (car theme) 'hidden)) |
((and (consp theme) (eq (car theme) 'hidden)) |
1076 |
(require-theme (cadr theme)) |
(require-theme (cadr theme)) |
1077 |
(unless (custom-theme-loaded-p (cadr theme)) |
(custom-disable-theme (cadr theme))) |
|
(put (cadr theme) 'theme-hidden t))) |
|
1078 |
(t |
(t |
1079 |
(require-theme theme) |
(require-theme theme))) |
1080 |
(put theme 'theme-hidden nil))) |
(push theme themes-loaded)) |
|
(setq themes-loaded (nconc (list theme) themes-loaded))) |
|
1081 |
(put by-theme 'theme-loads-themes themes-loaded))) |
(put by-theme 'theme-loads-themes themes-loaded))) |
1082 |
|
|
1083 |
(defun custom-load-themes (&rest body) |
(defun custom-load-themes (&rest body) |
1085 |
|
|
1086 |
See `custom-theme-load-themes' for more information on BODY." |
See `custom-theme-load-themes' for more information on BODY." |
1087 |
(apply 'custom-theme-load-themes 'user body)) |
(apply 'custom-theme-load-themes 'user body)) |
1088 |
|
|
1089 |
|
;;; Enabling and disabling loaded themes. |
1090 |
|
|
1091 |
|
(defun custom-enable-theme (theme) |
1092 |
|
"Reenable all variable and face settings defined by THEME. |
1093 |
|
The newly enabled theme gets the highest precedence (after `user'). |
1094 |
|
If it is already enabled, just give it highest precedence (after `user')." |
1095 |
|
(let ((settings (get theme 'theme-settings))) |
1096 |
|
(dolist (s settings) |
1097 |
|
(let* ((prop (car s)) |
1098 |
|
(symbol (cadr s)) |
1099 |
|
(spec-list (get symbol prop))) |
1100 |
|
(put symbol prop (cons (cddr s) (assq-delete-all theme spec-list))) |
1101 |
|
(if (eq prop 'theme-value) |
1102 |
|
(custom-theme-recalc-variable symbol) |
1103 |
|
(custom-theme-recalc-face symbol))))) |
1104 |
|
(push theme custom-enabled-themes) |
1105 |
|
;; `user' must always be the highest-precedence enabled theme. |
1106 |
|
(unless (eq theme 'user) |
1107 |
|
(custom-enable-theme 'user))) |
1108 |
|
|
1109 |
|
(defun custom-disable-theme (theme) |
1110 |
|
"Disable all variable and face settings defined by THEME. |
1111 |
|
See `custom-known-themes' for a list of known themes." |
1112 |
|
(let ((settings (get theme 'theme-settings))) |
1113 |
|
(dolist (s settings) |
1114 |
|
(let* ((prop (car s)) |
1115 |
|
(symbol (cadr s)) |
1116 |
|
(spec-list (get symbol prop))) |
1117 |
|
(put symbol 'theme-value (assq-delete-all theme spec-list)) |
1118 |
|
(if (eq prop 'theme-value) |
1119 |
|
(custom-theme-recalc-variable symbol) |
1120 |
|
(custom-theme-recalc-face symbol))))) |
1121 |
|
(setq custom-enabled-themes |
1122 |
|
(delq theme custom-enabled-themes))) |
1123 |
|
|
1124 |
|
(defun custom-theme-value (theme setting-list) |
1125 |
|
"Determine the value specified for THEME according to SETTING-LIST. |
1126 |
|
Returns a list whose car is the specified value, if we |
1127 |
|
find one; nil otherwise. |
1128 |
|
|
1129 |
; (defsubst copy-upto-last (elt list) |
SETTING-LIST is an alist with themes as its key. |
1130 |
; "Copy all the elements of the list upto the last occurence of elt" |
Each element has the form: |
|
; ;; Is it faster to do more work in C than to do less in elisp? |
|
|
; (nreverse (cdr (member elt (reverse list))))) |
|
|
|
|
|
(defun custom-theme-value (theme theme-spec-list) |
|
|
"Determine the value for THEME defined by THEME-SPEC-LIST. |
|
|
Returns a list with the original value if found; nil otherwise. |
|
|
|
|
|
THEME-SPEC-LIST is an alist with themes as its key. As new themes are |
|
|
installed, these are added to the front of THEME-SPEC-LIST. |
|
|
Each element has the form |
|
1131 |
|
|
1132 |
\(THEME MODE VALUE) |
\(THEME MODE VALUE) |
1133 |
|
|
1134 |
MODE is either the symbol `set' or the symbol `reset'. See |
MODE is either the symbol `set' or the symbol `reset'. See |
1135 |
`custom-push-theme' for more information on the format of |
`custom-push-theme' for more information on the format of |
1136 |
THEME-SPEC-LIST." |
SETTING-LIST." |
1137 |
;; Note we do _NOT_ signal an error if the theme is unknown |
;; Note we do _NOT_ signal an error if the theme is unknown |
1138 |
;; it might have gone away without the user knowing. |
;; it might have gone away without the user knowing. |
1139 |
(let ((value (cdr (assoc theme theme-spec-list)))) |
(let ((elt (cdr (assoc theme setting-list)))) |
1140 |
(if value |
(if elt |
1141 |
(if (eq (car value) 'set) |
(if (eq (car elt) 'set) |
1142 |
(cdr value) |
(cdr elt) |
1143 |
(custom-theme-value (cadr value) theme-spec-list))))) |
;; `reset' means refer to another theme's value in the same alist. |
1144 |
|
(custom-theme-value (cadr elt) setting-list))))) |
1145 |
(defun custom-theme-variable-value (variable theme) |
|
1146 |
"Return (list value) indicating value of VARIABLE in THEME. |
(defun custom-variable-theme-value (variable) |
1147 |
If THEME does not define a value for VARIABLE, return nil. The value |
"Return (list VALUE) indicating the custom theme value of VARIABLE. |
1148 |
definitions per theme are stored in VARIABLE's property `theme-value'. |
That is to say, it specifies what the value should be according to |
1149 |
The actual work is done by function `custom-theme-value', which see. |
currently enabled custom themes. |
1150 |
See `custom-push-theme' for more information on how these definitions |
|
1151 |
are stored." |
This function returns nil if no custom theme specifies a value for VARIABLE." |
1152 |
(custom-theme-value theme (get variable 'theme-value))) |
(let* ((theme-value (get variable 'theme-value))) |
1153 |
|
(if theme-value |
1154 |
(defun custom-theme-reset-internal (symbol to-theme) |
(custom-theme-value (car (car theme-value)) theme-value)))) |
1155 |
"Reset SYMBOL to the value defined by TO-THEME. |
|
1156 |
If SYMBOL is not defined in TO-THEME, reset SYMBOL to the standard |
(defun custom-face-theme-value (face) |
1157 |
value. See `custom-theme-variable-value'. The standard value is |
"Return the face spec of FACE according to currently enabled custom themes. |
1158 |
stored in SYMBOL's property `standard-value'." |
This function returns nil if no custom theme specifies anything for FACE." |
1159 |
(let ((value (custom-theme-variable-value symbol to-theme)) |
(let* ((theme-value (get face 'theme-face))) |
1160 |
was-in-theme) |
(if theme-value |
1161 |
(setq was-in-theme value) |
(custom-theme-value (car (car theme-value)) theme-value)))) |
1162 |
(setq value (or value (get symbol 'standard-value))) |
|
1163 |
(when value |
(defun custom-theme-recalc-variable (variable) |
1164 |
(put symbol 'saved-value was-in-theme) |
"Set VARIABLE according to currently enabled custom themes." |
1165 |
(if (or (get 'force-value symbol) (default-boundp symbol)) |
(let ((valspec (custom-variable-theme-value variable))) |
1166 |
(funcall (or (get symbol 'custom-set) 'set-default) symbol |
(when valspec |
1167 |
(eval (car value))))) |
(put variable 'saved-value valspec)) |
1168 |
value)) |
(unless valspec |
1169 |
|
(setq valspec (get variable 'standard-value))) |
1170 |
|
(when valspec |
1171 |
|
(if (or (get 'force-value variable) (default-boundp variable)) |
1172 |
|
(funcall (or (get variable 'custom-set) 'set-default) variable |
1173 |
|
(eval (car valspec))))))) |
1174 |
|
|
1175 |
|
(defun custom-theme-recalc-face (face) |
1176 |
|
"Set FACE according to currently enabled custom themes." |
1177 |
|
(let ((spec (custom-face-theme-value face))) |
1178 |
|
(when spec |
1179 |
|
(put face 'save-face spec)) |
1180 |
|
(unless spec |
1181 |
|
(setq spec (get face 'face-defface-spec))) |
1182 |
|
(when spec |
1183 |
|
(when (or (get face 'force-face) (facep face)) |
1184 |
|
(unless (facep face) |
1185 |
|
(make-empty-face face)) |
1186 |
|
(face-spec-set face spec))))) |
1187 |
|
|
1188 |
(defun custom-theme-reset-variables (theme &rest args) |
(defun custom-theme-reset-variables (theme &rest args) |
1189 |
"Reset the value of the variables to values previously defined. |
"Reset the specs in THEME of some variables to their values in other themes. |
1190 |
Associate this setting with THEME. |
Each of the arguments ARGS has this form: |
|
|
|
|
ARGS is a list of lists of the form |
|
1191 |
|
|
1192 |
(VARIABLE TO-THEME) |
(VARIABLE FROM-THEME) |
1193 |
|
|
1194 |
This means reset VARIABLE to its value in TO-THEME." |
This means reset VARIABLE to its value in FROM-THEME." |
1195 |
(custom-check-theme theme) |
(custom-check-theme theme) |
1196 |
(mapcar '(lambda (arg) |
(dolist (arg args) |
1197 |
(apply 'custom-theme-reset-internal arg) |
(custom-push-theme 'theme-value (car arg) theme 'reset (cadr arg)))) |
|
(custom-push-theme 'theme-value (car arg) theme 'reset (cadr arg))) |
|
|
args)) |
|
1198 |
|
|
1199 |
(defun custom-reset-variables (&rest args) |
(defun custom-reset-variables (&rest args) |
1200 |
"Reset the value of the variables to values previously saved. |
"Reset the specs of some variables to their values in certain themes. |
1201 |
This is the setting associated the `user' theme. |
This creates settings in the `user' theme. |
1202 |
|
|
1203 |
ARGS is a list of lists of the form |
Each of the arguments ARGS has this form: |
1204 |
|
|
1205 |
(VARIABLE TO-THEME) |
(VARIABLE FROM-THEME) |
1206 |
|
|
1207 |
This means reset VARIABLE to its value in TO-THEME." |
This means reset VARIABLE to its value in FROM-THEME." |
1208 |
(apply 'custom-theme-reset-variables 'user args)) |
(apply 'custom-theme-reset-variables 'user args)) |
1209 |
|
|
1210 |
;;; The End. |
;;; The End. |