aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChong Yidong2010-10-07 20:05:12 -0400
committerChong Yidong2010-10-07 20:05:12 -0400
commit61328d7c4c315ddb46483b48b66847b79c4364f7 (patch)
tree9774d8c4d1594c1cba5b9d86c0f8001df6b9b2d8
parent3d319c8f92f639940b35c750697e82d22b7c17ba (diff)
downloademacs-61328d7c4c315ddb46483b48b66847b79c4364f7.tar.gz
emacs-61328d7c4c315ddb46483b48b66847b79c4364f7.zip
Improvements to face customization interface.
* lisp/cus-edit.el (custom-variable, custom-face): Doc fix. (custom-face-edit): Add value-create attribute. (custom-face-edit-value-create) (custom-face-edit-value-visibility-action): New functions. Hide unused face attributes by default, and add a visibility toggle. (custom-face-edit-deactivate): Show empty values with shadow face. (custom-face-selected): Only use this for face specs with default attributes. (custom-face-value-create): Cleanup. * lisp/wid-edit.el (widget-checklist-value-create): Use dolist. (widget-checklist-match-find): Make second arg optional.
-rw-r--r--lisp/ChangeLog15
-rw-r--r--lisp/cus-edit.el339
-rw-r--r--lisp/wid-edit.el21
3 files changed, 212 insertions, 163 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 56a7f42408a..4c3d419d0aa 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,18 @@
12010-10-07 Chong Yidong <cyd@stupidchicken.com>
2
3 * cus-edit.el (custom-variable, custom-face): Doc fix.
4 (custom-face-edit): Add value-create attribute.
5 (custom-face-edit-value-create)
6 (custom-face-edit-value-visibility-action): New functions. Hide
7 unused face attributes by default, and add a visibility toggle.
8 (custom-face-edit-deactivate): Show empty values with shadow face.
9 (custom-face-selected): Only use this for face specs with default
10 attributes.
11 (custom-face-value-create): Cleanup.
12
13 * wid-edit.el (widget-checklist-value-create): Use dolist.
14 (widget-checklist-match-find): Make second arg optional.
15
12010-10-07 Glenn Morris <rgm@gnu.org> 162010-10-07 Glenn Morris <rgm@gnu.org>
2 17
3 * hilit-chg.el (hilit-chg-get-diff-info, hilit-chg-get-diff-list-hk): 18 * hilit-chg.el (hilit-chg-get-diff-info, hilit-chg-get-diff-list-hk):
diff --git a/lisp/cus-edit.el b/lisp/cus-edit.el
index a333be289ed..028426783c8 100644
--- a/lisp/cus-edit.el
+++ b/lisp/cus-edit.el
@@ -1914,7 +1914,7 @@ something in this group has been edited but not set.")
1914SET for current session only." "\ 1914SET for current session only." "\
1915something in this group has been set but not saved.") 1915something in this group has been set but not saved.")
1916 (changed ":" custom-changed "\ 1916 (changed ":" custom-changed "\
1917CHANGED outside Customize; operating on it here may be unreliable." "\ 1917CHANGED outside Customize." "\
1918something in this group has been changed outside customize.") 1918something in this group has been changed outside customize.")
1919 (saved "!" custom-saved "\ 1919 (saved "!" custom-saved "\
1920SAVED and set." "\ 1920SAVED and set." "\
@@ -2456,16 +2456,22 @@ However, setting it through Custom sets the default value.")
2456(define-widget 'custom-variable 'custom 2456(define-widget 'custom-variable 'custom
2457 "A widget for displaying a Custom variable. 2457 "A widget for displaying a Custom variable.
2458 2458
2459The following property has a special meaning for this widget: 2459The following properties have special meanings for this widget:
2460:hidden-states - A list of widget states for which the widget's initial 2460
2461 contents should be hidden." 2461:hidden-states should be a list of widget states for which the
2462 widget's initial contents are to be hidden.
2463
2464:custom-form should be a symbol describing how to display and
2465 edit the variable---either `edit' (using edit widgets),
2466 `lisp' (as a Lisp sexp), or `mismatch' (should not happen);
2467 if nil, use the return value of `custom-variable-default-form'."
2462 :format "%v" 2468 :format "%v"
2463 :help-echo "Set or reset this variable." 2469 :help-echo "Set or reset this variable."
2464 :documentation-property #'custom-variable-documentation 2470 :documentation-property #'custom-variable-documentation
2465 :custom-category 'option 2471 :custom-category 'option
2466 :custom-state nil 2472 :custom-state nil
2467 :custom-menu 'custom-variable-menu-create 2473 :custom-menu 'custom-variable-menu-create
2468 :custom-form nil ; defaults to value of `custom-variable-default-form' 2474 :custom-form nil
2469 :value-create 'custom-variable-value-create 2475 :value-create 'custom-variable-value-create
2470 :action 'custom-variable-action 2476 :action 'custom-variable-action
2471 :hidden-states '(standard) 2477 :hidden-states '(standard)
@@ -3026,24 +3032,64 @@ to switch between two values."
3026;;; The `custom-face-edit' Widget. 3032;;; The `custom-face-edit' Widget.
3027 3033
3028(define-widget 'custom-face-edit 'checklist 3034(define-widget 'custom-face-edit 'checklist
3029 "Edit face attributes." 3035 "Widget for editing face attributes."
3030 :format "%t: %v" 3036 :format "%v"
3031 :tag "Attributes" 3037 :extra-offset 3
3032 :extra-offset 13
3033 :button-args '(:help-echo "Control whether this attribute has any effect.") 3038 :button-args '(:help-echo "Control whether this attribute has any effect.")
3034 :value-to-internal 'custom-face-edit-fix-value 3039 :value-to-internal 'custom-face-edit-fix-value
3035 :match (lambda (widget value) 3040 :match (lambda (widget value)
3036 (widget-checklist-match widget 3041 (widget-checklist-match widget
3037 (custom-face-edit-fix-value widget value))) 3042 (custom-face-edit-fix-value widget value)))
3043 :value-create 'custom-face-edit-value-create
3038 :convert-widget 'custom-face-edit-convert-widget 3044 :convert-widget 'custom-face-edit-convert-widget
3039 :args (mapcar (lambda (att) 3045 :args (mapcar (lambda (att)
3040 (list 'group 3046 (list 'group :inline t
3041 :inline t
3042 :sibling-args (widget-get (nth 1 att) :sibling-args) 3047 :sibling-args (widget-get (nth 1 att) :sibling-args)
3043 (list 'const :format "" :value (nth 0 att)) 3048 (list 'const :format "" :value (nth 0 att))
3044 (nth 1 att))) 3049 (nth 1 att)))
3045 custom-face-attributes)) 3050 custom-face-attributes))
3046 3051
3052(defun custom-face-edit-value-create (widget)
3053 (let* ((value (widget-get widget :value)) ; list of key-value pairs
3054 (alist (widget-checklist-match-find widget value))
3055 (args (widget-get widget :args))
3056 (show-all (widget-get widget :show-all-attributes))
3057 (buttons (widget-get widget :buttons))
3058 entry)
3059 (unless (looking-back "^ *")
3060 (insert ?\n))
3061 (insert-char ?\s (widget-get widget :extra-offset))
3062 (if (or alist show-all)
3063 (dolist (prop args)
3064 (setq entry (assq prop alist))
3065 (if (or entry show-all)
3066 (widget-checklist-add-item widget prop entry)))
3067 (insert (propertize "-- Empty face --" 'face 'shadow) ?\n))
3068 (let ((indent (widget-get widget :indent)))
3069 (if indent (insert-char ?\s (widget-get widget :indent))))
3070 (push (widget-create-child-and-convert
3071 widget 'visibility
3072 :help-echo "Show or hide all face attributes."
3073 :button-face 'custom-visibility
3074 :pressed-face 'custom-visibility
3075 :mouse-face 'highlight
3076 :on "Hide Unused Attributes" :off "Show All Attributes"
3077 :on-image nil :off-image nil
3078 :always-active t
3079 :action 'custom-face-edit-value-visibility-action
3080 show-all)
3081 buttons)
3082 (insert ?\n)
3083 (widget-put widget :buttons buttons)
3084 (widget-put widget :children (nreverse (widget-get widget :children)))))
3085
3086(defun custom-face-edit-value-visibility-action (widget &rest ignore)
3087 ;; Toggle hiding of face attributes.
3088 (let ((parent (widget-get widget :parent)))
3089 (widget-put parent :show-all-attributes
3090 (not (widget-get parent :show-all-attributes)))
3091 (custom-redraw parent)))
3092
3047(defun custom-face-edit-fix-value (widget value) 3093(defun custom-face-edit-fix-value (widget value)
3048 "Ignoring WIDGET, convert :bold and :italic in VALUE to new form. 3094 "Ignoring WIDGET, convert :bold and :italic in VALUE to new form.
3049Also change :reverse-video to :inverse-video." 3095Also change :reverse-video to :inverse-video."
@@ -3092,7 +3138,7 @@ Also change :reverse-video to :inverse-video."
3092 (save-excursion 3138 (save-excursion
3093 (goto-char from) 3139 (goto-char from)
3094 (widget-default-delete widget) 3140 (widget-default-delete widget)
3095 (insert tag ": *\n") 3141 (insert tag ": " (propertize "--" 'face 'shadow) "\n")
3096 (widget-put widget :inactive 3142 (widget-put widget :inactive
3097 (cons value (cons from (- (point) from)))))))) 3143 (cons value (cons from (- (point) from))))))))
3098 3144
@@ -3235,14 +3281,23 @@ Only match frames that support the specified face attributes.")
3235 :version "20.3") 3281 :version "20.3")
3236 3282
3237(define-widget 'custom-face 'custom 3283(define-widget 'custom-face 'custom
3238 "Customize face." 3284 "Widget for customizing a face.
3285The widget value is the face name (a symbol).
3286
3287The following properties have special meanings for this widget:
3288
3289:custom-form should be a symbol describing how to display and
3290 edit the face attributes---either `selected' (attributes for
3291 selected display only), `all' (all attributes), `lisp' (as a
3292 Lisp sexp), or `mismatch' (should not happen); if nil, use
3293 the return value of `custom-face-default-form'."
3239 :sample-face 'custom-face-tag 3294 :sample-face 'custom-face-tag
3240 :help-echo "Set or reset this face." 3295 :help-echo "Set or reset this face."
3241 :documentation-property #'face-doc-string 3296 :documentation-property #'face-doc-string
3242 :value-create 'custom-face-value-create 3297 :value-create 'custom-face-value-create
3243 :action 'custom-face-action 3298 :action 'custom-face-action
3244 :custom-category 'face 3299 :custom-category 'face
3245 :custom-form nil ; defaults to value of `custom-face-default-form' 3300 :custom-form nil
3246 :custom-set 'custom-face-set 3301 :custom-set 'custom-face-set
3247 :custom-mark-to-save 'custom-face-mark-to-save 3302 :custom-mark-to-save 'custom-face-mark-to-save
3248 :custom-reset-current 'custom-redraw 3303 :custom-reset-current 'custom-redraw
@@ -3273,30 +3328,16 @@ Only match frames that support the specified face attributes.")
3273 (not (face-spec-set-match-display value (selected-frame)))) 3328 (not (face-spec-set-match-display value (selected-frame))))
3274 3329
3275(define-widget 'custom-face-selected 'group 3330(define-widget 'custom-face-selected 'group
3276 "Edit the attributes of the selected display in a face specification." 3331 "Widget for editing the attributes of a face on the selected display."
3277 :args '((choice :inline t 3332 :args '((group :tag "No Defaults" :inline t
3278 (group :tag "With Defaults" :inline t 3333 (repeat :format ""
3279 (group (const :tag "" default) 3334 :inline t
3280 (custom-face-edit :tag " Default\n Attributes")) 3335 (group custom-display-unselected sexp))
3281 (repeat :format "" 3336 (group (sexp :format "")
3282 :inline t 3337 (custom-face-edit :tag "\n Attributes"))
3283 (group custom-display-unselected sexp)) 3338 (repeat :format ""
3284 (group (sexp :format "") 3339 :inline t
3285 (custom-face-edit :tag " Overriding\n Attributes")) 3340 sexp))))
3286 (repeat :format ""
3287 :inline t
3288 sexp))
3289 (group :tag "No Defaults" :inline t
3290 (repeat :format ""
3291 :inline t
3292 (group custom-display-unselected sexp))
3293 (group (sexp :format "")
3294 (custom-face-edit :tag "\n Attributes"))
3295 (repeat :format ""
3296 :inline t
3297 sexp)))))
3298
3299
3300 3341
3301(defconst custom-face-selected (widget-convert 'custom-face-selected) 3342(defconst custom-face-selected (widget-convert 'custom-face-selected)
3302 "Converted version of the `custom-face-selected' widget.") 3343 "Converted version of the `custom-face-selected' widget.")
@@ -3344,120 +3385,114 @@ SPEC must be a full face spec."
3344 3385
3345(defun custom-face-value-create (widget) 3386(defun custom-face-value-create (widget)
3346 "Create a list of the display specifications for WIDGET." 3387 "Create a list of the display specifications for WIDGET."
3347 (let ((buttons (widget-get widget :buttons)) 3388 (let* ((buttons (widget-get widget :buttons))
3348 children 3389 (symbol (widget-get widget :value))
3349 (symbol (widget-get widget :value)) 3390 (tag (or (widget-get widget :tag)
3350 (tag (widget-get widget :tag)) 3391 (prin1-to-string symbol)))
3351 (state (widget-get widget :custom-state)) 3392 (hiddenp (eq (widget-get widget :custom-state) 'hidden))
3352 (begin (point)) 3393 children)
3353 (is-last (widget-get widget :custom-last)) 3394
3354 (prefix (widget-get widget :custom-prefix))) 3395 (if (eq custom-buffer-style 'tree)
3355 (unless tag 3396
3356 (setq tag (prin1-to-string symbol))) 3397 ;; Draw a tree-style `custom-face' widget
3357 (cond ((eq custom-buffer-style 'tree) 3398 (progn
3358 (insert prefix (if is-last " `--- " " |--- ")) 3399 (insert (widget-get widget :custom-prefix)
3359 (push (widget-create-child-and-convert 3400 (if (widget-get widget :custom-last) " `--- " " |--- "))
3360 widget 'custom-browse-face-tag) 3401 (push (widget-create-child-and-convert
3361 buttons) 3402 widget 'custom-browse-face-tag)
3362 (insert " " tag "\n") 3403 buttons)
3363 (widget-put widget :buttons buttons)) 3404 (insert " " tag "\n")
3364 (t 3405 (widget-put widget :buttons buttons))
3365 ;; Visibility. 3406
3366 (push (widget-create-child-and-convert 3407 ;; Draw an ordinary `custom-face' widget
3367 widget 'custom-visibility 3408 (let ((opoint (point)))
3368 :help-echo "Hide or show this face." 3409 ;; Visibility indicator.
3369 :on "Hide" 3410 (push (widget-create-child-and-convert
3370 :off "Show" 3411 widget 'custom-visibility
3371 :on-image "down" 3412 :help-echo "Hide or show this face."
3372 :off-image "right" 3413 :on "Hide" :off "Show"
3373 :action 'custom-toggle-parent 3414 :on-image "down" :off-image "right"
3374 (not (eq state 'hidden))) 3415 :action 'custom-toggle-parent
3375 buttons) 3416 (not hiddenp))
3376 (insert " ") 3417 buttons)
3377 ;; Create tag. 3418 ;; Face name (tag).
3378 (insert tag) 3419 (insert " " tag)
3379 (widget-specify-sample widget begin (point)) 3420 (widget-specify-sample widget opoint (point)))
3380 (if (eq custom-buffer-style 'face) 3421 (insert
3381 (insert " ") 3422 (cond ((eq custom-buffer-style 'face) " ")
3382 (if (string-match "face\\'" tag) 3423 ((string-match "face\\'" tag) ":")
3383 (insert ":") 3424 (t " face: ")))
3384 (insert " face: "))) 3425
3385 ;; Sample. 3426 ;; Face sample.
3386 (push (widget-create-child-and-convert widget 'item 3427 (push (widget-create-child-and-convert
3387 :format "(%{%t%})" 3428 widget 'item
3388 :sample-face symbol 3429 :format "(%{%t%})" :sample-face symbol :tag "sample")
3389 :tag "sample") 3430 buttons)
3390 buttons) 3431 ;; Magic.
3391 ;; Magic. 3432 (insert "\n")
3392 (insert "\n") 3433 (let ((magic (widget-create-child-and-convert
3393 (let ((magic (widget-create-child-and-convert 3434 widget 'custom-magic nil)))
3394 widget 'custom-magic nil))) 3435 (widget-put widget :custom-magic magic)
3395 (widget-put widget :custom-magic magic) 3436 (push magic buttons))
3396 (push magic buttons)) 3437
3397 ;; Update buttons. 3438 ;; Update buttons.
3398 (widget-put widget :buttons buttons) 3439 (widget-put widget :buttons buttons)
3399 ;; Insert documentation. 3440
3400 (widget-put widget :documentation-indent 3) 3441 ;; Insert documentation.
3401 (widget-add-documentation-string-button 3442 (widget-put widget :documentation-indent 3)
3402 widget :visibility-widget 'custom-visibility) 3443 (widget-add-documentation-string-button
3403 3444 widget :visibility-widget 'custom-visibility)
3404 ;; The comment field 3445 ;; The comment field
3405 (unless (eq state 'hidden) 3446 (unless hiddenp
3406 (let* ((comment (get symbol 'face-comment)) 3447 (let* ((comment (get symbol 'face-comment))
3407 (comment-widget 3448 (comment-widget
3408 (widget-create-child-and-convert 3449 (widget-create-child-and-convert
3409 widget 'custom-comment 3450 widget 'custom-comment
3410 :parent widget 3451 :parent widget
3411 :value (or comment "")))) 3452 :value (or comment ""))))
3412 (widget-put widget :comment-widget comment-widget) 3453 (widget-put widget :comment-widget comment-widget)
3413 (push comment-widget children))) 3454 (push comment-widget children)))
3414 ;; See also. 3455
3415 (unless (eq state 'hidden) 3456 ;; Editor.
3416 (when (eq (widget-get widget :custom-level) 1) 3457 (unless (eq (preceding-char) ?\n)
3417 (custom-add-parent-links widget)) 3458 (insert "\n"))
3418 (custom-add-see-also widget)) 3459 (unless hiddenp
3419 ;; Editor. 3460 (custom-load-widget widget)
3420 (unless (eq (preceding-char) ?\n) 3461 (unless (widget-get widget :custom-form)
3421 (insert "\n")) 3462 (widget-put widget :custom-form custom-face-default-form))
3422 (unless (eq state 'hidden) 3463
3423 (message "Creating face editor...") 3464 (let* ((spec (or (get symbol 'customized-face)
3424 (custom-load-widget widget) 3465 (get symbol 'saved-face)
3425 (unless (widget-get widget :custom-form) 3466 (get symbol 'face-defface-spec)
3426 (widget-put widget :custom-form custom-face-default-form)) 3467 ;; Attempt to construct it.
3427 (let* ((symbol (widget-value widget)) 3468 (list (list t (custom-face-attributes-get
3428 (spec (or (get symbol 'customized-face) 3469 symbol (selected-frame))))))
3429 (get symbol 'saved-face) 3470 (form (widget-get widget :custom-form))
3430 (get symbol 'face-defface-spec) 3471 (indent (widget-get widget :indent))
3431 ;; Attempt to construct it. 3472 edit-widget-type edit)
3432 (list (list t (custom-face-attributes-get 3473 ;; If the user has changed this face in some other way,
3433 symbol (selected-frame)))))) 3474 ;; edit it as the user has specified it.
3434 (form (widget-get widget :custom-form)) 3475 (if (not (face-spec-match-p symbol spec (selected-frame)))
3435 (indent (widget-get widget :indent)) 3476 (setq spec `((t ,(face-attr-construct symbol
3436 edit) 3477 (selected-frame))))))
3437 ;; If the user has changed this face in some other way, 3478 (setq spec (custom-pre-filter-face-spec spec))
3438 ;; edit it as the user has specified it. 3479
3439 (if (not (face-spec-match-p symbol spec (selected-frame))) 3480 (cond ((and (eq form 'selected)
3440 (setq spec (list (list t (face-attr-construct symbol (selected-frame)))))) 3481 (widget-apply custom-face-selected :match spec))
3441 (setq spec (custom-pre-filter-face-spec spec)) 3482 (when indent (insert-char ?\s indent))
3442 (setq edit (widget-create-child-and-convert 3483 (setq edit-widget-type 'custom-face-selected))
3443 widget 3484 ((and (not (eq form 'lisp))
3444 (cond ((and (eq form 'selected) 3485 (widget-apply custom-face-all :match spec))
3445 (widget-apply custom-face-selected 3486 (setq edit-widget-type 'custom-face-all))
3446 :match spec)) 3487 (t
3447 (when indent (insert-char ?\ indent)) 3488 (when indent
3448 'custom-face-selected) 3489 (insert-char ?\s indent))
3449 ((and (not (eq form 'lisp)) 3490 (setq edit-widget-type 'sexp)))
3450 (widget-apply custom-face-all 3491 (setq edit (widget-create-child-and-convert
3451 :match spec)) 3492 widget edit-widget-type :value spec))
3452 'custom-face-all) 3493 (custom-face-state-set widget)
3453 (t 3494 (push edit children)
3454 (when indent (insert-char ?\ indent)) 3495 (widget-put widget :children children))))))
3455 'sexp))
3456 :value spec))
3457 (custom-face-state-set widget)
3458 (push edit children)
3459 (widget-put widget :children children))
3460 (message "Creating face editor...done"))))))
3461 3496
3462(defvar custom-face-menu 3497(defvar custom-face-menu
3463 `(("Set for Current Session" custom-face-set) 3498 `(("Set for Current Session" custom-face-set)
diff --git a/lisp/wid-edit.el b/lisp/wid-edit.el
index 721414b32ac..22c8a21a203 100644
--- a/lisp/wid-edit.el
+++ b/lisp/wid-edit.el
@@ -2237,11 +2237,10 @@ when he invoked the menu."
2237 2237
2238(defun widget-checklist-value-create (widget) 2238(defun widget-checklist-value-create (widget)
2239 ;; Insert all values 2239 ;; Insert all values
2240 (let ((alist (widget-checklist-match-find widget (widget-get widget :value))) 2240 (let ((alist (widget-checklist-match-find widget))
2241 (args (widget-get widget :args))) 2241 (args (widget-get widget :args)))
2242 (while args 2242 (dolist (item args)
2243 (widget-checklist-add-item widget (car args) (assq (car args) alist)) 2243 (widget-checklist-add-item widget item (assq item alist)))
2244 (setq args (cdr args)))
2245 (widget-put widget :children (nreverse (widget-get widget :children))))) 2244 (widget-put widget :children (nreverse (widget-get widget :children)))))
2246 2245
2247(defun widget-checklist-add-item (widget type chosen) 2246(defun widget-checklist-add-item (widget type chosen)
@@ -2314,9 +2313,10 @@ If the item is checked, CHOSEN is a cons whose cdr is the value."
2314 values nil))))) 2313 values nil)))))
2315 (cons found rest))) 2314 (cons found rest)))
2316 2315
2317(defun widget-checklist-match-find (widget vals) 2316(defun widget-checklist-match-find (widget &optional vals)
2318 "Find the vals which match a type in the checklist. 2317 "Find the vals which match a type in the checklist.
2319Return an alist of (TYPE MATCH)." 2318Return an alist of (TYPE MATCH)."
2319 (or vals (setq vals (widget-get widget :value)))
2320 (let ((greedy (widget-get widget :greedy)) 2320 (let ((greedy (widget-get widget :greedy))
2321 (args (copy-sequence (widget-get widget :args))) 2321 (args (copy-sequence (widget-get widget :args)))
2322 found) 2322 found)
@@ -2809,11 +2809,10 @@ Return an alist of (TYPE MATCH)."
2809 argument answer found) 2809 argument answer found)
2810 (while args 2810 (while args
2811 (setq argument (car args) 2811 (setq argument (car args)
2812 args (cdr args) 2812 args (cdr args))
2813 answer (widget-match-inline argument vals)) 2813 (if (setq answer (widget-match-inline argument vals))
2814 (if answer 2814 (setq found (append found (car answer))
2815 (setq vals (cdr answer) 2815 vals (cdr answer))
2816 found (append found (car answer)))
2817 (setq vals nil 2816 (setq vals nil
2818 args nil))) 2817 args nil)))
2819 (if answer 2818 (if answer