changeset 111017:9506df1b7b65

Allow hiding of modified custom widgets. * cus-edit.el (custom-variable, custom-face): Combine the :inhibit-magic and :display-style properties into a single :custom-style property. (custom-toggle-hide-variable, custom-toggle-hide-face): New functions. If hiding an edited value, save it to :shown-value. (custom-variable-value-create, custom-face-value-create): Use them. (custom-magic-reset): Allow magic property to be unset. * cus-theme.el (custom-theme-add-var-1) (custom-theme-add-face-1): Use the :custom-style property. * custom.el: (custom-theme-load-path): Doc fix.
author Chong Yidong <cyd@stupidchicken.com>
date Sat, 16 Oct 2010 16:36:20 -0400
parents fedd4f6fa7e5
children de901820e0bc
files lisp/ChangeLog lisp/cus-edit.el lisp/cus-theme.el lisp/custom.el
diffstat 4 files changed, 85 insertions(+), 26 deletions(-) [+]
line wrap: on
line diff
--- a/lisp/ChangeLog	Sat Oct 16 14:27:08 2010 -0400
+++ b/lisp/ChangeLog	Sat Oct 16 16:36:20 2010 -0400
@@ -1,5 +1,14 @@
 2010-10-16  Chong Yidong  <cyd@stupidchicken.com>
 
+	* cus-edit.el (custom-variable, custom-face): Combine the
+	:inhibit-magic and :display-style properties into a single
+	:custom-style property.
+	(custom-toggle-hide-variable, custom-toggle-hide-face): New
+	functions.  If hiding an edited value, save it to :shown-value.
+	(custom-variable-value-create, custom-face-value-create): Use
+	them.
+	(custom-magic-reset): Allow magic property to be unset.
+
 	* custom.el: Custom themes no longer use load-path.
 	(custom-theme-load-path): New option.  Change built-in theme
 	directory to etc/.
@@ -9,6 +18,8 @@
 
 	* cus-theme.el (describe-theme-1): Use custom-theme--load-path.
 	(customize-themes): Link to custom-theme-load-path variable.
