changeset 67962:48d2cc2834b4

* custom.el (provide-theme): Ban `user' theme name. (custom-enabling-themes): New variable. (enable-theme): Don't enable user if custom-enabling-themes is t. (custom-enabled-themes): Make it a defcustom. (custom-theme-recalc-face): No-op if face is undefined.
author Chong Yidong <cyd@stupidchicken.com>
date Sat, 31 Dec 2005 20:49:22 +0000
parents 52f526ce11f6
children 5261f735431a
files lisp/ChangeLog lisp/custom.el
diffstat 2 files changed, 55 insertions(+), 25 deletions(-) [+]
line wrap: on
line diff
--- a/lisp/ChangeLog	Sat Dec 31 16:26:01 2005 +0000
+++ b/lisp/ChangeLog	Sat Dec 31 20:49:22 2005 +0000
@@ -1,5 +1,11 @@
 2005-12-31  Chong Yidong  <cyd@stupidchicken.com>
 
+	* custom.el (provide-theme): Ban `user' theme name.
+	(custom-enabling-themes): New variable.
+	(enable-theme): Don't enable user if custom-enabling-themes is t.
+	(custom-enabled-themes): Make it a defcustom.
+	(custom-theme-recalc-face): No-op if face is undefined.
+
 	* cus-edit.el (custom-button-mouse): New variable.
 	(custom-button-mouse): New face.
 	(custom-raised-buttons, custom-mode): Use it.
--- a/lisp/custom.el	Sat Dec 31 16:26:01 2005 +0000
+++ b/lisp/custom.el	Sat Dec 31 20:49:22 2005 +0000
@@ -648,8 +648,7 @@
 list would contain an entry for the `user' theme, too.
 
 See `custom-known-themes' for a list of known themes."
-  (unless (or (eq prop 'theme-value)
-	      (eq prop 'theme-face))
+  (unless (memq prop '(theme-value theme-face))
     (error "Unknown theme property"))
   (let* ((old (get symbol prop))
 	 (setting (assq theme old))
@@ -1048,14 +1047,6 @@
   "Return non-nil if THEME has been loaded."
   (memq theme custom-loaded-themes))
 
-(defvar custom-enabled-themes '(user)
-  "Custom themes currently enabled, highest precedence first.
-The first one is always `user'.")
-
-(defun custom-theme-enabled-p (theme)
-  "Return non-nil if THEME is enabled."
-  (memq theme custom-enabled-themes))
-
 (defun provide-theme (theme)
   "Indicate that this file provides THEME, and mark it as enabled.
 Add THEME to `custom-loaded-themes' and `custom-enabled-themes',
@@ -1063,6 +1054,8 @@
 
 Usually the `theme-feature' property contains a symbol created
 by `custom-make-theme-feature'."
+  (if (eq theme 'user)
+      (error "Custom theme cannot be named `user'"))
   (custom-check-theme theme)
   (provide (get theme 'theme-feature))
   (push theme custom-loaded-themes)
@@ -1123,6 +1116,8 @@
 
 ;;; Enabling and disabling loaded themes.
 
+(defvar custom-enabling-themes nil)
+
 (defun enable-theme (theme)
   "Reenable all variable and face settings defined by THEME.
 The newly enabled theme gets the highest precedence (after `user').
@@ -1131,9 +1126,9 @@
 This signals an error if THEME does not specify any theme
 settings.  Theme settings are set using `load-theme'."
   (interactive "SEnable Custom theme: ")
+  (unless (or (eq theme 'user) (memq theme custom-loaded-themes))
+    (error "Theme %s not defined" (symbol-name theme)))
   (let ((settings (get theme 'theme-settings)))
-    (unless (or (eq theme 'user) (memq theme custom-loaded-themes))
-      (error "Theme %s not defined" (symbol-name theme)))
     (dolist (s settings)
       (let* ((prop (car s))
 	     (symbol (cadr s))
@@ -1141,17 +1136,45 @@
 	(put symbol prop (cons (cddr s) (assq-delete-all theme spec-list)))
 	(if (eq prop 'theme-value)
 	    (custom-theme-recalc-variable symbol)
-	  (if (facep symbol)
-	      (custom-theme-recalc-face symbol))))))
-  (setq custom-enabled-themes
-        (cons theme (delq theme custom-enabled-themes)))
-  ;; `user' must always be the highest-precedence enabled theme.
+	  (custom-theme-recalc-face symbol)))))
   (unless (eq theme 'user)
-    (enable-theme 'user)))
+    (setq custom-enabled-themes
+	  (cons theme (delq theme custom-enabled-themes)))
+    (unless custom-enabling-themes
+      (enable-theme 'user))))
+
+(defcustom custom-enabled-themes nil
+  "List of enabled Custom Themes, highest precedence first.
+
+This does not include the `user' theme, which is set by Customize,
+and always takes precedence over other Custom Themes."
+  :group 'customize
+  :type  '(repeat symbol)
+  :set (lambda (symbol themes)
+	 ;; Avoid an infinite loop when custom-enabled-themes is
+	 ;; defined in a theme (e.g. `user').  Enabling the theme sets
+	 ;; custom-enabled-themes, which enables the theme...
+	 (unless custom-enabling-themes
+	   (let ((custom-enabling-themes t))
+	     (setq themes (delq 'user (delete-dups themes)))
+	     (if (boundp symbol)
+		 (dolist (theme (symbol-value symbol))
+		   (if (not (memq theme themes))
+		       (disable-theme theme))))
+	     (dolist (theme (reverse themes))
+	       (if (or (custom-theme-loaded-p theme) (eq theme 'user))
+		   (enable-theme theme)
+		 (load-theme theme)))
+	     (enable-theme 'user)
+	     (custom-set-default symbol themes)))))
+
+(defun custom-theme-enabled-p (theme)
+  "Return non-nil if THEME is enabled."
+  (memq theme custom-enabled-themes))
 
 (defun disable-theme (theme)
   "Disable all variable and face settings defined by THEME.
-See `custom-enabled-themes' for a list of known themes."
+See `custom-enabled-themes' for a list of enabled themes."
   (interactive "SDisable Custom theme: ")
   (when (memq theme custom-enabled-themes)
     (let ((settings (get theme 'theme-settings)))
@@ -1162,9 +1185,9 @@
 	  (put symbol prop (assq-delete-all theme spec-list))
 	  (if (eq prop 'theme-value)
 	      (custom-theme-recalc-variable symbol)
-	    (custom-theme-recalc-face symbol))))))
-  (setq custom-enabled-themes
-	(delq theme custom-enabled-themes)))
+	    (custom-theme-recalc-face symbol)))))
+    (setq custom-enabled-themes
+	  (delq theme custom-enabled-themes))))
 
 (defun custom-theme-value (theme setting-list)
   "Determine the value specified for THEME according to SETTING-LIST.
@@ -1212,9 +1235,10 @@
 
 (defun custom-theme-recalc-face (face)
   "Set FACE according to currently enabled custom themes."
-  (let ((theme-faces (reverse (get face 'theme-face))))
-    (dolist (spec theme-faces)
-      (face-spec-set face (car (cddr spec))))))
+  (if (facep face)
+      (let ((theme-faces (reverse (get face 'theme-face))))
+	(dolist (spec theme-faces)
+	  (face-spec-set face (car (cddr spec)))))))
 
 (defun custom-theme-reset-variables (theme &rest args)
   "Reset the specs in THEME of some variables to their values in other themes.