comparison lisp/custom/cus-edit.el @ 165:5a88923fcbfe r20-3b9

Import from CVS: tag r20-3b9
author cvs
date Mon, 13 Aug 2007 09:44:42 +0200
parents 0132846995bd
children 85ec50267440
comparison
equal deleted inserted replaced
164:4e0740e5aab2 165:5a88923fcbfe
2 ;; 2 ;;
3 ;; Copyright (C) 1996, 1997 Free Software Foundation, Inc. 3 ;; Copyright (C) 1996, 1997 Free Software Foundation, Inc.
4 ;; 4 ;;
5 ;; Author: Per Abrahamsen <abraham@dina.kvl.dk> 5 ;; Author: Per Abrahamsen <abraham@dina.kvl.dk>
6 ;; Keywords: help, faces 6 ;; Keywords: help, faces
7 ;; Version: 1.9931 7 ;; Version: 1.9937
8 ;; X-URL: http://www.dina.kvl.dk/~abraham/custom/ 8 ;; X-URL: http://www.dina.kvl.dk/~abraham/custom/
9 9
10 ;; This file is part of GNU Emacs. 10 ;; This file is part of GNU Emacs.
11 11
12 ;; GNU Emacs is free software; you can redistribute it and/or modify 12 ;; GNU Emacs is free software; you can redistribute it and/or modify
27 ;;; Commentary: 27 ;;; Commentary:
28 ;; 28 ;;
29 ;; This file implements the code to create and edit customize buffers. 29 ;; This file implements the code to create and edit customize buffers.
30 ;; 30 ;;
31 ;; See `custom.el'. 31 ;; See `custom.el'.
32
33 ;; No commands should have names starting with `custom-' because
34 ;; that interferes with completion. Use `customize-' for commands
35 ;; that the user will run with M-x, and `Custom-' for interactive commands.
32 36
33 ;;; Code: 37 ;;; Code:
34 38
35 (require 'cus-face) 39 (require 'cus-face)
36 (require 'wid-edit) 40 (require 'wid-edit)
249 (defgroup custom-faces nil 253 (defgroup custom-faces nil
250 "Faces used by customize." 254 "Faces used by customize."
251 :group 'customize 255 :group 'customize
252 :group 'faces) 256 :group 'faces)
253 257
254 (defgroup custom-buffer nil 258 (defgroup custom-browse nil
255 "Control the customize buffers." 259 "Control customize browser."
256 :prefix "custom-" 260 :prefix "custom-"
257 :group 'customize) 261 :group 'customize)
258 262
263 (defgroup custom-buffer nil
264 "Control customize buffers."
265 :prefix "custom-"
266 :group 'customize)
267
259 (defgroup custom-menu nil 268 (defgroup custom-menu nil
260 "Control how the customize menus." 269 "Control customize menus."
261 :prefix "custom-" 270 :prefix "custom-"
262 :group 'customize) 271 :group 'customize)
263 272
264 (defgroup abbrev-mode nil 273 (defgroup abbrev-mode nil
265 "Word abbreviations mode." 274 "Word abbreviations mode."
543 docs nil)))))) 552 docs nil))))))
544 found)) 553 found))
545 554
546 ;;; Sorting. 555 ;;; Sorting.
547 556
557 (defcustom custom-browse-sort-alphabetically nil
558 "If non-nil, sort members of each customization group alphabetically."
559 :type 'boolean
560 :group 'custom-browse)
561
562 (defcustom custom-browse-order-groups nil
563 "If non-nil, order group members within each customization group.
564 If `first', order groups before non-groups.
565 If `last', order groups after non-groups."
566 :type '(choice (const first)
567 (const last)
568 (const :tag "none" nil))
569 :group 'custom-browse)
570
548 (defcustom custom-buffer-sort-alphabetically nil 571 (defcustom custom-buffer-sort-alphabetically nil
549 "If non-nil, sort the members of each customization group alphabetically." 572 "If non-nil, sort members of each customization group alphabetically."
550 :type 'boolean 573 :type 'boolean
551 :group 'custom-buffer) 574 :group 'custom-buffer)
552 575
553 (defcustom custom-buffer-groups-last nil 576 (defcustom custom-buffer-order-groups 'last
554 "If non-nil, put subgroups after all ordinary options within a group." 577 "If non-nil, order group members within each customization group.
555 :type 'boolean 578 If `first', order groups before non-groups.
579 If `last', order groups after non-groups."
580 :type '(choice (const first)
581 (const last)
582 (const :tag "none" nil))
556 :group 'custom-buffer) 583 :group 'custom-buffer)
557 584
558 (defcustom custom-menu-sort-alphabetically nil 585 (defcustom custom-menu-sort-alphabetically nil
559 "If non-nil, sort the members of each customization group alphabetically." 586 "If non-nil, sort members of each customization group alphabetically."
560 :type 'boolean 587 :type 'boolean
561 :group 'custom-menu) 588 :group 'custom-menu)
562 589
563 (defcustom custom-menu-groups-first t 590 (defcustom custom-menu-order-groups 'first
564 "If non-nil, put subgroups before all ordinary options within a group." 591 "If non-nil, order group members within each customization group.
565 :type 'boolean 592 If `first', order groups before non-groups.
593 If `last', order groups after non-groups."
594 :type '(choice (const first)
595 (const last)
596 (const :tag "none" nil))
566 :group 'custom-menu) 597 :group 'custom-menu)
567 598
568 (defun custom-buffer-sort-predicate (a b) 599 (defun custom-sort-items (items sort-alphabetically order-groups)
569 "Return t iff A should come before B in a customization buffer. 600 "Return a sorted copy of ITEMS.
570 A and B should be members of a `custom-group' property." 601 ITEMS should be a `custom-group' property.
571 (cond ((and (not custom-buffer-groups-last) 602 If SORT-ALPHABETICALLY non-nil, sort alphabetically.
572 (not custom-buffer-sort-alphabetically)) 603 If ORDER-GROUPS is `first' order groups before non-groups, if `last' order
573 nil) 604 groups after non-groups, if nil do not order groups at all."
574 ((or (eq (eq (nth 1 a) 'custom-group) (eq (nth 1 b) 'custom-group)) 605 (sort (copy-sequence items)
575 (not custom-buffer-groups-last)) 606 (lambda (a b)
576 (if custom-buffer-sort-alphabetically 607 (let ((typea (nth 1 a)) (typeb (nth 1 b))
577 (string-lessp (symbol-name (nth 0 a)) (symbol-name (nth 0 b))) 608 (namea (symbol-name (nth 0 a))) (nameb (symbol-name (nth 0 b))))
578 nil)) 609 (cond ((not order-groups)
579 (t 610 ;; Since we don't care about A and B order, maybe sort.
580 (not (eq (nth 1 a) 'custom-group) )))) 611 (when sort-alphabetically
581 612 (string-lessp namea nameb)))
582 (defalias 'custom-browse-sort-predicate 'ignore) 613 ((eq typea 'custom-group)
583 614 ;; If B is also a group, maybe sort. Otherwise, order A and B.
584 (defun custom-menu-sort-predicate (a b) 615 (if (eq typeb 'custom-group)
585 "Return t iff A should come before B in a customization menu. 616 (when sort-alphabetically
586 A and B should be members of a `custom-group' property." 617 (string-lessp namea nameb))
587 (cond ((and (not custom-menu-groups-first) 618 (eq order-groups 'first)))
588 (not custom-menu-sort-alphabetically)) 619 ((eq typeb 'custom-group)
589 nil) 620 ;; Since A cannot be a group, order A and B.
590 ((or (eq (eq (nth 1 a) 'custom-group) (eq (nth 1 b) 'custom-group)) 621 (eq order-groups 'last))
591 (not custom-menu-groups-first)) 622 (sort-alphabetically
592 (if custom-menu-sort-alphabetically 623 ;; Since A and B cannot be groups, sort.
593 (string-lessp (symbol-name (nth 0 a)) (symbol-name (nth 0 b))) 624 (string-lessp namea nameb)))))))
594 nil))
595 (t
596 (eq (nth 1 a) 'custom-group) )))
597 625
598 ;;; Custom Mode Commands. 626 ;;; Custom Mode Commands.
599 627
600 (defvar custom-options nil 628 (defvar custom-options nil
601 "Customization widgets in the current buffer.") 629 "Customization widgets in the current buffer.")
602 630
603 (defun custom-set () 631 (defun Custom-set ()
604 "Set changes in all modified options." 632 "Set changes in all modified options."
605 (interactive) 633 (interactive)
606 (let ((children custom-options)) 634 (let ((children custom-options))
607 (mapcar (lambda (child) 635 (mapcar (lambda (child)
608 (when (eq (widget-get child :custom-state) 'modified) 636 (when (eq (widget-get child :custom-state) 'modified)
609 (widget-apply child :custom-set))) 637 (widget-apply child :custom-set)))
610 children))) 638 children)))
611 639
612 (defun custom-save () 640 (defun Custom-save ()
613 "Set all modified group members and save them." 641 "Set all modified group members and save them."
614 (interactive) 642 (interactive)
615 (let ((children custom-options)) 643 (let ((children custom-options))
616 (mapcar (lambda (child) 644 (mapcar (lambda (child)
617 (when (memq (widget-get child :custom-state) '(modified set)) 645 (when (memq (widget-get child :custom-state) '(modified set))
618 (widget-apply child :custom-save))) 646 (widget-apply child :custom-save)))
619 children)) 647 children))
620 (custom-save-all)) 648 (custom-save-all))
621 649
622 (defvar custom-reset-menu 650 (defvar custom-reset-menu
623 '(("Current" . custom-reset-current) 651 '(("Current" . Custom-reset-current)
624 ("Saved" . custom-reset-saved) 652 ("Saved" . Custom-reset-saved)
625 ("Standard Settings" . custom-reset-standard)) 653 ("Standard Settings" . Custom-reset-standard))
626 "Alist of actions for the `Reset' button. 654 "Alist of actions for the `Reset' button.
627 The key is a string containing the name of the action, the value is a 655 The key is a string containing the name of the action, the value is a
628 lisp function taking the widget as an element which will be called 656 lisp function taking the widget as an element which will be called
629 when the action is chosen.") 657 when the action is chosen.")
630 658
635 custom-reset-menu 663 custom-reset-menu
636 event))) 664 event)))
637 (if answer 665 (if answer
638 (funcall answer)))) 666 (funcall answer))))
639 667
640 (defun custom-reset-current (&rest ignore) 668 (defun Custom-reset-current (&rest ignore)
641 "Reset all modified group members to their current value." 669 "Reset all modified group members to their current value."
642 (interactive) 670 (interactive)
643 (let ((children custom-options)) 671 (let ((children custom-options))
644 (mapcar (lambda (child) 672 (mapcar (lambda (child)
645 (when (eq (widget-get child :custom-state) 'modified) 673 (when (eq (widget-get child :custom-state) 'modified)
646 (widget-apply child :custom-reset-current))) 674 (widget-apply child :custom-reset-current)))
647 children))) 675 children)))
648 676
649 (defun custom-reset-saved (&rest ignore) 677 (defun Custom-reset-saved (&rest ignore)
650 "Reset all modified or set group members to their saved value." 678 "Reset all modified or set group members to their saved value."
651 (interactive) 679 (interactive)
652 (let ((children custom-options)) 680 (let ((children custom-options))
653 (mapcar (lambda (child) 681 (mapcar (lambda (child)
654 (when (eq (widget-get child :custom-state) 'modified) 682 (when (eq (widget-get child :custom-state) 'modified)
655 (widget-apply child :custom-reset-saved))) 683 (widget-apply child :custom-reset-saved)))
656 children))) 684 children)))
657 685
658 (defun custom-reset-standard (&rest ignore) 686 (defun Custom-reset-standard (&rest ignore)
659 "Reset all modified, set, or saved group members to their standard settings." 687 "Reset all modified, set, or saved group members to their standard settings."
660 (interactive) 688 (interactive)
661 (let ((children custom-options)) 689 (let ((children custom-options))
662 (mapcar (lambda (child) 690 (mapcar (lambda (child)
663 (when (eq (widget-get child :custom-state) 'modified) 691 (when (eq (widget-get child :custom-state) 'modified)
699 (not (boundp var)))) 727 (not (boundp var))))
700 (t 728 (t
701 (eval-minibuffer prompt))))))) 729 (eval-minibuffer prompt)))))))
702 730
703 ;;;###autoload 731 ;;;###autoload
704 (defun custom-set-value (var val) 732 (defun customize-set-value (var val)
705 "Set VARIABLE to VALUE. VALUE is a Lisp object. 733 "Set VARIABLE to VALUE. VALUE is a Lisp object.
706 734
707 If VARIABLE has a `variable-interactive' property, that is used as if 735 If VARIABLE has a `variable-interactive' property, that is used as if
708 it were the arg to `interactive' (which see) to interactively read the value. 736 it were the arg to `interactive' (which see) to interactively read the value.
709 737
713 "Set %s to value: ")) 741 "Set %s to value: "))
714 742
715 (set var val)) 743 (set var val))
716 744
717 ;;;###autoload 745 ;;;###autoload
718 (defun custom-set-variable (var val) 746 (defun customize-set-variable (var val)
719 "Set the default for VARIABLE to VALUE. VALUE is a Lisp object. 747 "Set the default for VARIABLE to VALUE. VALUE is a Lisp object.
720 748
721 If VARIABLE has a `custom-set' property, that is used for setting 749 If VARIABLE has a `custom-set' property, that is used for setting
722 VARIABLE, otherwise `set-default' is used. 750 VARIABLE, otherwise `set-default' is used.
723 751
809 "Customize SYMBOL, which should be a face name or nil. 837 "Customize SYMBOL, which should be a face name or nil.
810 If SYMBOL is nil, customize all faces." 838 If SYMBOL is nil, customize all faces."
811 (interactive (list (completing-read "Customize face: (default all) " 839 (interactive (list (completing-read "Customize face: (default all) "
812 obarray 'custom-facep))) 840 obarray 'custom-facep)))
813 (if (or (null symbol) (and (stringp symbol) (zerop (length symbol)))) 841 (if (or (null symbol) (and (stringp symbol) (zerop (length symbol))))
814 (let ((found nil)) 842 (custom-buffer-create (custom-sort-items
815 (message "Looking for faces...") 843 (mapcar (lambda (symbol)
816 (mapcar (lambda (symbol) 844 (list symbol 'custom-face))
817 (push (list symbol 'custom-face) found)) 845 (face-list))
818 (nreverse (mapcar 'intern 846 t nil)
819 (sort (mapcar 'symbol-name (face-list)) 847 "*Customize Faces*")
820 'string-lessp)))) 848 (when (stringp symbol)
821 849 (setq symbol (intern symbol)))
822 (custom-buffer-create found "*Customize Faces*"))
823 (if (stringp symbol)
824 (setq symbol (intern symbol)))
825 (unless (symbolp symbol) 850 (unless (symbolp symbol)
826 (error "Should be a symbol %S" symbol)) 851 (error "Should be a symbol %S" symbol))
827 (custom-buffer-create (list (list symbol 'custom-face)) 852 (custom-buffer-create (list (list symbol 'custom-face))
828 (format "*Customize Face: %s*" 853 (format "*Customize Face: %s*"
829 (custom-unlispify-tag-name symbol))))) 854 (custom-unlispify-tag-name symbol)))))
853 (custom-facep symbol) 878 (custom-facep symbol)
854 (push (list symbol 'custom-face) found)) 879 (push (list symbol 'custom-face) found))
855 (and (get symbol 'customized-value) 880 (and (get symbol 'customized-value)
856 (boundp symbol) 881 (boundp symbol)
857 (push (list symbol 'custom-variable) found)))) 882 (push (list symbol 'custom-variable) found))))
858 (if found 883 (if (not found)
859 (custom-buffer-create found "*Customize Customized*") 884 (error "No customized user options")
860 (error "No customized user options")))) 885 (custom-buffer-create (custom-sort-items found t nil)
886 "*Customize Customized*"))))
861 887
862 ;;;###autoload 888 ;;;###autoload
863 (defun customize-saved () 889 (defun customize-saved ()
864 "Customize all already saved user options." 890 "Customize all already saved user options."
865 (interactive) 891 (interactive)
869 (custom-facep symbol) 895 (custom-facep symbol)
870 (push (list symbol 'custom-face) found)) 896 (push (list symbol 'custom-face) found))
871 (and (get symbol 'saved-value) 897 (and (get symbol 'saved-value)
872 (boundp symbol) 898 (boundp symbol)
873 (push (list symbol 'custom-variable) found)))) 899 (push (list symbol 'custom-variable) found))))
874 (if found 900 (if (not found )
875 (custom-buffer-create found "*Customize Saved*") 901 (error "No saved user options")
876 (error "No saved user options")))) 902 (custom-buffer-create (custom-sort-items found t nil)
903 "*Customize Saved*"))))
877 904
878 ;;;###autoload 905 ;;;###autoload
879 (defun customize-apropos (regexp &optional all) 906 (defun customize-apropos (regexp &optional all)
880 "Customize all user options matching REGEXP. 907 "Customize all user options matching REGEXP.
881 If ALL is `options', include only options. 908 If ALL is `options', include only options.
901 (user-variable-p symbol) 928 (user-variable-p symbol)
902 (get symbol 'variable-documentation)))) 929 (get symbol 'variable-documentation))))
903 (push (list symbol 'custom-variable) found))))) 930 (push (list symbol 'custom-variable) found)))))
904 (if (not found) 931 (if (not found)
905 (error "No matches") 932 (error "No matches")
906 (let ((custom-buffer-sort-alphabetically t)) 933 (custom-buffer-create (custom-sort-items found t
907 (custom-buffer-create (sort found 'custom-buffer-sort-predicate) 934 custom-buffer-order-groups)
908 "*Customize Apropos*"))))) 935 "*Customize Apropos*"))))
909 936
910 ;;;###autoload 937 ;;;###autoload
911 (defun customize-apropos-options (regexp &optional arg) 938 (defun customize-apropos-options (regexp &optional arg)
912 "Customize all user options matching REGEXP. 939 "Customize all user options matching REGEXP.
913 With prefix arg, include options which are not user-settable." 940 With prefix arg, include options which are not user-settable."
977 1004
978 (defun custom-buffer-create-internal (options) 1005 (defun custom-buffer-create-internal (options)
979 (message "Creating customization buffer...") 1006 (message "Creating customization buffer...")
980 (custom-mode) 1007 (custom-mode)
981 (widget-insert "This is a customization buffer. 1008 (widget-insert "This is a customization buffer.
982 Push RET or click mouse-2 on the word ") 1009 Square brackets show active fields; type RET or click mouse-2
1010 on an active field to invoke its action. Invoke ")
983 (widget-create 'info-link 1011 (widget-create 'info-link
984 :tag "help" 1012 :tag "Help"
985 :help-echo "Read the online help." 1013 :help-echo "Read the online help."
986 "(emacs)Easy Customization") 1014 "(emacs)Easy Customization")
987 (widget-insert " for more information.\n\n") 1015 (widget-insert " for more information.\n\n")
988 (message "Creating customization buttons...") 1016 (message "Creating customization buttons...")
1017 (widget-insert "Operate on everything in this buffer:\n ")
989 (widget-create 'push-button 1018 (widget-create 'push-button
990 :tag "Set" 1019 :tag "Set"
991 :help-echo "Set all modifications for this session." 1020 :help-echo "\
1021 Make your editing in this buffer take effect for this session."
992 :action (lambda (widget &optional event) 1022 :action (lambda (widget &optional event)
993 (custom-set))) 1023 (Custom-set)))
994 (widget-insert " ") 1024 (widget-insert " ")
995 (widget-create 'push-button 1025 (widget-create 'push-button
996 :tag "Save" 1026 :tag "Save"
997 :help-echo "\ 1027 :help-echo "\
998 Make the modifications default for future sessions." 1028 Make your editing in this buffer take effect for future Emacs sessions."
999 :action (lambda (widget &optional event) 1029 :action (lambda (widget &optional event)
1000 (custom-save))) 1030 (Custom-save)))
1001 (widget-insert " ") 1031 (widget-insert " ")
1002 (if custom-reset-button-menu 1032 (if custom-reset-button-menu
1003 (widget-create 'push-button 1033 (widget-create 'push-button
1004 :tag "Reset" 1034 :tag "Reset"
1005 :help-echo "Show a menu with reset operations." 1035 :help-echo "Show a menu with reset operations."
1007 :action (lambda (widget &optional event) 1037 :action (lambda (widget &optional event)
1008 (custom-reset event))) 1038 (custom-reset event)))
1009 (widget-create 'push-button 1039 (widget-create 'push-button
1010 :tag "Reset" 1040 :tag "Reset"
1011 :help-echo "\ 1041 :help-echo "\
1012 Reset all visible items in this buffer to their current settings." 1042 Reset all edited text in this buffer to reflect current values."
1013 :action 'custom-reset-current) 1043 :action 'Custom-reset-current)
1014 (widget-insert " ") 1044 (widget-insert " ")
1015 (widget-create 'push-button 1045 (widget-create 'push-button
1016 :tag "Reset to Saved" 1046 :tag "Reset to Saved"
1017 :help-echo "\ 1047 :help-echo "\
1018 Reset all visible items in this buffer to their saved settings." 1048 Reset all values in this buffer to their saved settings."
1019 :action 'custom-reset-saved) 1049 :action 'Custom-reset-saved)
1020 (widget-insert " ") 1050 (widget-insert " ")
1021 (widget-create 'push-button 1051 (widget-create 'push-button
1022 :tag "Reset to Standard" 1052 :tag "Reset to Standard"
1023 :help-echo "\ 1053 :help-echo "\
1024 Reset all visible items in this buffer to their standard settings." 1054 Reset all values in this buffer to their standard settings."
1025 :action 'custom-reset-standard)) 1055 :action 'Custom-reset-standard))
1026 (widget-insert " ") 1056 (widget-insert " ")
1027 (widget-create 'push-button 1057 (widget-create 'push-button
1028 :tag "Done" 1058 :tag "Bury Buffer"
1029 :help-echo "Bury the buffer." 1059 :help-echo "Bury the buffer."
1030 :action (lambda (widget &optional event) 1060 :action (lambda (widget &optional event)
1031 (bury-buffer))) 1061 (bury-buffer)))
1032 (widget-insert "\n\n") 1062 (widget-insert "\n\n")
1033 (message "Creating customization items...") 1063 (message "Creating customization items...")
1066 (message "Creating customization buffer...done")) 1096 (message "Creating customization buffer...done"))
1067 1097
1068 ;;; The Tree Browser. 1098 ;;; The Tree Browser.
1069 1099
1070 ;;;###autoload 1100 ;;;###autoload
1071 (defun customize-browse () 1101 (defun customize-browse (group)
1072 "Create a tree browser for the customize hierarchy." 1102 "Create a tree browser for the customize hierarchy."
1073 (interactive) 1103 (interactive (list (let ((completion-ignore-case t))
1104 (completing-read "Customize group: (default emacs) "
1105 obarray
1106 (lambda (symbol)
1107 (get symbol 'custom-group))
1108 t))))
1109
1110 (when (stringp group)
1111 (if (string-equal "" group)
1112 (setq group 'emacs)
1113 (setq group (intern group))))
1074 (let ((name "*Customize Browser*")) 1114 (let ((name "*Customize Browser*"))
1075 (kill-buffer (get-buffer-create name)) 1115 (kill-buffer (get-buffer-create name))
1076 (switch-to-buffer (get-buffer-create name))) 1116 (switch-to-buffer (get-buffer-create name)))
1077 (custom-mode) 1117 (custom-mode)
1078 (widget-insert "\ 1118 (widget-insert "\
1079 Invoke [+] below to expand items, and [-] to collapse items. 1119 Invoke [+] below to expand items, and [-] to collapse items.
1080 Invoke the [group], [face], and [option] buttons below to edit that 1120 Invoke the [Group], [Face], and [Option] buttons below to edit that
1081 item in another window.\n\n") 1121 item in another window.\n\n")
1082 (let ((custom-buffer-style 'tree)) 1122 (let ((custom-buffer-style 'tree))
1083 (widget-create 'custom-group 1123 (widget-create 'custom-group
1084 :custom-last t 1124 :custom-last t
1085 :custom-state 'unknown 1125 :custom-state 'unknown
1086 :tag (custom-unlispify-tag-name 'emacs) 1126 :tag (custom-unlispify-tag-name group)
1087 :value 'emacs)) 1127 :value group))
1088 (goto-char (point-min))) 1128 (goto-char (point-min)))
1089 1129
1090 (define-widget 'custom-tree-visibility 'item 1130 (define-widget 'custom-tree-visibility 'item
1091 "Control visibility of of items in the customize tree browser." 1131 "Control visibility of of items in the customize tree browser."
1092 :format "%[[%t]%]" 1132 :format "%[[%t]%]"
1096 (let ((custom-buffer-style 'tree)) 1136 (let ((custom-buffer-style 'tree))
1097 (custom-toggle-parent widget))) 1137 (custom-toggle-parent widget)))
1098 1138
1099 (define-widget 'custom-tree-group-tag 'push-button 1139 (define-widget 'custom-tree-group-tag 'push-button
1100 "Show parent in other window when activated." 1140 "Show parent in other window when activated."
1101 :tag "group" 1141 :tag "Group"
1102 :tag-glyph "folder" 1142 :tag-glyph "folder"
1103 :action 'custom-tree-group-tag-action) 1143 :action 'custom-tree-group-tag-action)
1104 1144
1105 (defun custom-tree-group-tag-action (widget &rest ignore) 1145 (defun custom-tree-group-tag-action (widget &rest ignore)
1106 (let ((parent (widget-get widget :parent))) 1146 (let ((parent (widget-get widget :parent)))
1107 (customize-group-other-window (widget-value parent)))) 1147 (customize-group-other-window (widget-value parent))))
1108 1148
1109 (define-widget 'custom-tree-variable-tag 'push-button 1149 (define-widget 'custom-tree-variable-tag 'push-button
1110 "Show parent in other window when activated." 1150 "Show parent in other window when activated."
1111 :tag "option" 1151 :tag "Option"
1112 :tag-glyph "option" 1152 :tag-glyph "option"
1113 :action 'custom-tree-variable-tag-action) 1153 :action 'custom-tree-variable-tag-action)
1114 1154
1115 (defun custom-tree-variable-tag-action (widget &rest ignore) 1155 (defun custom-tree-variable-tag-action (widget &rest ignore)
1116 (let ((parent (widget-get widget :parent))) 1156 (let ((parent (widget-get widget :parent)))
1117 (customize-variable-other-window (widget-value parent)))) 1157 (customize-variable-other-window (widget-value parent))))
1118 1158
1119 (define-widget 'custom-tree-face-tag 'push-button 1159 (define-widget 'custom-tree-face-tag 'push-button
1120 "Show parent in other window when activated." 1160 "Show parent in other window when activated."
1121 :tag "face" 1161 :tag "Face"
1122 :tag-glyph "face" 1162 :tag-glyph "face"
1123 :action 'custom-tree-face-tag-action) 1163 :action 'custom-tree-face-tag-action)
1124 1164
1125 (defun custom-tree-face-tag-action (widget &rest ignore) 1165 (defun custom-tree-face-tag-action (widget &rest ignore)
1126 (let ((parent (widget-get widget :parent))) 1166 (let ((parent (widget-get widget :parent)))
1127 (customize-face-other-window (widget-value parent)))) 1167 (customize-face-other-window (widget-value parent))))
1128 1168
1129 (defconst custom-tree-alist '((" " "space") 1169 (defconst custom-tree-alist '((" " "space")
1130 (" | " "vertical") 1170 (" | " "vertical")
1171 ("-\\ " "top")
1131 (" |-" "middle") 1172 (" |-" "middle")
1132 (" `-" "bottom"))) 1173 (" `-" "bottom")))
1133 1174
1134 (defun custom-tree-insert (prefix) 1175 (defun custom-tree-insert-prefix (prefix)
1135 "Insert PREFIX. On XEmacs convert it to line graphics." 1176 "Insert PREFIX. On XEmacs convert it to line graphics."
1136 (if nil ;(string-match "XEmacs" emacs-version) 1177 (if nil ; (string-match "XEmacs" emacs-version)
1137 (while (not (string-equal prefix "")) 1178 (progn
1138 (let ((entry (substring prefix 0 3))) 1179 (insert "*")
1139 (setq prefix (substring prefix 3)) 1180 (while (not (string-equal prefix ""))
1140 (widget-specify-insert 1181 (let ((entry (substring prefix 0 3)))
1141 (widget-glyph-insert nil entry 1182 (setq prefix (substring prefix 3))
1142 (nth 1 (assoc entry custom-tree-alist)))))) 1183 (let ((overlay (make-overlay (1- (point)) (point) nil t nil))
1184 (name (nth 1 (assoc entry custom-tree-alist))))
1185 (overlay-put overlay 'end-glyph (widget-glyph-find name entry))
1186 (overlay-put overlay 'start-open t)
1187 (overlay-put overlay 'end-open t)))))
1143 (insert prefix))) 1188 (insert prefix)))
1144 1189
1145 ;;; Modification of Basic Widgets. 1190 ;;; Modification of Basic Widgets.
1146 ;; 1191 ;;
1147 ;; We add extra properties to the basic widgets needed here. This is 1192 ;; We add extra properties to the basic widgets needed here. This is
1281 1326
1282 The list should be sorted most significant first.") 1327 The list should be sorted most significant first.")
1283 1328
1284 (defcustom custom-magic-show 'long 1329 (defcustom custom-magic-show 'long
1285 "If non-nil, show textual description of the state. 1330 "If non-nil, show textual description of the state.
1286 If non-nil and not the symbol `long', only show first word." 1331 If `long', show a full-line description, not just one word."
1287 :type '(choice (const :tag "no" nil) 1332 :type '(choice (const :tag "no" nil)
1288 (const short) 1333 (const short)
1289 (const long)) 1334 (const long))
1290 :group 'custom-buffer) 1335 :group 'custom-buffer)
1291 1336
1292 (defcustom custom-magic-show-hidden '(option face) 1337 (defcustom custom-magic-show-hidden '(option face)
1293 "Control whether the state button is shown for hidden items. 1338 "Control whether the State button is shown for hidden items.
1294 The value should be a list with the custom categories where the state 1339 The value should be a list with the custom categories where the State
1295 button should be visible. Possible categories are `group', `option', 1340 button should be visible. Possible categories are `group', `option',
1296 and `face'." 1341 and `face'."
1297 :type '(set (const group) (const option) (const face)) 1342 :type '(set (const group) (const option) (const face))
1298 :group 'custom-buffer) 1343 :group 'custom-buffer)
1299 1344
1300 (defcustom custom-magic-show-button nil 1345 (defcustom custom-magic-show-button nil
1301 "Show a magic button indicating the state of each customization option." 1346 "Show a \"magic\" button indicating the state of each customization option."
1302 :type 'boolean 1347 :type 'boolean
1303 :group 'custom-buffer) 1348 :group 'custom-buffer)
1304 1349
1305 (define-widget 'custom-magic 'default 1350 (define-widget 'custom-magic 'default
1306 "Show and manipulate state for a customization option." 1351 "Show and manipulate state for a customization option."
1337 (match-string 2 text)))) 1382 (match-string 2 text))))
1338 (when (and custom-magic-show 1383 (when (and custom-magic-show
1339 (or (not hidden) 1384 (or (not hidden)
1340 (memq category custom-magic-show-hidden))) 1385 (memq category custom-magic-show-hidden)))
1341 (insert " ") 1386 (insert " ")
1342 (when (eq category 'group) 1387 (when (and (eq category 'group)
1388 (not (and (eq custom-buffer-style 'links)
1389 (> (widget-get parent :custom-level) 1))))
1343 (insert-char ?\ (* custom-buffer-indent 1390 (insert-char ?\ (* custom-buffer-indent
1344 (widget-get parent :custom-level)))) 1391 (widget-get parent :custom-level))))
1345 (push (widget-create-child-and-convert 1392 (push (widget-create-child-and-convert
1346 widget 'choice-item 1393 widget 'choice-item
1347 :help-echo "Change the state of this item." 1394 :help-echo "Change the state of this item."
1350 :button-suffix 'widget-push-button-suffix 1397 :button-suffix 'widget-push-button-suffix
1351 :mouse-down-action 'widget-magic-mouse-down-action 1398 :mouse-down-action 'widget-magic-mouse-down-action
1352 :tag "State") 1399 :tag "State")
1353 children) 1400 children)
1354 (insert ": ") 1401 (insert ": ")
1355 (if (eq custom-magic-show 'long) 1402 (let ((start (point)))
1356 (insert text) 1403 (if (eq custom-magic-show 'long)
1357 (insert (symbol-name state))) 1404 (insert text)
1358 (when lisp 1405 (insert (symbol-name state)))
1359 (insert " (lisp)")) 1406 (when lisp
1407 (insert " (lisp)"))
1408 (put-text-property start (point) 'face 'custom-state-face))
1360 (insert "\n")) 1409 (insert "\n"))
1361 (when (eq category 'group) 1410 (when (and (eq category 'group)
1411 (not (and (eq custom-buffer-style 'links)
1412 (> (widget-get parent :custom-level) 1))))
1362 (insert-char ?\ (* custom-buffer-indent 1413 (insert-char ?\ (* custom-buffer-indent
1363 (widget-get parent :custom-level)))) 1414 (widget-get parent :custom-level))))
1364 (when custom-magic-show-button 1415 (when custom-magic-show-button
1365 (when custom-magic-show 1416 (when custom-magic-show
1366 (let ((indent (widget-get parent :indent))) 1417 (let ((indent (widget-get parent :indent)))
1386 (let ((magic (widget-get widget :custom-magic))) 1437 (let ((magic (widget-get widget :custom-magic)))
1387 (widget-value-set magic (widget-value magic)))) 1438 (widget-value-set magic (widget-value magic))))
1388 1439
1389 ;;; The `custom' Widget. 1440 ;;; The `custom' Widget.
1390 1441
1442 (defface custom-button-face nil
1443 "Face used for buttons in customization buffers."
1444 :group 'custom-faces)
1445
1446 (defface custom-documentation-face nil
1447 "Face used for documentation strings in customization buffers."
1448 :group 'custom-faces)
1449
1450 (defface custom-state-face '((((class color)
1451 (background dark))
1452 (:foreground "lime green"))
1453 (((class color)
1454 (background light))
1455 (:foreground "dark green"))
1456 (t nil))
1457 "Face used for State descriptions in the customize buffer."
1458 :group 'custom-faces)
1459
1391 (define-widget 'custom 'default 1460 (define-widget 'custom 'default
1392 "Customize a user option." 1461 "Customize a user option."
1393 :format "%v" 1462 :format "%v"
1394 :convert-widget 'custom-convert-widget 1463 :convert-widget 'custom-convert-widget
1395 :notify 'custom-notify 1464 :notify 'custom-notify
1399 :documentation-property 'widget-subclass-responsibility 1468 :documentation-property 'widget-subclass-responsibility
1400 :value-create 'widget-subclass-responsibility 1469 :value-create 'widget-subclass-responsibility
1401 :value-delete 'widget-children-value-delete 1470 :value-delete 'widget-children-value-delete
1402 :value-get 'widget-value-value-get 1471 :value-get 'widget-value-value-get
1403 :validate 'widget-children-validate 1472 :validate 'widget-children-validate
1473 :button-face 'custom-button-face
1404 :match (lambda (widget value) (symbolp value))) 1474 :match (lambda (widget value) (symbolp value)))
1405 1475
1406 (defun custom-convert-widget (widget) 1476 (defun custom-convert-widget (widget)
1407 ;; Initialize :value and :tag from :args in WIDGET. 1477 ;; Initialize :value and :tag from :args in WIDGET.
1408 (let ((args (widget-get widget :args))) 1478 (let ((args (widget-get widget :args)))
1507 (widget-put widget :custom-state 'hidden))) 1577 (widget-put widget :custom-state 'hidden)))
1508 (custom-redraw widget) 1578 (custom-redraw widget)
1509 (widget-setup))) 1579 (widget-setup)))
1510 1580
1511 (defun custom-toggle-parent (widget &rest ignore) 1581 (defun custom-toggle-parent (widget &rest ignore)
1512 "Toggle visibility of parent to WIDGET." 1582 "Toggle visibility of parent of WIDGET."
1513 (custom-toggle-hide (widget-get widget :parent))) 1583 (custom-toggle-hide (widget-get widget :parent)))
1514 1584
1515 (defun custom-add-see-also (widget &optional prefix) 1585 (defun custom-add-see-also (widget &optional prefix)
1516 "Add `See also ...' to WIDGET if there are any links. 1586 "Add `See also ...' to WIDGET if there are any links.
1517 Insert PREFIX first if non-nil." 1587 Insert PREFIX first if non-nil."
1538 (insert " and "))) 1608 (insert " and ")))
1539 (t 1609 (t
1540 (insert ", ")))) 1610 (insert ", "))))
1541 (widget-put widget :buttons buttons)))) 1611 (widget-put widget :buttons buttons))))
1542 1612
1543 (defun custom-add-parent-links (widget) 1613 (defun custom-add-parent-links (widget &optional initial-string)
1544 "Add `Parent groups: ...' to WIDGET." 1614 "Add \"Parent groups: ...\" to WIDGET if the group has parents.
1615 The value if non-nil if any parents were found.
1616 If INITIAL-STRING is non-nil, use that rather than \"Parent groups:\"."
1545 (let ((name (widget-value widget)) 1617 (let ((name (widget-value widget))
1546 (type (widget-type widget)) 1618 (type (widget-type widget))
1547 (buttons (widget-get widget :buttons)) 1619 (buttons (widget-get widget :buttons))
1620 (start (point))
1548 found) 1621 found)
1549 (insert "Parent groups:") 1622 (insert (or initial-string "Parent groups:"))
1550 (mapatoms (lambda (symbol) 1623 (mapatoms (lambda (symbol)
1551 (let ((group (get symbol 'custom-group))) 1624 (let ((entry (assq name (get symbol 'custom-group))))
1552 (when (assq name group) 1625 (when (eq (nth 1 entry) type)
1553 (when (eq type (nth 1 (assq name group))) 1626 (insert " ")
1554 (insert " ") 1627 (push (widget-create-child-and-convert
1555 (push (widget-create-child-and-convert 1628 widget 'custom-group-link
1556 widget 'custom-group-link 1629 :tag (custom-unlispify-tag-name symbol)
1557 :tag (custom-unlispify-tag-name symbol) 1630 symbol)
1558 symbol) 1631 buttons)
1559 buttons) 1632 (setq found t)))))
1560 (setq found t))))))
1561 (widget-put widget :buttons buttons) 1633 (widget-put widget :buttons buttons)
1562 (unless found 1634 (if found
1563 (insert " (none)")) 1635 (insert "\n")
1564 (insert "\n"))) 1636 (delete-region start (point)))
1637 found))
1565 1638
1566 ;;; The `custom-variable' Widget. 1639 ;;; The `custom-variable' Widget.
1567 1640
1568 (defface custom-variable-sample-face '((t (:underline t))) 1641 (defface custom-variable-tag-face '((((class color)
1642 (background dark))
1643 (:foreground "light blue" :underline t))
1644 (((class color)
1645 (background light))
1646 (:foreground "blue" :underline t))
1647 (t (:underline t)))
1569 "Face used for unpushable variable tags." 1648 "Face used for unpushable variable tags."
1570 :group 'custom-faces) 1649 :group 'custom-faces)
1571 1650
1572 (defface custom-variable-button-face '((t (:underline t :bold t))) 1651 (defface custom-variable-button-face '((t (:underline t :bold t)))
1573 "Face used for pushable variable tags." 1652 "Face used for pushable variable tags."
1645 ((eq state 'hidden) 1724 ((eq state 'hidden)
1646 ;; Indicate hidden value. 1725 ;; Indicate hidden value.
1647 (push (widget-create-child-and-convert 1726 (push (widget-create-child-and-convert
1648 widget 'item 1727 widget 'item
1649 :format "%{%t%}: " 1728 :format "%{%t%}: "
1650 :sample-face 'custom-variable-sample-face 1729 :sample-face 'custom-variable-tag-face
1651 :tag tag 1730 :tag tag
1652 :parent widget) 1731 :parent widget)
1653 buttons) 1732 buttons)
1654 (push (widget-create-child-and-convert 1733 (push (widget-create-child-and-convert
1655 widget 'visibility 1734 widget 'visibility
1696 :format tag-format 1775 :format tag-format
1697 :action 'custom-tag-action 1776 :action 'custom-tag-action
1698 :help-echo "Change value of this option." 1777 :help-echo "Change value of this option."
1699 :mouse-down-action 'custom-tag-mouse-down-action 1778 :mouse-down-action 'custom-tag-mouse-down-action
1700 :button-face 'custom-variable-button-face 1779 :button-face 'custom-variable-button-face
1701 :sample-face 'custom-variable-sample-face 1780 :sample-face 'custom-variable-tag-face
1702 tag) 1781 tag)
1703 buttons) 1782 buttons)
1704 (insert " ") 1783 (insert " ")
1705 (push (widget-create-child-and-convert 1784 (push (widget-create-child-and-convert
1706 widget 'visibility 1785 widget 'visibility
2346 2425
2347 ;;; The `custom-group-link' Widget. 2426 ;;; The `custom-group-link' Widget.
2348 2427
2349 (define-widget 'custom-group-link 'link 2428 (define-widget 'custom-group-link 'link
2350 "Show parent in other window when activated." 2429 "Show parent in other window when activated."
2351 :help-echo "Create customize buffer for this group group." 2430 :help-echo "Create customization buffer for this group."
2352 :action 'custom-group-link-action) 2431 :action 'custom-group-link-action)
2353 2432
2354 (defun custom-group-link-action (widget &rest ignore) 2433 (defun custom-group-link-action (widget &rest ignore)
2355 (customize-group (widget-value widget))) 2434 (customize-group (widget-value widget)))
2356 2435
2357 ;;; The `custom-group' Widget. 2436 ;;; The `custom-group' Widget.
2358 2437
2359 (defcustom custom-group-tag-faces '(custom-group-tag-face-1) 2438 (defcustom custom-group-tag-faces nil
2360 ;; In XEmacs, this ought to play games with font size. 2439 ;; In XEmacs, this ought to play games with font size.
2361 "Face used for group tags. 2440 "Face used for group tags.
2362 The first member is used for level 1 groups, the second for level 2, 2441 The first member is used for level 1 groups, the second for level 2,
2363 and so forth. The remaining group tags are shown with 2442 and so forth. The remaining group tags are shown with
2364 `custom-group-tag-face'." 2443 `custom-group-tag-face'."
2403 (defun custom-group-sample-face-get (widget) 2482 (defun custom-group-sample-face-get (widget)
2404 ;; Use :sample-face. 2483 ;; Use :sample-face.
2405 (or (nth (1- (widget-get widget :custom-level)) custom-group-tag-faces) 2484 (or (nth (1- (widget-get widget :custom-level)) custom-group-tag-faces)
2406 'custom-group-tag-face)) 2485 'custom-group-tag-face))
2407 2486
2487 (define-widget 'custom-group-visibility 'visibility
2488 "An indicator and manipulator for hidden group contents."
2489 :create 'custom-group-visibility-create)
2490
2491 (defun custom-group-visibility-create (widget)
2492 (let ((visible (widget-value widget)))
2493 (if visible
2494 (insert "--------")))
2495 (widget-default-create widget))
2496
2408 (defun custom-group-value-create (widget) 2497 (defun custom-group-value-create (widget)
2409 "Insert a customize group for WIDGET in the current buffer." 2498 "Insert a customize group for WIDGET in the current buffer."
2410 (let ((state (widget-get widget :custom-state)) 2499 (let ((state (widget-get widget :custom-state))
2411 (level (widget-get widget :custom-level)) 2500 (level (widget-get widget :custom-level))
2412 (indent (widget-get widget :indent)) 2501 (indent (widget-get widget :indent))
2414 (buttons (widget-get widget :buttons)) 2503 (buttons (widget-get widget :buttons))
2415 (tag (widget-get widget :tag)) 2504 (tag (widget-get widget :tag))
2416 (symbol (widget-value widget))) 2505 (symbol (widget-value widget)))
2417 (cond ((and (eq custom-buffer-style 'tree) 2506 (cond ((and (eq custom-buffer-style 'tree)
2418 (eq state 'hidden)) 2507 (eq state 'hidden))
2419 (custom-tree-insert prefix) 2508 (custom-tree-insert-prefix prefix)
2420 (push (widget-create-child-and-convert 2509 (push (widget-create-child-and-convert
2421 widget 'custom-tree-visibility 2510 widget 'custom-tree-visibility
2422 ;; :tag-glyph "plus" 2511 ;; :tag-glyph "plus"
2423 :tag "+") 2512 :tag "+")
2424 buttons) 2513 buttons)
2429 buttons) 2518 buttons)
2430 (insert " " tag "\n") 2519 (insert " " tag "\n")
2431 (widget-put widget :buttons buttons)) 2520 (widget-put widget :buttons buttons))
2432 ((and (eq custom-buffer-style 'tree) 2521 ((and (eq custom-buffer-style 'tree)
2433 (zerop (length (get symbol 'custom-group)))) 2522 (zerop (length (get symbol 'custom-group))))
2434 (custom-tree-insert prefix) 2523 (custom-tree-insert-prefix prefix)
2435 (insert "[ ]-- ") 2524 (insert "[ ]-- ")
2436 ;; (widget-glyph-insert nil "[ ]" "empty") 2525 ;; (widget-glyph-insert nil "[ ]" "empty")
2437 ;; (widget-glyph-insert nil "-- " "horizontal") 2526 ;; (widget-glyph-insert nil "-- " "horizontal")
2438 (push (widget-create-child-and-convert 2527 (push (widget-create-child-and-convert
2439 widget 'custom-tree-group-tag) 2528 widget 'custom-tree-group-tag)
2440 buttons) 2529 buttons)
2441 (insert " " tag "\n") 2530 (insert " " tag "\n")
2442 (widget-put widget :buttons buttons)) 2531 (widget-put widget :buttons buttons))
2443 ((eq custom-buffer-style 'tree) 2532 ((eq custom-buffer-style 'tree)
2444 (custom-tree-insert prefix) 2533 (custom-tree-insert-prefix prefix)
2445 (custom-load-widget widget) 2534 (custom-load-widget widget)
2446 (if (zerop (length (get symbol 'custom-group))) 2535 (if (zerop (length (get symbol 'custom-group)))
2447 (progn 2536 (progn
2448 (custom-tree-insert prefix) 2537 (custom-tree-insert-prefix prefix)
2449 (insert "[ ]-- ") 2538 (insert "[ ]-- ")
2450 ;; (widget-glyph-insert nil "[ ]" "empty") 2539 ;; (widget-glyph-insert nil "[ ]" "empty")
2451 ;; (widget-glyph-insert nil "-- " "horizontal") 2540 ;; (widget-glyph-insert nil "-- " "horizontal")
2452 (push (widget-create-child-and-convert 2541 (push (widget-create-child-and-convert
2453 widget 'custom-tree-group-tag) 2542 widget 'custom-tree-group-tag)
2457 (push (widget-create-child-and-convert 2546 (push (widget-create-child-and-convert
2458 widget 'custom-tree-visibility 2547 widget 'custom-tree-visibility
2459 ;; :tag-glyph "minus" 2548 ;; :tag-glyph "minus"
2460 :tag "-") 2549 :tag "-")
2461 buttons) 2550 buttons)
2462 (insert "-+ ") 2551 (insert "-\\ ")
2463 ;; (widget-glyph-insert nil "-+ " "top") 2552 ;; (widget-glyph-insert nil "-\\ " "top")
2464 (push (widget-create-child-and-convert 2553 (push (widget-create-child-and-convert
2465 widget 'custom-tree-group-tag) 2554 widget 'custom-tree-group-tag)
2466 buttons) 2555 buttons)
2467 (insert " " tag "\n") 2556 (insert " " tag "\n")
2468 (widget-put widget :buttons buttons) 2557 (widget-put widget :buttons buttons)
2469 (message "Creating group...") 2558 (message "Creating group...")
2470 (let* ((members (sort (copy-sequence (get symbol 'custom-group)) 2559 (let* ((members (custom-sort-items (get symbol 'custom-group)
2471 'custom-browse-sort-predicate)) 2560 custom-browse-sort-alphabetically
2561 custom-browse-order-groups))
2472 (prefixes (widget-get widget :custom-prefixes)) 2562 (prefixes (widget-get widget :custom-prefixes))
2473 (custom-prefix-list (custom-prefix-add symbol prefixes)) 2563 (custom-prefix-list (custom-prefix-add symbol prefixes))
2474 (length (length members)) 2564 (length (length members))
2475 (extra-prefix (if (widget-get widget :custom-last) 2565 (extra-prefix (if (widget-get widget :custom-last)
2476 " " 2566 " "
2494 (widget-put widget :children (reverse children))) 2584 (widget-put widget :children (reverse children)))
2495 (message "Creating group...done"))) 2585 (message "Creating group...done")))
2496 ;; Nested style. 2586 ;; Nested style.
2497 ((eq state 'hidden) 2587 ((eq state 'hidden)
2498 ;; Create level indicator. 2588 ;; Create level indicator.
2499 (insert-char ?\ (* custom-buffer-indent (1- level))) 2589 (unless (eq custom-buffer-style 'links)
2500 (insert "-- ") 2590 (insert-char ?\ (* custom-buffer-indent (1- level)))
2591 (insert "-- "))
2501 ;; Create tag. 2592 ;; Create tag.
2502 (let ((begin (point))) 2593 (let ((begin (point)))
2503 (insert tag) 2594 (insert tag)
2504 (widget-specify-sample widget begin (point))) 2595 (widget-specify-sample widget begin (point)))
2505 (insert " group: ") 2596 (insert " group: ")
2506 ;; Create link/visibility indicator. 2597 ;; Create link/visibility indicator.
2507 (if (eq custom-buffer-style 'links) 2598 (if (eq custom-buffer-style 'links)
2508 (push (widget-create-child-and-convert 2599 (push (widget-create-child-and-convert
2509 widget 'custom-group-link 2600 widget 'custom-group-link
2510 :tag "Show" 2601 :tag "Go to Group"
2511 symbol) 2602 symbol)
2512 buttons) 2603 buttons)
2513 (push (widget-create-child-and-convert 2604 (push (widget-create-child-and-convert
2514 widget 'visibility 2605 widget 'group-visibility
2515 :help-echo "Show members of this group." 2606 :help-echo "Show members of this group."
2516 :action 'custom-toggle-parent 2607 :action 'custom-toggle-parent
2517 (not (eq state 'hidden))) 2608 (not (eq state 'hidden)))
2518 buttons)) 2609 buttons))
2519 (insert " \n") 2610 (insert " \n")
2523 (widget-put widget :custom-magic magic) 2614 (widget-put widget :custom-magic magic)
2524 (push magic buttons)) 2615 (push magic buttons))
2525 ;; Update buttons. 2616 ;; Update buttons.
2526 (widget-put widget :buttons buttons) 2617 (widget-put widget :buttons buttons)
2527 ;; Insert documentation. 2618 ;; Insert documentation.
2619 (if (and (eq custom-buffer-style 'links) (> level 1))
2620 (widget-put widget :documentation-indent 0))
2528 (widget-default-format-handler widget ?h)) 2621 (widget-default-format-handler widget ?h))
2529 ;; Nested style. 2622 ;; Nested style.
2530 (t ;Visible. 2623 (t ;Visible.
2624 ;; Add parent groups references above the group.
2625 (if t ;;; This should test that the buffer
2626 ;;; was made to display a group.
2627 (when (eq level 1)
2628 (if (custom-add-parent-links widget
2629 "Go to parent group:")
2630 (insert "\n"))))
2531 ;; Create level indicator. 2631 ;; Create level indicator.
2532 (insert-char ?\ (* custom-buffer-indent (1- level))) 2632 (insert-char ?\ (* custom-buffer-indent (1- level)))
2533 (insert "/- ") 2633 (insert "/- ")
2534 ;; Create tag. 2634 ;; Create tag.
2535 (let ((start (point))) 2635 (let ((start (point)))
2561 (push magic buttons)) 2661 (push magic buttons))
2562 ;; Update buttons. 2662 ;; Update buttons.
2563 (widget-put widget :buttons buttons) 2663 (widget-put widget :buttons buttons)
2564 ;; Insert documentation. 2664 ;; Insert documentation.
2565 (widget-default-format-handler widget ?h) 2665 (widget-default-format-handler widget ?h)
2566 ;; Parents and See also. 2666 ;; Parent groups.
2567 (when (eq level 1) 2667 (if nil ;;; This should test that the buffer
2568 (insert-char ?\ custom-buffer-indent) 2668 ;;; was not made to display a group.
2569 (custom-add-parent-links widget)) 2669 (when (eq level 1)
2670 (insert-char ?\ custom-buffer-indent)
2671 (custom-add-parent-links widget)))
2570 (custom-add-see-also widget 2672 (custom-add-see-also widget
2571 (make-string (* custom-buffer-indent level) 2673 (make-string (* custom-buffer-indent level)
2572 ?\ )) 2674 ?\ ))
2573 ;; Members. 2675 ;; Members.
2574 (message "Creating group...") 2676 (message "Creating group...")
2575 (custom-load-widget widget) 2677 (custom-load-widget widget)
2576 (let* ((members (sort (copy-sequence (get symbol 'custom-group)) 2678 (let* ((members (custom-sort-items (get symbol 'custom-group)
2577 'custom-buffer-sort-predicate)) 2679 custom-buffer-sort-alphabetically
2680 custom-buffer-order-groups))
2578 (prefixes (widget-get widget :custom-prefixes)) 2681 (prefixes (widget-get widget :custom-prefixes))
2579 (custom-prefix-list (custom-prefix-add symbol prefixes)) 2682 (custom-prefix-list (custom-prefix-add symbol prefixes))
2580 (length (length members)) 2683 (length (length members))
2581 (count 0) 2684 (count 0)
2582 (children (mapcar (lambda (entry) 2685 (children (mapcar (lambda (entry)
2805 (princ ")") 2908 (princ ")")
2806 (unless (looking-at "\n") 2909 (unless (looking-at "\n")
2807 (princ "\n"))))) 2910 (princ "\n")))))
2808 2911
2809 ;;;###autoload 2912 ;;;###autoload
2810 (defun custom-save-customized () 2913 (defun customize-save-customized ()
2811 "Save all user options which have been set in this session." 2914 "Save all user options which have been set in this session."
2812 (interactive) 2915 (interactive)
2813 (mapatoms (lambda (symbol) 2916 (mapatoms (lambda (symbol)
2814 (let ((face (get symbol 'customized-face)) 2917 (let ((face (get symbol 'customized-face))
2815 (value (get symbol 'customized-value))) 2918 (value (get symbol 'customized-value)))
2836 ;;; Menu support 2939 ;;; Menu support
2837 2940
2838 (unless (string-match "XEmacs" emacs-version) 2941 (unless (string-match "XEmacs" emacs-version)
2839 (defconst custom-help-menu 2942 (defconst custom-help-menu
2840 '("Customize" 2943 '("Customize"
2841 ["Update menu..." custom-menu-update t] 2944 ["Update menu..." Custom-menu-update t]
2945 ["Browse..." (customize-browse 'emacs) t]
2842 ["Group..." customize-group t] 2946 ["Group..." customize-group t]
2843 ["Variable..." customize-variable t] 2947 ["Variable..." customize-variable t]
2844 ["Face..." customize-face t] 2948 ["Face..." customize-face t]
2845 ["Saved..." customize-saved t] 2949 ["Saved..." customize-saved t]
2846 ["Set..." customize-customized t] 2950 ["Set..." customize-customized t]
2858 (define-key global-map [menu-bar help-menu customize-menu] 2962 (define-key global-map [menu-bar help-menu customize-menu]
2859 (cons (car custom-help-menu) 2963 (cons (car custom-help-menu)
2860 (easy-menu-create-keymaps (car custom-help-menu) 2964 (easy-menu-create-keymaps (car custom-help-menu)
2861 (cdr custom-help-menu))))) 2965 (cdr custom-help-menu)))))
2862 2966
2863 (defun custom-menu-update (event) 2967 (defun Custom-menu-update (event)
2864 "Update customize menu." 2968 "Update customize menu."
2865 (interactive "e") 2969 (interactive "e")
2866 (add-hook 'custom-define-hook 'custom-menu-reset) 2970 (add-hook 'custom-define-hook 'custom-menu-reset)
2867 (let* ((emacs (widget-apply '(custom-group) :custom-menu 'emacs)) 2971 (let* ((emacs (widget-apply '(custom-group) :custom-menu 'emacs))
2868 (menu `(,(car custom-help-menu) 2972 (menu `(,(car custom-help-menu)
2926 (if (and (or (not (boundp 'custom-menu-nesting)) 3030 (if (and (or (not (boundp 'custom-menu-nesting))
2927 (>= custom-menu-nesting 0)) 3031 (>= custom-menu-nesting 0))
2928 (< (length (get symbol 'custom-group)) widget-menu-max-size)) 3032 (< (length (get symbol 'custom-group)) widget-menu-max-size))
2929 (let ((custom-prefix-list (custom-prefix-add symbol 3033 (let ((custom-prefix-list (custom-prefix-add symbol
2930 custom-prefix-list)) 3034 custom-prefix-list))
2931 (members (sort (copy-sequence (get symbol 'custom-group)) 3035 (members (custom-sort-items (get symbol 'custom-group)
2932 'custom-menu-sort-predicate))) 3036 custom-menu-sort-alphabetically
3037 custom-menu-order-groups)))
2933 (custom-load-symbol symbol) 3038 (custom-load-symbol symbol)
2934 `(,(custom-unlispify-menu-entry symbol t) 3039 `(,(custom-unlispify-menu-entry symbol t)
2935 ,item 3040 ,item
2936 "--" 3041 "--"
2937 ,@(mapcar (lambda (entry) 3042 ,@(mapcar (lambda (entry)
2960 3065
2961 ;;; The Custom Mode. 3066 ;;; The Custom Mode.
2962 3067
2963 (defvar custom-mode-map nil 3068 (defvar custom-mode-map nil
2964 "Keymap for `custom-mode'.") 3069 "Keymap for `custom-mode'.")
2965 3070
2966 (unless custom-mode-map 3071 (unless custom-mode-map
2967 (setq custom-mode-map (make-sparse-keymap)) 3072 (setq custom-mode-map (make-sparse-keymap))
2968 (set-keymap-parent custom-mode-map widget-keymap) 3073 (set-keymap-parent custom-mode-map widget-keymap)
2969 (suppress-keymap custom-mode-map) 3074 (suppress-keymap custom-mode-map)
2970 (define-key custom-mode-map "q" 'bury-buffer)) 3075 (define-key custom-mode-map " " 'scroll-up)
2971 3076 (define-key custom-mode-map "\177" 'scroll-down)
2972 (easy-menu-define custom-mode-menu 3077 (define-key custom-mode-map "q" 'bury-buffer)
3078 (define-key custom-mode-map "u" 'Custom-goto-parent))
3079
3080 (easy-menu-define Custom-mode-menu
2973 custom-mode-map 3081 custom-mode-map
2974 "Menu used in customization buffers." 3082 "Menu used in customization buffers."
2975 `("Custom" 3083 `("Custom"
2976 ,(customize-menu-create 'customize) 3084 ,(customize-menu-create 'customize)
2977 ["Set" custom-set t] 3085 ["Set" Custom-set t]
2978 ["Save" custom-save t] 3086 ["Save" Custom-save t]
2979 ["Reset to Current" custom-reset-current t] 3087 ["Reset to Current" Custom-reset-current t]
2980 ["Reset to Saved" custom-reset-saved t] 3088 ["Reset to Saved" Custom-reset-saved t]
2981 ["Reset to Standard Settings" custom-reset-standard t] 3089 ["Reset to Standard Settings" Custom-reset-standard t]
2982 ["Info" (Info-goto-node "(custom)The Customization Buffer") t])) 3090 ["Info" (Info-goto-node "(custom)The Customization Buffer") t]))
3091
3092 (defun Custom-goto-parent ()
3093 "Go to the parent group listed at the top of this buffer.
3094 If several parents are listed, go to the first of them."
3095 (interactive)
3096 (save-excursion
3097 (goto-char (point-min))
3098 (if (search-forward "\nGo to parent group: " nil t)
3099 (let* ((button (get-char-property (point) 'button))
3100 (parent (downcase (widget-get button :tag))))
3101 (customize-group parent)))))
2983 3102
2984 (defcustom custom-mode-hook nil 3103 (defcustom custom-mode-hook nil
2985 "Hook called when entering custom-mode." 3104 "Hook called when entering custom-mode."
2986 :type 'hook 3105 :type 'hook
2987 :group 'custom-buffer ) 3106 :group 'custom-buffer )
2988 3107
3108 (defun custom-state-buffer-message (widget)
3109 (if (eq (widget-get (widget-get widget :parent) :custom-state) 'modified)
3110 (message "To install your edits, invoke [State] and choose the Set operation")))
3111
2989 (defun custom-mode () 3112 (defun custom-mode ()
2990 "Major mode for editing customization buffers. 3113 "Major mode for editing customization buffers.
2991 3114
2992 The following commands are available: 3115 The following commands are available:
2993 3116
2994 Move to next button or editable field. \\[widget-forward] 3117 Move to next button or editable field. \\[widget-forward]
2995 Move to previous button or editable field. \\[widget-backward] 3118 Move to previous button or editable field. \\[widget-backward]
2996 Invoke button under the mouse pointer. \\[widget-button-click] 3119 Invoke button under the mouse pointer. \\[widget-button-click]
2997 Invoke button under point. \\[widget-button-press] 3120 Invoke button under point. \\[widget-button-press]
2998 Set all modifications. \\[custom-set] 3121 Set all modifications. \\[Custom-set]
2999 Make all modifications default. \\[custom-save] 3122 Make all modifications default. \\[Custom-save]
3000 Reset all modified options. \\[custom-reset-current] 3123 Reset all modified options. \\[Custom-reset-current]
3001 Reset all modified or set options. \\[custom-reset-saved] 3124 Reset all modified or set options. \\[Custom-reset-saved]
3002 Reset all options. \\[custom-reset-standard] 3125 Reset all options. \\[Custom-reset-standard]
3003 3126
3004 Entry to this mode calls the value of `custom-mode-hook' 3127 Entry to this mode calls the value of `custom-mode-hook'
3005 if that value is non-nil." 3128 if that value is non-nil."
3006 (kill-all-local-variables) 3129 (kill-all-local-variables)
3007 (setq major-mode 'custom-mode 3130 (setq major-mode 'custom-mode
3008 mode-name "Custom") 3131 mode-name "Custom")
3009 (use-local-map custom-mode-map) 3132 (use-local-map custom-mode-map)
3010 (easy-menu-add custom-mode-menu) 3133 (easy-menu-add Custom-mode-menu)
3011 (make-local-variable 'custom-options) 3134 (make-local-variable 'custom-options)
3135 (make-local-variable 'widget-documentation-face)
3136 (setq widget-documentation-face 'custom-documentation-face)
3137 (make-local-hook 'widget-edit-functions)
3138 (add-hook 'widget-edit-functions 'custom-state-buffer-message nil t)
3012 (run-hooks 'custom-mode-hook)) 3139 (run-hooks 'custom-mode-hook))
3013 3140
3014 ;;; The End. 3141 ;;; The End.
3015 3142
3016 (provide 'cus-edit) 3143 (provide 'cus-edit)