+	(custom-theme-add-var-1, custom-theme-add-face-1): Use the
+	:custom-style property.
 
 	* themes/*.el: Moved to etc/.
 
--- a/lisp/cus-edit.el	Sat Oct 16 14:27:08 2010 -0400
+++ b/lisp/cus-edit.el	Sat Oct 16 16:36:20 2010 -0400
@@ -2077,7 +2077,8 @@
 (defun custom-magic-reset (widget)
   "Redraw the :custom-magic property of WIDGET."
   (let ((magic (widget-get widget :custom-magic)))
-    (widget-value-set magic (widget-value magic))))
+    (when magic
+      (widget-value-set magic (widget-value magic)))))
 
 ;;; The `custom' Widget.
 
@@ -2465,8 +2466,9 @@
 :shown-value, if non-nil, should be a list whose `car' is the
   variable value to display in place of the current value.
 
-:inhibit-magic, if non-nil, inhibits creating the magic
-  custom-state widget."
+:custom-style describes the widget interface style; nil is the
+  default style, while `simple' means a simpler interface that
+  inhibits the magic custom-state widget."
   :format "%v"
   :help-echo "Set or reset this variable."
   :documentation-property #'custom-variable-documentation
@@ -2552,7 +2554,7 @@
 		  :on "Hide"
 		  :off-image "right"
 		  :off "Show Value"
-		  :action 'custom-toggle-parent
+		  :action 'custom-toggle-hide-variable
 		  nil)
 		 buttons)
 	   (insert " ")
@@ -2572,7 +2574,7 @@
 		  :off "Show"
 		  :on-image "down"
 		  :off-image "right"
-		  :action 'custom-toggle-parent
+		  :action 'custom-toggle-hide-variable
 		  t)
 		 buttons)
 	   (insert " ")
@@ -2602,7 +2604,7 @@
 		  :off "Show"
 		  :on-image "down"
 		  :off-image "right"
-		  :action 'custom-toggle-parent
+		  :action 'custom-toggle-hide-variable
 		  t)
 		 buttons)
 	   (insert " ")
@@ -2631,7 +2633,7 @@
       (unless (eq (preceding-char) ?\n)
 	(widget-insert "\n"))
       ;; Create the magic button.
-      (unless (widget-get widget :inhibit-magic)
+      (unless (eq (widget-get widget :custom-style) 'simple)
 	(let ((magic (widget-create-child-and-convert
 		      widget 'custom-magic nil)))
 	  (widget-put widget :custom-magic magic)
@@ -2667,6 +2669,31 @@
 	  (custom-add-parent-links widget))
 	(custom-add-see-also widget)))))
 
+(defun custom-toggle-hide-variable (visibility-widget &rest ignore)
+  "Toggle the visibility of a `custom-variable' parent widget.
+By default, this signals an error if the parent has unsaved
+changes.  If the parent has a `simple' :custom-style property,
+the present value is saved to its :shown-value property instead."
+  (let ((widget (widget-get visibility-widget :parent)))
+    (unless (eq (widget-type widget) 'custom-variable)
+      (error "Invalid widget type"))
+    (custom-load-widget widget)
+    (let ((state (widget-get widget :custom-state)))
+      (if (eq state 'hidden)
+	  (widget-put widget :custom-state 'unknown)
+	;; In normal interface, widget can't be hidden if modified.
+	(when (memq state '(invalid modified set))
+	  (if (eq (widget-get widget :custom-style) 'simple)
+	      (widget-put widget :shown-value
+			  (list (widget-value
+				 (car-safe
+				  (widget-get widget :children)))))
+	    (error "There are unsaved changes")))
+	(widget-put widget :documentation-shown nil)
+	(widget-put widget :custom-state 'hidden))
+      (custom-redraw widget)
+      (widget-setup))))
+
 (defun custom-tag-action (widget &rest args)
   "Pass :action to first child of WIDGET's parent."
   (apply 'widget-apply (car (widget-get (widget-get widget :parent) :children))
@@ -3291,17 +3318,15 @@
   Lisp sexp), or `mismatch' (should not happen); if nil, use
   the return value of `custom-face-default-form'.
 
-:display-style, if non-nil, describes the style of display to
-  use.  If the value is `concise', a neater interface is shown.
+:custom-style describes the widget interface style; nil is the
+  default style, while `simple' means a simpler interface that
+  inhibits the magic custom-state widget.
 
 :sample-indent, if non-nil, is the number of columns to which to
   indent the face sample (an integer).
 
 :shown-value, if non-nil, is the face spec to display as the value
-  of the widget, instead of the current face spec.
-
-:inhibit-magic, if non-nil, inhibits creating the magic
-  custom-state widget."
+  of the widget, instead of the current face spec."
   :sample-face 'custom-face-tag
   :help-echo "Set or reset this face."
   :documentation-property #'face-doc-string
@@ -3395,6 +3420,29 @@
 	(setq spec `((t ,(face-attr-construct face (selected-frame))))))
     (custom-pre-filter-face-spec spec)))
 
+(defun custom-toggle-hide-face (visibility-widget &rest ignore)
+  "Toggle the visibility of a `custom-face' parent widget.
+By default, this signals an error if the parent has unsaved
+changes.  If the parent has a `simple' :custom-style property,
+the present value is saved to its :shown-value property instead."
+  (let ((widget (widget-get visibility-widget :parent)))
+    (unless (eq (widget-type widget) 'custom-face)
+      (error "Invalid widget type"))
+    (custom-load-widget widget)
+    (let ((state (widget-get widget :custom-state)))
+      (if (eq state 'hidden)
+	  (widget-put widget :custom-state 'unknown)
+	;; In normal interface, widget can't be hidden if modified.
+	(when (memq state '(invalid modified set))
+	  (if (eq (widget-get widget :custom-style) 'simple)
+	      (widget-put widget :shown-value
+			  (custom-face-widget-to-spec widget))
+	    (error "There are unsaved changes")))
+	(widget-put widget :documentation-shown nil)
+	(widget-put widget :custom-state 'hidden))
+      (custom-redraw widget)
+      (widget-setup))))
+
 (defun custom-face-value-create (widget)
   "Create a list of the display specifications for WIDGET."
   (let* ((buttons (widget-get widget :buttons))
@@ -3402,7 +3450,7 @@
 	 (tag (or (widget-get widget :tag)
 		  (prin1-to-string symbol)))
 	 (hiddenp (eq (widget-get widget :custom-state) 'hidden))
-	 (style   (widget-get widget :display-style))
+	 (style   (widget-get widget :custom-style))
 	 children)
 
     (if (eq custom-buffer-style 'tree)
@@ -3425,7 +3473,7 @@
 	       :help-echo "Hide or show this face."
 	       :on "Hide" :off "Show"
 	       :on-image "down" :off-image "right"
-	       :action 'custom-toggle-parent
+	       :action 'custom-toggle-hide-face
 	       (not hiddenp))
 	      buttons)
 	;; Face name (tag).
@@ -3452,7 +3500,7 @@
       (insert "\n")
 
       ;; Magic.
-      (unless (widget-get widget :inhibit-magic)
+      (unless (eq (widget-get widget :custom-style) 'simple)
 	(let ((magic (widget-create-child-and-convert
 		      widget 'custom-magic nil)))
 	  (widget-put widget :custom-magic magic)
@@ -3462,7 +3510,7 @@
       (widget-put widget :buttons buttons)
 
       ;; Insert documentation.
-      (unless (and hiddenp (eq style 'concise))
+      (unless (and hiddenp (eq style 'simple))
 	(widget-put widget :documentation-indent 3)
 	(widget-add-documentation-string-button
 	 widget :visibility-widget 'custom-visibility)
--- a/lisp/cus-theme.el	Sat Oct 16 14:27:08 2010 -0400
+++ b/lisp/cus-theme.el	Sat Oct 16 16:36:20 2010 -0400
@@ -41,7 +41,7 @@
     map)
   "Keymap for `custom-new-theme-mode'.")
 
-(define-derived-mode custom-new-theme-mode nil "Cus-Theme"
+(define-derived-mode custom-new-theme-mode nil "Custom-Theme"
   "Major mode for editing Custom themes.
 Do not call this mode function yourself.  It is meant for internal use."
   (use-local-map custom-new-theme-mode-map)
@@ -214,7 +214,7 @@
 			     :notify 'ignore
 			     :custom-level 0
 			     :custom-state 'hidden
-			     :inhibit-magic t))
+			     :custom-style 'simple))
 	custom-theme-variables)
   (widget-insert " "))
 
@@ -250,9 +250,8 @@
 			     :documentation-shown t
 			     :value symbol
 			     :custom-state 'hidden
-			     :display-style 'concise
+			     :custom-style 'simple
 			     :shown-value spec
-			     :inhibit-magic t
 			     :sample-indent 34))
 	custom-theme-faces)
   (widget-insert " "))
@@ -476,7 +475,7 @@
     map)
   "Keymap for `custom-theme-choose-mode'.")
 
-(define-derived-mode custom-theme-choose-mode nil "Cus-Theme"
+(define-derived-mode custom-theme-choose-mode nil "Themes"
   "Major mode for selecting Custom themes.
 Do not call this mode function yourself.  It is meant for internal use."
   (use-local-map custom-theme-choose-mode-map)
--- a/lisp/custom.el	Sat Oct 16 14:27:08 2010 -0400
+++ b/lisp/custom.el	Sat Oct 16 16:36:20 2010 -0400
@@ -1066,10 +1066,11 @@
 Emacs commands for loading custom themes (e.g. `customize-themes'
 and `load-theme') search for custom theme files in the specified
 order.  Each element in the list should be one of the following:
-\(i) the symbol `custom-theme-directory', which means the value
-of that variable; (ii) the symbol t (the built-in Emacs theme
-directory, named \"themes\" in `data-directory'); or \(iii) a
-directory name (a string)."
+- the symbol `custom-theme-directory', meaning the value of
+  `custom-theme-directory'.
+- the symbol t, meaning the built-in theme directory (a directory
+  named \"themes\" in `data-directory').
+- a directory name (a string)."
   :type '(repeat (choice (const :tag "custom-theme-directory"
 				custom-theme-directory)
 			 (const :tag "Built-in theme directory" t)