+ (widget-setup)
+ (goto-char (point-min))
+ (message ""))
+
+;;; Theme variables
+
+(defun custom-theme-add-variable (symbol)
+ (interactive "vVariable name: ")
+ (cond ((assq symbol custom-theme-variables)
+ (message "%s is already in the theme" (symbol-name symbol)))
+ ((not (boundp symbol))
+ (message "%s is not defined as a variable" (symbol-name symbol)))
+ ((eq symbol 'custom-enabled-themes)
+ (message "Custom theme cannot contain `custom-enabled-themes'"))
+ (t
+ (save-excursion
+ (goto-char custom-theme-insert-variable-marker)
+ (widget-insert "\n")
+ (let ((widget (widget-create 'custom-variable
+ :tag (custom-unlispify-tag-name symbol)
+ :custom-level 0
+ :action 'custom-theme-variable-action
+ :custom-state 'unknown
+ :value symbol)))
+ (push (cons symbol widget) custom-theme-variables)
+ (custom-magic-reset widget))
+ (widget-setup)))))
+
+(defvar custom-theme-variable-menu
+ `(("Reset to Current" custom-redraw
+ (lambda (widget)
+ (and (boundp (widget-value widget))
+ (memq (widget-get widget :custom-state)
+ '(themed modified changed)))))
+ ("Reset to Theme Value" custom-variable-reset-theme
+ (lambda (widget)
+ (let ((theme (intern (widget-value custom-theme-name)))
+ (symbol (widget-value widget))
+ found)
+ (and (custom-theme-p theme)
+ (dolist (setting (get theme 'theme-settings) found)
+ (if (and (eq (cadr setting) symbol)
+ (eq (car setting) 'theme-value))
+ (setq found t)))))))
+ ("---" ignore ignore)
+ ("Delete" custom-theme-delete-variable nil))
+ "Alist of actions for the `custom-variable' widget in Custom Theme Mode.
+See the documentation for `custom-variable'.")
+
+(defun custom-theme-variable-action (widget &optional event)
+ "Show the Custom Theme Mode menu for a `custom-variable' widget.
+Optional EVENT is the location for the menu."
+ (let ((custom-variable-menu custom-theme-variable-menu))
+ (custom-variable-action widget event)))
+
+(defun custom-variable-reset-theme (widget)
+ "Reset WIDGET to its value for the currently edited theme."
+ (let ((theme (intern (widget-value custom-theme-name)))
+ (symbol (widget-value widget))
+ found)
+ (dolist (setting (get theme 'theme-settings))
+ (if (and (eq (cadr setting) symbol)
+ (eq (car setting) 'theme-value))
+ (setq found setting)))
+ (widget-value-set (car (widget-get widget :children))
+ (nth 3 found)))
+ (widget-put widget :custom-state 'themed)
+ (custom-redraw-magic widget)
+ (widget-setup))
+
+(defun custom-theme-delete-variable (widget)
+ (setq custom-theme-variables
+ (assq-delete-all (widget-value widget) custom-theme-variables))
+ (widget-delete widget))
+
+;;; Theme faces
+
+(defun custom-theme-add-face (symbol)
+ (interactive (list (read-face-name "Face name" nil nil)))
+ (cond ((assq symbol custom-theme-faces)
+ (message "%s is already in the theme" (symbol-name symbol)))
+ ((not (facep symbol))
+ (message "%s is not defined as a face" (symbol-name symbol)))
+ (t
+ (save-excursion
+ (goto-char custom-theme-insert-face-marker)
+ (widget-insert "\n")
+ (let ((widget (widget-create 'custom-face
+ :tag (custom-unlispify-tag-name symbol)
+ :custom-level 0
+ :action 'custom-theme-face-action
+ :custom-state 'unknown
+ :value symbol)))
+ (push (cons symbol widget) custom-theme-faces)
+ (custom-magic-reset widget)
+ (widget-setup))))))
+
+(defvar custom-theme-face-menu
+ `(("Reset to Theme Value" custom-face-reset-theme
+ (lambda (widget)
+ (let ((theme (intern (widget-value custom-theme-name)))
+ (symbol (widget-value widget))
+ found)
+ (and (custom-theme-p theme)
+ (dolist (setting (get theme 'theme-settings) found)
+ (if (and (eq (cadr setting) symbol)
+ (eq (car setting) 'theme-face))
+ (setq found t)))))))
+ ("---" ignore ignore)
+ ("Delete" custom-theme-delete-face nil))
+ "Alist of actions for the `custom-variable' widget in Custom Theme Mode.
+See the documentation for `custom-variable'.")
+
+(defun custom-theme-face-action (widget &optional event)
+ "Show the Custom Theme Mode menu for a `custom-face' widget.
+Optional EVENT is the location for the menu."
+ (let ((custom-face-menu custom-theme-face-menu))
+ (custom-face-action widget event)))
+
+(defun custom-face-reset-theme (widget)
+ "Reset WIDGET to its value for the currently edited theme."
+ (let ((theme (intern (widget-value custom-theme-name)))
+ (symbol (widget-value widget))
+ found)
+ (dolist (setting (get theme 'theme-settings))
+ (if (and (eq (cadr setting) symbol)
+ (eq (car setting) 'theme-face))
+ (setq found setting)))
+ (widget-value-set (car (widget-get widget :children))
+ (nth 3 found)))
+ (widget-put widget :custom-state 'themed)
+ (custom-redraw-magic widget)