comparison lisp/cus-edit.el @ 25685:fc2bfab28ed7

Don't define-widget-keywords. (multimedia): New group. (custom-last): Function removed. (custom-quote): Add vectorp case, comment out characterp case. (custom-buffer-done-function, custom-raised-buttons): New option. (Custom-buffer-done): New function. (custom-buffer-create-internal): Obey custom-raised-buttons, Custom-buffer-done. (custom-button-face): Make it `released-button'. (custom-button-pressed-face): Make it `pressed-button' (custom-mode-map): Bind "q" to Custom-buffer-done. (custom-mode): Deal with raised/pressed buttons. Changes from Didier Verna: (custom-prompt-variable): Optional third arg makes prompt for a comment string. (customize-set-value, customize-set-variable, customize-save-variable): Optional prefix makes function handle variable comments. (customize-customized, customize-saved, custom-variable-state-set) (custom-variable-set, custom-variable-save, custom-face-state-set) (custom-variable-reset-saved, custom-variable-reset-standard) (custom-face-set, custom-face-save, custom-face-reset-saved) (custom-face-reset-standard, customize-save-customized): Handle custom comments. (custom-comment-face, custom-comment-tag-face): New face. (custom-comment): New widget. (custom-comment-create, custom-comment-delete) (custom-comment-value-set, custom-comment-show) ()custom-comment-invisible-p): New functions. (custom-variable-value-create, custom-face-value-create): Create a comment field widget. (custom-variable-menu, custom-face-menu): New entry for custom comment. (custom-face-value-create): Remove compatibility code. (custom-save-variables, custom-save-faces): Possibly save custom comments.
author Dave Love <fx@gnu.org>
date Mon, 13 Sep 1999 13:44:41 +0000
parents d6081fb56cda
children 0d1ba90ad774
comparison
equal deleted inserted replaced
25684:e3ed0e86532c 25685:fc2bfab28ed7
1 ;;; cus-edit.el --- Tools for customizating Emacs and Lisp packages. 1 ;;; cus-edit.el --- Tools for customizating Emacs and Lisp packages.
2 ;; 2 ;;
3 ;; Copyright (C) 1996, 1997 Free Software Foundation, Inc. 3 ;; Copyright (C) 1996, 1997, 1999 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.9954 7 ;; X-URL: http://www.dina.kvl.dk/~abraham/custom/ (probably obsolete)
8 ;; X-URL: http://www.dina.kvl.dk/~abraham/custom/
9 8
10 ;; This file is part of GNU Emacs. 9 ;; This file is part of GNU Emacs.
11 10
12 ;; GNU Emacs is free software; you can redistribute it and/or modify 11 ;; GNU Emacs is free software; you can redistribute it and/or modify
13 ;; it under the terms of the GNU General Public License as published by 12 ;; it under the terms of the GNU General Public License as published by
47 46
48 (condition-case nil 47 (condition-case nil
49 (require 'cus-start) 48 (require 'cus-start)
50 (error nil)) 49 (error nil))
51 50
52 (define-widget-keywords :custom-last :custom-prefix :custom-category
53 :custom-prefixes :custom-menu
54 :custom-show
55 :custom-magic :custom-state :custom-level :custom-form
56 :custom-set :custom-save :custom-reset-current :custom-reset-saved
57 :custom-reset-standard)
58
59 (put 'custom-define-hook 'custom-type 'hook) 51 (put 'custom-define-hook 'custom-type 'hook)
60 (put 'custom-define-hook 'standard-value '(nil)) 52 (put 'custom-define-hook 'standard-value '(nil))
61 (custom-add-to-group 'customize 'custom-define-hook 'custom-variable) 53 (custom-add-to-group 'customize 'custom-define-hook 'custom-variable)
62 54
63 ;;; Customization Groups. 55 ;;; Customization Groups.
240 232
241 (defgroup help nil 233 (defgroup help nil
242 "Support for on-line help systems." 234 "Support for on-line help systems."
243 :group 'emacs) 235 :group 'emacs)
244 236
237 (defgroup multimedia nil
238 "Non-textual support, specifically images and sound."
239 :group 'emacs)
240
245 (defgroup local nil 241 (defgroup local nil
246 "Code local to your site." 242 "Code local to your site."
247 :group 'emacs) 243 :group 'emacs)
248 244
249 (defgroup customize '((widgets custom-group)) 245 (defgroup customize '((widgets custom-group))
250 "Customization of the Customization support." 246 "Customization of the Customization support."
251 :link '(custom-manual "(elisp)Customization") 247 :link '(custom-manual "(elisp)Customization")
252 :link '(url-link :tag "Development Page" 248 :link '(url-link :tag "(Old?) Development Page"
253 "http://www.dina.kvl.dk/~abraham/custom/") 249 "http://www.dina.kvl.dk/~abraham/custom/")
254 :prefix "custom-" 250 :prefix "custom-"
255 :group 'help) 251 :group 'help)
256 252
257 (defgroup custom-faces nil 253 (defgroup custom-faces nil
354 (defgroup windows nil 350 (defgroup windows nil
355 "Windows within a frame." 351 "Windows within a frame."
356 :group 'environment) 352 :group 'environment)
357 353
358 ;;; Utilities. 354 ;;; Utilities.
359
360 (defun custom-last (x &optional n)
361 ;; Stolen from `cl.el'.
362 "Returns the last link in the list LIST.
363 With optional argument N, returns Nth-to-last link (default 1)."
364 (if n
365 (let ((m 0) (p x))
366 (while (consp p) (incf m) (pop p))
367 (if (<= n 0) p
368 (if (< n m) (nthcdr (- m n) x) x)))
369 (while (consp (cdr x)) (pop x))
370 x))
371 355
372 (defun custom-quote (sexp) 356 (defun custom-quote (sexp)
373 "Quote SEXP iff it is not self quoting." 357 "Quote SEXP iff it is not self quoting."
374 (if (or (memq sexp '(t nil)) 358 (if (or (memq sexp '(t nil))
375 (and (symbolp sexp) 359 (and (symbolp sexp)
376 (eq (aref (symbol-name sexp) 0) ?:)) 360 (eq (aref (symbol-name sexp) 0) ?:))
377 (and (listp sexp) 361 (and (listp sexp)
378 (memq (car sexp) '(lambda))) 362 (memq (car sexp) '(lambda)))
379 (stringp sexp) 363 (stringp sexp)
380 (numberp sexp) 364 (numberp sexp)
381 (and (fboundp 'characterp) 365 (vectorp sexp)
382 (characterp sexp))) 366 ;;; (and (fboundp 'characterp)
367 ;;; (characterp sexp))
368 )
383 sexp 369 sexp
384 (list 'quote sexp))) 370 (list 'quote sexp)))
385 371
386 (defun custom-split-regexp-maybe (regexp) 372 (defun custom-split-regexp-maybe (regexp)
387 "If REGEXP is a string, split it to a list at `\\|'. 373 "If REGEXP is a string, split it to a list at `\\|'.
388 You can get the original back with from the result with: 374 You can get the original back with from the result with:
389 (mapconcat 'identity result \"\\|\") 375 (mapconcat 'identity result \"\\|\")
390 376
391 IF REGEXP is not a string, return it unchanged." 377 IF REGEXP is not a string, return it unchanged."
392 (if (stringp regexp) 378 (if (stringp regexp)
393 (let ((start 0) 379 (let ((start 0)
403 "Prompt for a variable, defaulting to the variable at point. 389 "Prompt for a variable, defaulting to the variable at point.
404 Return a list suitable for use in `interactive'." 390 Return a list suitable for use in `interactive'."
405 (let ((v (variable-at-point)) 391 (let ((v (variable-at-point))
406 (enable-recursive-minibuffers t) 392 (enable-recursive-minibuffers t)
407 val) 393 val)
408 (setq val (completing-read 394 (setq val (completing-read
409 (if (symbolp v) 395 (if (symbolp v)
410 (format "Customize option: (default %s) " v) 396 (format "Customize option: (default %s) " v)
411 "Customize variable: ") 397 "Customize variable: ")
412 obarray (lambda (symbol) 398 obarray (lambda (symbol)
413 (and (boundp symbol) 399 (and (boundp symbol)
422 "Convert MENU to the form used by `widget-choose'. 408 "Convert MENU to the form used by `widget-choose'.
423 MENU should be in the same format as `custom-variable-menu'. 409 MENU should be in the same format as `custom-variable-menu'.
424 WIDGET is the widget to apply the filter entries of MENU on." 410 WIDGET is the widget to apply the filter entries of MENU on."
425 (let ((result nil) 411 (let ((result nil)
426 current name action filter) 412 current name action filter)
427 (while menu 413 (while menu
428 (setq current (car menu) 414 (setq current (car menu)
429 name (nth 0 current) 415 name (nth 0 current)
430 action (nth 1 current) 416 action (nth 1 current)
431 filter (nth 2 current) 417 filter (nth 2 current)
432 menu (cdr menu)) 418 menu (cdr menu))
472 (let ((prefixes custom-prefix-list) 458 (let ((prefixes custom-prefix-list)
473 prefix) 459 prefix)
474 (while prefixes 460 (while prefixes
475 (setq prefix (car prefixes)) 461 (setq prefix (car prefixes))
476 (if (search-forward prefix (+ (point) (length prefix)) t) 462 (if (search-forward prefix (+ (point) (length prefix)) t)
477 (progn 463 (progn
478 (setq prefixes nil) 464 (setq prefixes nil)
479 (delete-region (point-min) (point))) 465 (delete-region (point-min) (point)))
480 (setq prefixes (cdr prefixes)))))) 466 (setq prefixes (cdr prefixes))))))
481 (subst-char-in-region (point-min) (point-max) ?- ?\ t) 467 (subst-char-in-region (point-min) (point-max) ?- ?\ t)
482 (capitalize-region (point-min) (point-max)) 468 (capitalize-region (point-min) (point-max))
483 (unless no-suffix 469 (unless no-suffix
484 (goto-char (point-max)) 470 (goto-char (point-max))
485 (insert "...")) 471 (insert "..."))
486 (buffer-string))))) 472 (buffer-string)))))
487 473
488 (defcustom custom-unlispify-tag-names t 474 (defcustom custom-unlispify-tag-names t
512 ("-functions\\'" (repeat function)) 498 ("-functions\\'" (repeat function))
513 ("-list\\'" (repeat sexp)) 499 ("-list\\'" (repeat sexp))
514 ("-alist\\'" (repeat (cons sexp sexp)))) 500 ("-alist\\'" (repeat (cons sexp sexp))))
515 "Alist of (MATCH TYPE). 501 "Alist of (MATCH TYPE).
516 502
517 MATCH should be a regexp matching the name of a symbol, and TYPE should 503 MATCH should be a regexp matching the name of a symbol, and TYPE should
518 be a widget suitable for editing the value of that symbol. The TYPE 504 be a widget suitable for editing the value of that symbol. The TYPE
519 of the first entry where MATCH matches the name of the symbol will be 505 of the first entry where MATCH matches the name of the symbol will be
520 used. 506 used.
521 507
522 This is used for guessing the type of variables not declared with 508 This is used for guessing the type of variables not declared with
523 customize." 509 customize."
524 :type '(repeat (group (regexp :tag "Match") (sexp :tag "Type"))) 510 :type '(repeat (group (regexp :tag "Match") (sexp :tag "Type")))
525 :group 'customize) 511 :group 'customize)
538 :type '(repeat (group (regexp :tag "Match") (sexp :tag "Type"))) 524 :type '(repeat (group (regexp :tag "Match") (sexp :tag "Type")))
539 :group 'customize) 525 :group 'customize)
540 526
541 (defun custom-guess-type (symbol) 527 (defun custom-guess-type (symbol)
542 "Guess a widget suitable for editing the value of SYMBOL. 528 "Guess a widget suitable for editing the value of SYMBOL.
543 This is done by matching SYMBOL with `custom-guess-name-alist' and 529 This is done by matching SYMBOL with `custom-guess-name-alist' and
544 if that fails, the doc string with `custom-guess-doc-alist'." 530 if that fails, the doc string with `custom-guess-doc-alist'."
545 (let ((name (symbol-name symbol)) 531 (let ((name (symbol-name symbol))
546 (names custom-guess-name-alist) 532 (names custom-guess-name-alist)
547 current found) 533 current found)
548 (while names 534 (while names
552 (setq found (nth 1 current) 538 (setq found (nth 1 current)
553 names nil))) 539 names nil)))
554 (unless found 540 (unless found
555 (let ((doc (documentation-property symbol 'variable-documentation)) 541 (let ((doc (documentation-property symbol 'variable-documentation))
556 (docs custom-guess-doc-alist)) 542 (docs custom-guess-doc-alist))
557 (when doc 543 (when doc
558 (while docs 544 (while docs
559 (setq current (car docs) 545 (setq current (car docs)
560 docs (cdr docs)) 546 docs (cdr docs))
561 (when (string-match (nth 0 current) doc) 547 (when (string-match (nth 0 current) doc)
562 (setq found (nth 1 current) 548 (setq found (nth 1 current)
664 '(modified set changed rogue)) 650 '(modified set changed rogue))
665 (widget-apply child :custom-save))) 651 (widget-apply child :custom-save)))
666 children)) 652 children))
667 (custom-save-all)) 653 (custom-save-all))
668 654
669 (defvar custom-reset-menu 655 (defvar custom-reset-menu
670 '(("Current" . Custom-reset-current) 656 '(("Current" . Custom-reset-current)
671 ("Saved" . Custom-reset-saved) 657 ("Saved" . Custom-reset-saved)
672 ("Standard Settings" . Custom-reset-standard)) 658 ("Standard Settings" . Custom-reset-standard))
673 "Alist of actions for the `Reset' button. 659 "Alist of actions for the `Reset' button.
674 The key is a string containing the name of the action, the value is a 660 The key is a string containing the name of the action, the value is a
688 "Reset all modified group members to their current value." 674 "Reset all modified group members to their current value."
689 (interactive) 675 (interactive)
690 (let ((children custom-options)) 676 (let ((children custom-options))
691 (mapcar (lambda (widget) 677 (mapcar (lambda (widget)
692 (and (default-boundp (widget-value widget)) 678 (and (default-boundp (widget-value widget))
693 (if (memq (widget-get widget :custom-state) 679 (if (memq (widget-get widget :custom-state)
694 '(modified changed)) 680 '(modified changed))
695 (widget-apply widget :custom-reset-current)))) 681 (widget-apply widget :custom-reset-current))))
696 children))) 682 children)))
697 683
698 (defun Custom-reset-saved (&rest ignore) 684 (defun Custom-reset-saved (&rest ignore)
717 (widget-apply widget :custom-reset-standard)))) 703 (widget-apply widget :custom-reset-standard))))
718 children))) 704 children)))
719 705
720 ;;; The Customize Commands 706 ;;; The Customize Commands
721 707
722 (defun custom-prompt-variable (prompt-var prompt-val) 708 (defun custom-prompt-variable (prompt-var prompt-val &optional comment)
723 "Prompt for a variable and a value and return them as a list. 709 "Prompt for a variable and a value and return them as a list.
724 PROMPT-VAR is the prompt for the variable, and PROMPT-VAL is the 710 PROMPT-VAR is the prompt for the variable, and PROMPT-VAL is the
725 prompt for the value. The %s escape in PROMPT-VAL is replaced with 711 prompt for the value. The %s escape in PROMPT-VAL is replaced with
726 the name of the variable. 712 the name of the variable.
727 713
728 If the variable has a `variable-interactive' property, that is used as if 714 If the variable has a `variable-interactive' property, that is used as if
729 it were the arg to `interactive' (which see) to interactively read the value. 715 it were the arg to `interactive' (which see) to interactively read the value.
730 716
731 If the variable has a `custom-type' property, it must be a widget and the 717 If the variable has a `custom-type' property, it must be a widget and the
732 `:prompt-value' property of that widget will be used for reading the value." 718 `:prompt-value' property of that widget will be used for reading the value.
719
720 If optional COMMENT argument is non nil, also prompt for a comment and return
721 it as the third element in the list."
733 (let* ((var (read-variable prompt-var)) 722 (let* ((var (read-variable prompt-var))
734 (minibuffer-help-form '(describe-variable var))) 723 (minibuffer-help-form '(describe-variable var))
735 (list var 724 (val
736 (let ((prop (get var 'variable-interactive)) 725 (let ((prop (get var 'variable-interactive))
737 (type (get var 'custom-type)) 726 (type (get var 'custom-type))
738 (prompt (format prompt-val var))) 727 (prompt (format prompt-val var)))
739 (unless (listp type) 728 (unless (listp type)
740 (setq type (list type))) 729 (setq type (list type)))
749 prompt 738 prompt
750 (if (boundp var) 739 (if (boundp var)
751 (symbol-value var)) 740 (symbol-value var))
752 (not (boundp var)))) 741 (not (boundp var))))
753 (t 742 (t
754 (eval-minibuffer prompt))))))) 743 (eval-minibuffer prompt))))))
744 (if comment
745 (list var val
746 (read-string "Comment: " (get var 'variable-comment)))
747 (list var val))))
755 748
756 ;;;###autoload 749 ;;;###autoload
757 (defun customize-set-value (var val) 750 (defun customize-set-value (var val &optional comment)
758 "Set VARIABLE to VALUE. VALUE is a Lisp object. 751 "Set VARIABLE to VALUE. VALUE is a Lisp object.
759 752
760 If VARIABLE has a `variable-interactive' property, that is used as if 753 If VARIABLE has a `variable-interactive' property, that is used as if
761 it were the arg to `interactive' (which see) to interactively read the value. 754 it were the arg to `interactive' (which see) to interactively read the value.
762 755
763 If VARIABLE has a `custom-type' property, it must be a widget and the 756 If VARIABLE has a `custom-type' property, it must be a widget and the
764 `:prompt-value' property of that widget will be used for reading the value." 757 `:prompt-value' property of that widget will be used for reading the value.
758
759 If given a prefix (or a COMMENT argument), also prompt for a comment."
765 (interactive (custom-prompt-variable "Set variable: " 760 (interactive (custom-prompt-variable "Set variable: "
766 "Set %s to value: ")) 761 "Set %s to value: "
762 current-prefix-arg))
767 763
768 (set var val)) 764 (set var val)
765 (cond ((string= comment "")
766 (put var 'variable-comment nil))
767 (comment
768 (put var 'variable-comment comment))))
769 769
770 ;;;###autoload 770 ;;;###autoload
771 (defun customize-set-variable (var val) 771 (defun customize-set-variable (var val &optional comment)
772 "Set the default for VARIABLE to VALUE. VALUE is a Lisp object. 772 "Set the default for VARIABLE to VALUE. VALUE is a Lisp object.
773 773
774 If VARIABLE has a `custom-set' property, that is used for setting 774 If VARIABLE has a `custom-set' property, that is used for setting
775 VARIABLE, otherwise `set-default' is used. 775 VARIABLE, otherwise `set-default' is used.
776 776
779 779
780 If VARIABLE has a `variable-interactive' property, that is used as if 780 If VARIABLE has a `variable-interactive' property, that is used as if
781 it were the arg to `interactive' (which see) to interactively read the value. 781 it were the arg to `interactive' (which see) to interactively read the value.
782 782
783 If VARIABLE has a `custom-type' property, it must be a widget and the 783 If VARIABLE has a `custom-type' property, it must be a widget and the
784 `:prompt-value' property of that widget will be used for reading the value. " 784 `:prompt-value' property of that widget will be used for reading the value.
785
786 If given a prefix (or a COMMENT argument), also prompt for a comment."
785 (interactive (custom-prompt-variable "Set variable: " 787 (interactive (custom-prompt-variable "Set variable: "
786 "Set customized value for %s to: ")) 788 "Set customized value for %s to: "
789 current-prefix-arg))
787 (funcall (or (get var 'custom-set) 'set-default) var val) 790 (funcall (or (get var 'custom-set) 'set-default) var val)
788 (put var 'customized-value (list (custom-quote val)))) 791 (put var 'customized-value (list (custom-quote val)))
792 (cond ((string= comment "")
793 (put var 'variable-comment nil)
794 (put var 'customized-variable-comment nil))
795 (comment
796 (put var 'variable-comment comment)
797 (put var 'customized-variable-comment comment))))
789 798
790 ;;;###autoload 799 ;;;###autoload
791 (defun customize-save-variable (var val) 800 (defun customize-save-variable (var val &optional comment)
792 "Set the default for VARIABLE to VALUE, and save it for future sessions. 801 "Set the default for VARIABLE to VALUE, and save it for future sessions.
793 If VARIABLE has a `custom-set' property, that is used for setting 802 If VARIABLE has a `custom-set' property, that is used for setting
794 VARIABLE, otherwise `set-default' is used. 803 VARIABLE, otherwise `set-default' is used.
795 804
796 The `customized-value' property of the VARIABLE will be set to a list 805 The `customized-value' property of the VARIABLE will be set to a list
798 807
799 If VARIABLE has a `variable-interactive' property, that is used as if 808 If VARIABLE has a `variable-interactive' property, that is used as if
800 it were the arg to `interactive' (which see) to interactively read the value. 809 it were the arg to `interactive' (which see) to interactively read the value.
801 810
802 If VARIABLE has a `custom-type' property, it must be a widget and the 811 If VARIABLE has a `custom-type' property, it must be a widget and the
803 `:prompt-value' property of that widget will be used for reading the value. " 812 `:prompt-value' property of that widget will be used for reading the value.
813
814 If given a prefix (or a COMMENT argument), also prompt for a comment."
804 (interactive (custom-prompt-variable "Set and ave variable: " 815 (interactive (custom-prompt-variable "Set and ave variable: "
805 "Set and save value for %s as: ")) 816 "Set and save value for %s as: "
817 current-prefix-arg))
806 (funcall (or (get var 'custom-set) 'set-default) var val) 818 (funcall (or (get var 'custom-set) 'set-default) var val)
807 (put var 'saved-value (list (custom-quote val))) 819 (put var 'saved-value (list (custom-quote val)))
820 (cond ((string= comment "")
821 (put var 'variable-comment nil)
822 (put var 'saved-variable-comment nil))
823 (comment
824 (put var 'variable-comment comment)
825 (put var 'saved-variable-comment comment)))
808 (custom-save-all)) 826 (custom-save-all))
809 827
810 ;;;###autoload 828 ;;;###autoload
811 (defun customize () 829 (defun customize ()
812 "Select a customization buffer which you can use to set user options. 830 "Select a customization buffer which you can use to set user options.
819 ;;;###autoload 837 ;;;###autoload
820 (defun customize-group (group) 838 (defun customize-group (group)
821 "Customize GROUP, which must be a customization group." 839 "Customize GROUP, which must be a customization group."
822 (interactive (list (let ((completion-ignore-case t)) 840 (interactive (list (let ((completion-ignore-case t))
823 (completing-read "Customize group: (default emacs) " 841 (completing-read "Customize group: (default emacs) "
824 obarray 842 obarray
825 (lambda (symbol) 843 (lambda (symbol)
826 (or (get symbol 'custom-loads) 844 (or (get symbol 'custom-loads)
827 (get symbol 'custom-group))) 845 (get symbol 'custom-group)))
828 t)))) 846 t))))
829 (when (stringp group) 847 (when (stringp group)
844 ;;;###autoload 862 ;;;###autoload
845 (defun customize-group-other-window (group) 863 (defun customize-group-other-window (group)
846 "Customize GROUP, which must be a customization group." 864 "Customize GROUP, which must be a customization group."
847 (interactive (list (let ((completion-ignore-case t)) 865 (interactive (list (let ((completion-ignore-case t))
848 (completing-read "Customize group: (default emacs) " 866 (completing-read "Customize group: (default emacs) "
849 obarray 867 obarray
850 (lambda (symbol) 868 (lambda (symbol)
851 (or (get symbol 'custom-loads) 869 (or (get symbol 'custom-loads)
852 (get symbol 'custom-group))) 870 (get symbol 'custom-group)))
853 t)))) 871 t))))
854 (when (stringp group) 872 (when (stringp group)
933 (get symbol 'group-documentation)) 951 (get symbol 'group-documentation))
934 (let ((version (get symbol 'custom-version))) 952 (let ((version (get symbol 'custom-version)))
935 (and version 953 (and version
936 (or (null since-version) 954 (or (null since-version)
937 (customize-version-lessp since-version version)) 955 (customize-version-lessp since-version version))
938 (if (member version versions) 956 (if (member version versions)
939 t 957 t
940 ;;; Collect all versions that we use. 958 ;;; Collect all versions that we use.
941 (push version versions)))) 959 (push version versions))))
942 (setq found 960 (setq found
943 ;; We have to set the right thing here, 961 ;; We have to set the right thing here,
944 ;; depending if we have a group or a 962 ;; depending if we have a group or a
945 ;; variable. 963 ;; variable.
946 (if (get symbol 'group-documentation) 964 (if (get symbol 'group-documentation)
947 (cons (list symbol 'custom-group) found) 965 (cons (list symbol 'custom-group) found)
948 (cons (list symbol 'custom-variable) found)))))) 966 (cons (list symbol 'custom-variable) found))))))
949 (if (not found) 967 (if (not found)
950 (error "No user option defaults have been changed since Emacs %s" 968 (error "No user option defaults have been changed since Emacs %s"
951 since-version) 969 since-version)
952 (let ((flist nil)) 970 (let ((flist nil))
953 (while versions 971 (while versions
954 (push (copy-sequence 972 (push (copy-sequence
955 (cdr (assoc (car versions) custom-versions-load-alist))) 973 (cdr (assoc (car versions) custom-versions-load-alist)))
956 flist) 974 flist)
957 (setq versions (cdr versions))) 975 (setq versions (cdr versions)))
958 (put 'custom-versions-load-alist 'custom-loads 976 (put 'custom-versions-load-alist 'custom-loads
959 ;; Get all the files that correspond to element from the 977 ;; Get all the files that correspond to element from the
960 ;; VERSIONS list. This could use some simplification. 978 ;; VERSIONS list. This could use some simplification.
961 (apply 'nconc flist))) 979 (apply 'nconc flist)))
962 ;; Because we set all the files needed to be loaded as a 980 ;; Because we set all the files needed to be loaded as a
963 ;; `custom-loads' property to `custom-versions-load-alist' this 981 ;; `custom-loads' property to `custom-versions-load-alist' this
998 1016
999 ;;;###autoload 1017 ;;;###autoload
1000 (defun customize-face (&optional symbol) 1018 (defun customize-face (&optional symbol)
1001 "Customize SYMBOL, which should be a face name or nil. 1019 "Customize SYMBOL, which should be a face name or nil.
1002 If SYMBOL is nil, customize all faces." 1020 If SYMBOL is nil, customize all faces."
1003 (interactive (list (completing-read "Customize face: (default all) " 1021 (interactive (list (completing-read "Customize face: (default all) "
1004 obarray 'custom-facep))) 1022 obarray 'custom-facep)))
1005 (if (or (null symbol) (and (stringp symbol) (zerop (length symbol)))) 1023 (if (or (null symbol) (and (stringp symbol) (zerop (length symbol))))
1006 (custom-buffer-create (custom-sort-items 1024 (custom-buffer-create (custom-sort-items
1007 (mapcar (lambda (symbol) 1025 (mapcar (lambda (symbol)
1008 (list symbol 'custom-face)) 1026 (list symbol 'custom-face))
1018 (custom-unlispify-tag-name symbol))))) 1036 (custom-unlispify-tag-name symbol)))))
1019 1037
1020 ;;;###autoload 1038 ;;;###autoload
1021 (defun customize-face-other-window (&optional symbol) 1039 (defun customize-face-other-window (&optional symbol)
1022 "Show customization buffer for FACE in other window." 1040 "Show customization buffer for FACE in other window."
1023 (interactive (list (completing-read "Customize face: " 1041 (interactive (list (completing-read "Customize face: "
1024 obarray 'custom-facep))) 1042 obarray 'custom-facep)))
1025 (if (or (null symbol) (and (stringp symbol) (zerop (length symbol)))) 1043 (if (or (null symbol) (and (stringp symbol) (zerop (length symbol))))
1026 () 1044 ()
1027 (if (stringp symbol) 1045 (if (stringp symbol)
1028 (setq symbol (intern symbol))) 1046 (setq symbol (intern symbol)))
1029 (unless (symbolp symbol) 1047 (unless (symbolp symbol)
1030 (error "Should be a symbol %S" symbol)) 1048 (error "Should be a symbol %S" symbol))
1031 (custom-buffer-create-other-window 1049 (custom-buffer-create-other-window
1032 (list (list symbol 'custom-face)) 1050 (list (list symbol 'custom-face))
1033 (format "*Customize Face: %s*" (custom-unlispify-tag-name symbol))))) 1051 (format "*Customize Face: %s*" (custom-unlispify-tag-name symbol)))))
1034 1052
1035 ;;;###autoload 1053 ;;;###autoload
1036 (defun customize-customized () 1054 (defun customize-customized ()
1037 "Customize all user options set since the last save in this session." 1055 "Customize all user options set since the last save in this session."
1038 (interactive) 1056 (interactive)
1039 (let ((found nil)) 1057 (let ((found nil))
1040 (mapatoms (lambda (symbol) 1058 (mapatoms (lambda (symbol)
1041 (and (get symbol 'customized-face) 1059 (and (or (get symbol 'customized-face)
1060 (get symbol 'customized-face-comment))
1042 (custom-facep symbol) 1061 (custom-facep symbol)
1043 (push (list symbol 'custom-face) found)) 1062 (push (list symbol 'custom-face) found))
1044 (and (get symbol 'customized-value) 1063 (and (or (get symbol 'customized-value)
1064 (get symbol 'customized-variable-comment))
1045 (boundp symbol) 1065 (boundp symbol)
1046 (push (list symbol 'custom-variable) found)))) 1066 (push (list symbol 'custom-variable) found))))
1047 (if (not found) 1067 (if (not found)
1048 (error "No customized user options") 1068 (error "No customized user options")
1049 (custom-buffer-create (custom-sort-items found t nil) 1069 (custom-buffer-create (custom-sort-items found t nil)
1053 (defun customize-saved () 1073 (defun customize-saved ()
1054 "Customize all already saved user options." 1074 "Customize all already saved user options."
1055 (interactive) 1075 (interactive)
1056 (let ((found nil)) 1076 (let ((found nil))
1057 (mapatoms (lambda (symbol) 1077 (mapatoms (lambda (symbol)
1058 (and (get symbol 'saved-face) 1078 (and (or (get symbol 'saved-face)
1079 (get symbol 'saved-face-comment))
1059 (custom-facep symbol) 1080 (custom-facep symbol)
1060 (push (list symbol 'custom-face) found)) 1081 (push (list symbol 'custom-face) found))
1061 (and (get symbol 'saved-value) 1082 (and (or (get symbol 'saved-value)
1083 (get symbol 'saved-variable-comment))
1062 (boundp symbol) 1084 (boundp symbol)
1063 (push (list symbol 'custom-variable) found)))) 1085 (push (list symbol 'custom-variable) found))))
1064 (if (not found ) 1086 (if (not found )
1065 (error "No saved user options") 1087 (error "No saved user options")
1066 (custom-buffer-create (custom-sort-items found t nil) 1088 (custom-buffer-create (custom-sort-items found t nil)
1127 links: groups have links to subgroups." 1149 links: groups have links to subgroups."
1128 :type '(radio (const brackets) 1150 :type '(radio (const brackets)
1129 (const links)) 1151 (const links))
1130 :group 'custom-buffer) 1152 :group 'custom-buffer)
1131 1153
1154 (defcustom custom-buffer-done-function 'bury-buffer
1155 "*Function called to remove a Custom buffer when the user is done with it.
1156 Called with one argument, the buffer to remove."
1157 :type '(choice (function-item bury-buffer)
1158 (function-item kill-buffer)
1159 (function :tag "Other"))
1160 :version "21.1"
1161 :group 'custom-buffer)
1162
1132 (defcustom custom-buffer-indent 3 1163 (defcustom custom-buffer-indent 3
1133 "Number of spaces to indent nested groups." 1164 "Number of spaces to indent nested groups."
1134 :type 'integer 1165 :type 'integer
1135 :group 'custom-buffer) 1166 :group 'custom-buffer)
1136 1167
1169 "If non-nil, only show a single reset button in customize buffers. 1200 "If non-nil, only show a single reset button in customize buffers.
1170 This button will have a menu with all three reset operations." 1201 This button will have a menu with all three reset operations."
1171 :type 'boolean 1202 :type 'boolean
1172 :group 'custom-buffer) 1203 :group 'custom-buffer)
1173 1204
1205 (defun Custom-buffer-done (&rest ignore)
1206 "Remove current buffer by calling `custom-buffer-done-function'."
1207 (interactive)
1208 (funcall custom-buffer-done-function (current-buffer)))
1209
1210 (defcustom custom-raised-buttons (not (equal (face-valid-attribute-values :box)
1211 '(("unspecified" . unspecified))))
1212 "If non-nil, indicate active buttons in a `raised-button' style.
1213 Otherwise use brackets."
1214 :type 'boolean
1215 :version "21.1"
1216 :group 'custom-buffer)
1217
1174 (defun custom-buffer-create-internal (options &optional description) 1218 (defun custom-buffer-create-internal (options &optional description)
1175 (message "Creating customization buffer...") 1219 (message "Creating customization buffer...")
1176 (custom-mode) 1220 (custom-mode)
1177 (widget-insert "This is a customization buffer") 1221 (widget-insert "This is a customization buffer")
1178 (if description 1222 (if description
1179 (widget-insert description)) 1223 (widget-insert description))
1180 (widget-insert ". 1224 (widget-insert (format ".
1181 Square brackets show active fields; type RET or click mouse-1 1225 %s show active fields; type RET or click mouse-1
1182 on an active field to invoke its action. Editing an option value 1226 on an active field to invoke its action. Editing an option value
1183 changes the text in the buffer; invoke the State button and 1227 changes the text in the buffer; invoke the State button and
1184 choose the Set operation to set the option value. 1228 choose the Set operation to set the option value.
1185 Invoke ") 1229 Invoke " (if custom-raised-buttons
1186 (widget-create 'info-link 1230 "`Raised' buttons"
1231 "Square brackets")))
1232 (widget-create 'info-link
1187 :tag "Help" 1233 :tag "Help"
1188 :help-echo "Read the online help." 1234 :help-echo "Read the online help."
1189 "(emacs)Easy Customization") 1235 "(emacs)Easy Customization")
1190 (widget-insert " for more information.\n\n") 1236 (widget-insert " for more information.\n\n")
1191 (message "Creating customization buttons...") 1237 (message "Creating customization buttons...")
1230 :help-echo "\ 1276 :help-echo "\
1231 Reset all values in this buffer to their standard settings." 1277 Reset all values in this buffer to their standard settings."
1232 :action 'Custom-reset-standard)) 1278 :action 'Custom-reset-standard))
1233 (widget-insert " ") 1279 (widget-insert " ")
1234 (widget-create 'push-button 1280 (widget-create 'push-button
1235 :tag "Bury Buffer" 1281 :tag "Finish"
1236 :help-echo "Bury the buffer." 1282 :help-echo "Bury or kill the buffer."
1237 :action (lambda (widget &optional event) 1283 :action #'Custom-buffer-done)
1238 (bury-buffer)))
1239 (widget-insert "\n\n") 1284 (widget-insert "\n\n")
1240 (message "Creating customization items...") 1285 (message "Creating customization items...")
1241 (setq custom-options 1286 (setq custom-options
1242 (if (= (length options) 1) 1287 (if (= (length options) 1)
1243 (mapcar (lambda (entry) 1288 (mapcar (lambda (entry)
1244 (widget-create (nth 1 entry) 1289 (widget-create (nth 1 entry)
1245 :documentation-shown t 1290 :documentation-shown t
1246 :custom-state 'unknown 1291 :custom-state 'unknown
1290 on an active field to invoke its action. 1335 on an active field to invoke its action.
1291 Invoke [+] below to expand a group, and [-] to collapse an expanded group.\n") 1336 Invoke [+] below to expand a group, and [-] to collapse an expanded group.\n")
1292 (if custom-browse-only-groups 1337 (if custom-browse-only-groups
1293 (widget-insert "\ 1338 (widget-insert "\
1294 Invoke the [Group] button below to edit that item in another window.\n\n") 1339 Invoke the [Group] button below to edit that item in another window.\n\n")
1295 (widget-insert "Invoke the ") 1340 (widget-insert "Invoke the ")
1296 (widget-create 'item 1341 (widget-create 'item
1297 :format "%t" 1342 :format "%t"
1298 :tag "[Group]" 1343 :tag "[Group]"
1299 :tag-glyph "folder") 1344 :tag-glyph "folder")
1300 (widget-insert ", ") 1345 (widget-insert ", ")
1301 (widget-create 'item 1346 (widget-create 'item
1302 :format "%t" 1347 :format "%t"
1303 :tag "[Face]" 1348 :tag "[Face]"
1304 :tag-glyph "face") 1349 :tag-glyph "face")
1305 (widget-insert ", and ") 1350 (widget-insert ", and ")
1306 (widget-create 'item 1351 (widget-create 'item
1307 :format "%t" 1352 :format "%t"
1308 :tag "[Option]" 1353 :tag "[Option]"
1309 :tag-glyph "option") 1354 :tag-glyph "option")
1310 (widget-insert " buttons below to edit that 1355 (widget-insert " buttons below to edit that
1311 item in another window.\n\n")) 1356 item in another window.\n\n"))
1312 (let ((custom-buffer-style 'tree)) 1357 (let ((custom-buffer-style 'tree))
1313 (widget-create 'custom-group 1358 (widget-create 'custom-group
1314 :custom-last t 1359 :custom-last t
1315 :custom-state 'unknown 1360 :custom-state 'unknown
1316 :tag (custom-unlispify-tag-name group) 1361 :tag (custom-unlispify-tag-name group)
1317 :value group)) 1362 :value group))
1318 (goto-char (point-min))) 1363 (goto-char (point-min)))
1362 (" |-" "middle") 1407 (" |-" "middle")
1363 (" `-" "bottom"))) 1408 (" `-" "bottom")))
1364 1409
1365 (defun custom-browse-insert-prefix (prefix) 1410 (defun custom-browse-insert-prefix (prefix)
1366 "Insert PREFIX. On XEmacs convert it to line graphics." 1411 "Insert PREFIX. On XEmacs convert it to line graphics."
1412 ;; Fixme: do graphics.
1367 (if nil ; (string-match "XEmacs" emacs-version) 1413 (if nil ; (string-match "XEmacs" emacs-version)
1368 (progn 1414 (progn
1369 (insert "*") 1415 (insert "*")
1370 (while (not (string-equal prefix "")) 1416 (while (not (string-equal prefix ""))
1371 (let ((entry (substring prefix 0 3))) 1417 (let ((entry (substring prefix 0 3)))
1372 (setq prefix (substring prefix 3)) 1418 (setq prefix (substring prefix 3))
1373 (let ((overlay (make-overlay (1- (point)) (point) nil t nil)) 1419 (let ((overlay (make-overlay (1- (point)) (point) nil t nil))
1422 (t 1468 (t
1423 (:underline t))) 1469 (:underline t)))
1424 "Face used when the customize item is not defined for customization." 1470 "Face used when the customize item is not defined for customization."
1425 :group 'custom-magic-faces) 1471 :group 'custom-magic-faces)
1426 1472
1427 (defface custom-modified-face '((((class color)) 1473 (defface custom-modified-face '((((class color))
1428 (:foreground "white" :background "blue")) 1474 (:foreground "white" :background "blue"))
1429 (t 1475 (t
1430 (:italic t :bold))) 1476 (:italic t :bold)))
1431 "Face used when the customize item has been modified." 1477 "Face used when the customize item has been modified."
1432 :group 'custom-magic-faces) 1478 :group 'custom-magic-faces)
1433 1479
1434 (defface custom-set-face '((((class color)) 1480 (defface custom-set-face '((((class color))
1435 (:foreground "blue" :background "white")) 1481 (:foreground "blue" :background "white"))
1436 (t 1482 (t
1437 (:italic t))) 1483 (:italic t)))
1438 "Face used when the customize item has been set." 1484 "Face used when the customize item has been set."
1439 :group 'custom-magic-faces) 1485 :group 'custom-magic-faces)
1440 1486
1441 (defface custom-changed-face '((((class color)) 1487 (defface custom-changed-face '((((class color))
1442 (:foreground "white" :background "blue")) 1488 (:foreground "white" :background "blue"))
1443 (t 1489 (t
1444 (:italic t))) 1490 (:italic t)))
1445 "Face used when the customize item has been changed." 1491 "Face used when the customize item has been changed."
1446 :group 'custom-magic-faces) 1492 :group 'custom-magic-faces)
1475 something in this group is not prepared for customization.") 1521 something in this group is not prepared for customization.")
1476 (standard " " nil "\ 1522 (standard " " nil "\
1477 this %c is unchanged from its standard setting." "\ 1523 this %c is unchanged from its standard setting." "\
1478 visible group members are all at standard settings.")) 1524 visible group members are all at standard settings."))
1479 "Alist of customize option states. 1525 "Alist of customize option states.
1480 Each entry is of the form (STATE MAGIC FACE ITEM-DESC [ GROUP-DESC ]), where 1526 Each entry is of the form (STATE MAGIC FACE ITEM-DESC [ GROUP-DESC ]), where
1481 1527
1482 STATE is one of the following symbols: 1528 STATE is one of the following symbols:
1483 1529
1484 `nil' 1530 `nil'
1485 For internal use, should never occur. 1531 For internal use, should never occur.
1486 `unknown' 1532 `unknown'
1487 For internal use, should never occur. 1533 For internal use, should never occur.
1488 `hidden' 1534 `hidden'
1489 This item is not being displayed. 1535 This item is not being displayed.
1490 `invalid' 1536 `invalid'
1491 This item is modified, but has an invalid form. 1537 This item is modified, but has an invalid form.
1492 `modified' 1538 `modified'
1493 This item is modified, and has a valid form. 1539 This item is modified, and has a valid form.
1494 `set' 1540 `set'
1546 :value-create 'custom-magic-value-create 1592 :value-create 'custom-magic-value-create
1547 :value-delete 'widget-children-value-delete) 1593 :value-delete 'widget-children-value-delete)
1548 1594
1549 (defun widget-magic-mouse-down-action (widget &optional event) 1595 (defun widget-magic-mouse-down-action (widget &optional event)
1550 ;; Non-nil unless hidden. 1596 ;; Non-nil unless hidden.
1551 (not (eq (widget-get (widget-get (widget-get widget :parent) :parent) 1597 (not (eq (widget-get (widget-get (widget-get widget :parent) :parent)
1552 :custom-state) 1598 :custom-state)
1553 'hidden))) 1599 'hidden)))
1554 1600
1555 (defun custom-magic-value-create (widget) 1601 (defun custom-magic-value-create (widget)
1556 ;; Create compact status report for WIDGET. 1602 ;; Create compact status report for WIDGET.
1565 (nth 4 entry)) 1611 (nth 4 entry))
1566 (nth 3 entry))) 1612 (nth 3 entry)))
1567 (form (widget-get parent :custom-form)) 1613 (form (widget-get parent :custom-form))
1568 children) 1614 children)
1569 (while (string-match "\\`\\(.*\\)%c\\(.*\\)\\'" text) 1615 (while (string-match "\\`\\(.*\\)%c\\(.*\\)\\'" text)
1570 (setq text (concat (match-string 1 text) 1616 (setq text (concat (match-string 1 text)
1571 (symbol-name category) 1617 (symbol-name category)
1572 (match-string 2 text)))) 1618 (match-string 2 text))))
1573 (when (and custom-magic-show 1619 (when (and custom-magic-show
1574 (or (not hidden) 1620 (or (not hidden)
1575 (memq category custom-magic-show-hidden))) 1621 (memq category custom-magic-show-hidden)))
1577 (when (and (eq category 'group) 1623 (when (and (eq category 'group)
1578 (not (and (eq custom-buffer-style 'links) 1624 (not (and (eq custom-buffer-style 'links)
1579 (> (widget-get parent :custom-level) 1)))) 1625 (> (widget-get parent :custom-level) 1))))
1580 (insert-char ?\ (* custom-buffer-indent 1626 (insert-char ?\ (* custom-buffer-indent
1581 (widget-get parent :custom-level)))) 1627 (widget-get parent :custom-level))))
1582 (push (widget-create-child-and-convert 1628 (push (widget-create-child-and-convert
1583 widget 'choice-item 1629 widget 'choice-item
1584 :help-echo "Change the state of this item." 1630 :help-echo "Change the state of this item."
1585 :format (if hidden "%t" "%[%t%]") 1631 :format (if hidden "%t" "%[%t%]")
1586 :button-prefix 'widget-push-button-prefix 1632 :button-prefix 'widget-push-button-prefix
1587 :button-suffix 'widget-push-button-suffix 1633 :button-suffix 'widget-push-button-suffix
1588 :mouse-down-action 'widget-magic-mouse-down-action 1634 :mouse-down-action 'widget-magic-mouse-down-action
1607 (when custom-magic-show-button 1653 (when custom-magic-show-button
1608 (when custom-magic-show 1654 (when custom-magic-show
1609 (let ((indent (widget-get parent :indent))) 1655 (let ((indent (widget-get parent :indent)))
1610 (when indent 1656 (when indent
1611 (insert-char ? indent)))) 1657 (insert-char ? indent))))
1612 (push (widget-create-child-and-convert 1658 (push (widget-create-child-and-convert
1613 widget 'choice-item 1659 widget 'choice-item
1614 :mouse-down-action 'widget-magic-mouse-down-action 1660 :mouse-down-action 'widget-magic-mouse-down-action
1615 :button-face face 1661 :button-face face
1616 :button-prefix "" 1662 :button-prefix ""
1617 :button-suffix "" 1663 :button-suffix ""
1618 :help-echo "Change the state." 1664 :help-echo "Change the state."
1629 (let ((magic (widget-get widget :custom-magic))) 1675 (let ((magic (widget-get widget :custom-magic)))
1630 (widget-value-set magic (widget-value magic)))) 1676 (widget-value-set magic (widget-value magic))))
1631 1677
1632 ;;; The `custom' Widget. 1678 ;;; The `custom' Widget.
1633 1679
1634 (defface custom-button-face nil 1680 (defface custom-button-face
1681 '((((type x) (class color)) ; Like default modeline
1682 (:box (:line-width 2 :style released-button) :background "lightgrey"))
1683 (t
1684 nil))
1635 "Face used for buttons in customization buffers." 1685 "Face used for buttons in customization buffers."
1686 :version "21.1"
1687 :group 'custom-faces)
1688
1689 (defface custom-button-pressed-face
1690 '((((type x) (class color))
1691 (:box (:line-width 2 :style pressed-button) :background "lightgrey"))
1692 (t
1693 (:inverse-video t)))
1694 "Face used for buttons in customization buffers."
1695 :version "21.1"
1636 :group 'custom-faces) 1696 :group 'custom-faces)
1637 1697
1638 (defface custom-documentation-face nil 1698 (defface custom-documentation-face nil
1639 "Face used for documentation strings in customization buffers." 1699 "Face used for documentation strings in customization buffers."
1640 :group 'custom-faces) 1700 :group 'custom-faces)
1665 :match (lambda (widget value) (symbolp value))) 1725 :match (lambda (widget value) (symbolp value)))
1666 1726
1667 (defun custom-convert-widget (widget) 1727 (defun custom-convert-widget (widget)
1668 ;; Initialize :value and :tag from :args in WIDGET. 1728 ;; Initialize :value and :tag from :args in WIDGET.
1669 (let ((args (widget-get widget :args))) 1729 (let ((args (widget-get widget :args)))
1670 (when args 1730 (when args
1671 (widget-put widget :value (widget-apply widget 1731 (widget-put widget :value (widget-apply widget
1672 :value-to-internal (car args))) 1732 :value-to-internal (car args)))
1673 (widget-put widget :tag (custom-unlispify-tag-name (car args))) 1733 (widget-put widget :tag (custom-unlispify-tag-name (car args)))
1674 (widget-put widget :args nil))) 1734 (widget-put widget :args nil)))
1675 widget) 1735 widget)
1693 (save-excursion 1753 (save-excursion
1694 (widget-value-set widget (widget-value widget)) 1754 (widget-value-set widget (widget-value widget))
1695 (custom-redraw-magic widget)) 1755 (custom-redraw-magic widget))
1696 (when (and (>= pos from) (<= pos to)) 1756 (when (and (>= pos from) (<= pos to))
1697 (condition-case nil 1757 (condition-case nil
1698 (progn 1758 (progn
1699 (if (> column 0) 1759 (if (> column 0)
1700 (goto-line line) 1760 (goto-line line)
1701 (goto-line (1+ line))) 1761 (goto-line (1+ line)))
1702 (move-to-column column)) 1762 (move-to-column column))
1703 (error nil))))) 1763 (error nil)))))
1704 1764
1705 (defun custom-redraw-magic (widget) 1765 (defun custom-redraw-magic (widget)
1706 "Redraw WIDGET state with current settings." 1766 "Redraw WIDGET state with current settings."
1707 (while widget 1767 (while widget
1708 (let ((magic (widget-get widget :custom-magic))) 1768 (let ((magic (widget-get widget :custom-magic)))
1709 (cond (magic 1769 (cond (magic
1710 (widget-value-set magic (widget-value magic)) 1770 (widget-value-set magic (widget-value magic))
1711 (when (setq widget (widget-get widget :group)) 1771 (when (setq widget (widget-get widget :group))
1712 (custom-group-state-update widget))) 1772 (custom-group-state-update widget)))
1713 (t 1773 (t
1714 (setq widget nil))))) 1774 (setq widget nil)))))
1728 "Hack to avoid recursive dependencies.") 1788 "Hack to avoid recursive dependencies.")
1729 1789
1730 (defun custom-load-symbol (symbol) 1790 (defun custom-load-symbol (symbol)
1731 "Load all dependencies for SYMBOL." 1791 "Load all dependencies for SYMBOL."
1732 (unless custom-load-recursion 1792 (unless custom-load-recursion
1733 (let ((custom-load-recursion t) 1793 (let ((custom-load-recursion t)
1734 (loads (get symbol 'custom-loads)) 1794 (loads (get symbol 'custom-loads))
1735 load) 1795 load)
1736 (while loads 1796 (while loads
1737 (setq load (car loads) 1797 (setq load (car loads)
1738 loads (cdr loads)) 1798 loads (cdr loads))
1786 (let ((state (widget-get widget :custom-state))) 1846 (let ((state (widget-get widget :custom-state)))
1787 (cond ((memq state '(invalid modified)) 1847 (cond ((memq state '(invalid modified))
1788 (error "There are unset changes")) 1848 (error "There are unset changes"))
1789 ((eq state 'hidden) 1849 ((eq state 'hidden)
1790 (widget-put widget :custom-state 'unknown)) 1850 (widget-put widget :custom-state 'unknown))
1791 (t 1851 (t
1792 (widget-put widget :documentation-shown nil) 1852 (widget-put widget :documentation-shown nil)
1793 (widget-put widget :custom-state 'hidden))) 1853 (widget-put widget :custom-state 'hidden)))
1794 (custom-redraw widget) 1854 (custom-redraw widget)
1795 (widget-setup))) 1855 (widget-setup)))
1796 1856
1820 (insert ".\n")) 1880 (insert ".\n"))
1821 ((null (cdr links)) 1881 ((null (cdr links))
1822 (if many 1882 (if many
1823 (insert ", and ") 1883 (insert ", and ")
1824 (insert " and "))) 1884 (insert " and ")))
1825 (t 1885 (t
1826 (insert ", ")))) 1886 (insert ", "))))
1827 (widget-put widget :buttons buttons)))) 1887 (widget-put widget :buttons buttons))))
1828 1888
1829 (defun custom-add-parent-links (widget &optional initial-string) 1889 (defun custom-add-parent-links (widget &optional initial-string)
1830 "Add \"Parent groups: ...\" to WIDGET if the group has parents. 1890 "Add \"Parent groups: ...\" to WIDGET if the group has parents.
1838 (insert (or initial-string "Parent groups:")) 1898 (insert (or initial-string "Parent groups:"))
1839 (mapatoms (lambda (symbol) 1899 (mapatoms (lambda (symbol)
1840 (let ((entry (assq name (get symbol 'custom-group)))) 1900 (let ((entry (assq name (get symbol 'custom-group))))
1841 (when (eq (nth 1 entry) type) 1901 (when (eq (nth 1 entry) type)
1842 (insert " ") 1902 (insert " ")
1843 (push (widget-create-child-and-convert 1903 (push (widget-create-child-and-convert
1844 widget 'custom-group-link 1904 widget 'custom-group-link
1845 :tag (custom-unlispify-tag-name symbol) 1905 :tag (custom-unlispify-tag-name symbol)
1846 symbol) 1906 symbol)
1847 buttons) 1907 buttons)
1848 (setq found t))))) 1908 (setq found t)))))
1849 (widget-put widget :buttons buttons) 1909 (widget-put widget :buttons buttons)
1850 (if found 1910 (if found
1851 (insert "\n") 1911 (insert "\n")
1852 (delete-region start (point))) 1912 (delete-region start (point)))
1853 found)) 1913 found))
1914
1915 ;;; The `custom-comment' Widget.
1916
1917 ;; like the editable field
1918 (defface custom-comment-face '((((class grayscale color)
1919 (background light))
1920 (:background "gray85"))
1921 (((class grayscale color)
1922 (background dark))
1923 (:background "dim gray"))
1924 (t
1925 (:italic t)))
1926 "Face used for comments on variables or faces"
1927 :version "21.1"
1928 :group 'custom-faces)
1929
1930 ;; like font-lock-comment-face
1931 (defface custom-comment-tag-face
1932 '((((class color) (background dark)) (:foreground "gray80"))
1933 (((class color) (background light)) (:foreground "blue4"))
1934 (((class grayscale) (background light))
1935 (:foreground "DimGray" :bold t :italic t))
1936 (((class grayscale) (background dark))
1937 (:foreground "LightGray" :bold t :italic t))
1938 (t (:bold t)))
1939 "Face used for variables or faces comment tags"
1940 :group 'custom-faces)
1941
1942 (define-widget 'custom-comment 'string
1943 "User comment"
1944 :tag "Comment"
1945 :help-echo "Edit a comment here"
1946 :sample-face 'custom-comment-tag-face
1947 :value-face 'custom-comment-face
1948 :value-set 'custom-comment-value-set
1949 :create 'custom-comment-create
1950 :delete 'custom-comment-delete)
1951
1952 (defun custom-comment-create (widget)
1953 (let (overlay)
1954 (widget-default-create widget)
1955 (widget-put widget :comment-overlay
1956 (setq overlay (make-overlay (widget-get widget :from)
1957 (widget-get widget :to))))
1958 ;;(overlay-put overlay 'start-open t)
1959 (when (equal (widget-get widget :value) "")
1960 (overlay-put overlay 'invisible t))))
1961
1962 (defun custom-comment-delete (widget)
1963 (widget-default-delete widget)
1964 (delete-overlay (widget-get widget :comment-overlay)))
1965
1966 (defun custom-comment-value-set (widget value)
1967 (widget-default-value-set widget value)
1968 (if (equal value "")
1969 (overlay-put (widget-get widget :comment-overlay) 'invisible t)
1970 (overlay-put (widget-get widget :comment-overlay) 'invisible nil)))
1971
1972 ;; Those functions are for the menu. WIDGET is NOT the comment widget. It's
1973 ;; the global custom one
1974 (defun custom-comment-show (widget)
1975 (overlay-put
1976 (widget-get (widget-get widget :comment-widget) :comment-overlay)
1977 'invisible nil))
1978
1979 (defun custom-comment-invisible-p (widget)
1980 (overlay-get
1981 (widget-get (widget-get widget :comment-widget) :comment-overlay)
1982 'invisible))
1854 1983
1855 ;;; The `custom-variable' Widget. 1984 ;;; The `custom-variable' Widget.
1856 1985
1857 (defface custom-variable-tag-face '((((class color) 1986 (defface custom-variable-tag-face '((((class color)
1858 (background dark)) 1987 (background dark))
1892 :custom-reset-saved 'custom-variable-reset-saved 2021 :custom-reset-saved 'custom-variable-reset-saved
1893 :custom-reset-standard 'custom-variable-reset-standard) 2022 :custom-reset-standard 'custom-variable-reset-standard)
1894 2023
1895 (defun custom-variable-type (symbol) 2024 (defun custom-variable-type (symbol)
1896 "Return a widget suitable for editing the value of SYMBOL. 2025 "Return a widget suitable for editing the value of SYMBOL.
1897 If SYMBOL has a `custom-type' property, use that. 2026 If SYMBOL has a `custom-type' property, use that.
1898 Otherwise, look up symbol in `custom-guess-type-alist'." 2027 Otherwise, look up symbol in `custom-guess-type-alist'."
1899 (let* ((type (or (get symbol 'custom-type) 2028 (let* ((type (or (get symbol 'custom-type)
1900 (and (not (get symbol 'standard-value)) 2029 (and (not (get symbol 'standard-value))
1901 (custom-guess-type symbol)) 2030 (custom-guess-type symbol))
1902 'sexp)) 2031 'sexp))
1946 buttons) 2075 buttons)
1947 (insert " " tag "\n") 2076 (insert " " tag "\n")
1948 (widget-put widget :buttons buttons)) 2077 (widget-put widget :buttons buttons))
1949 ((eq state 'hidden) 2078 ((eq state 'hidden)
1950 ;; Indicate hidden value. 2079 ;; Indicate hidden value.
1951 (push (widget-create-child-and-convert 2080 (push (widget-create-child-and-convert
1952 widget 'item 2081 widget 'item
1953 :format "%{%t%}: " 2082 :format "%{%t%}: "
1954 :sample-face 'custom-variable-tag-face 2083 :sample-face 'custom-variable-tag-face
1955 :tag tag 2084 :tag tag
1956 :parent widget) 2085 :parent widget)
1957 buttons) 2086 buttons)
1958 (push (widget-create-child-and-convert 2087 (push (widget-create-child-and-convert
1959 widget 'visibility 2088 widget 'visibility
1960 :help-echo "Show the value of this option." 2089 :help-echo "Show the value of this option."
1961 :action 'custom-toggle-parent 2090 :action 'custom-toggle-parent
1962 nil) 2091 nil)
1963 buttons)) 2092 buttons))
1970 ((default-boundp symbol) 2099 ((default-boundp symbol)
1971 (custom-quote (funcall get symbol))) 2100 (custom-quote (funcall get symbol)))
1972 (t 2101 (t
1973 (custom-quote (widget-get conv :value)))))) 2102 (custom-quote (widget-get conv :value))))))
1974 (insert (symbol-name symbol) ": ") 2103 (insert (symbol-name symbol) ": ")
1975 (push (widget-create-child-and-convert 2104 (push (widget-create-child-and-convert
1976 widget 'visibility 2105 widget 'visibility
1977 :help-echo "Hide the value of this option." 2106 :help-echo "Hide the value of this option."
1978 :action 'custom-toggle-parent 2107 :action 'custom-toggle-parent
1979 t) 2108 t)
1980 buttons) 2109 buttons)
1981 (insert " ") 2110 (insert " ")
1982 (push (widget-create-child-and-convert 2111 (push (widget-create-child-and-convert
1983 widget 'sexp 2112 widget 'sexp
1984 :button-face 'custom-variable-button-face 2113 :button-face 'custom-variable-button-face
1985 :format "%v" 2114 :format "%v"
1986 :tag (symbol-name symbol) 2115 :tag (symbol-name symbol)
1987 :parent widget 2116 :parent widget
1988 :value value) 2117 :value value)
1994 (unless (string-match ":" format) 2123 (unless (string-match ":" format)
1995 (error "Bad format")) 2124 (error "Bad format"))
1996 (setq tag-format (substring format 0 (match-end 0))) 2125 (setq tag-format (substring format 0 (match-end 0)))
1997 (setq value-format (substring format (match-end 0))) 2126 (setq value-format (substring format (match-end 0)))
1998 (push (widget-create-child-and-convert 2127 (push (widget-create-child-and-convert
1999 widget 'item 2128 widget 'item
2000 :format tag-format 2129 :format tag-format
2001 :action 'custom-tag-action 2130 :action 'custom-tag-action
2002 :help-echo "Change value of this option." 2131 :help-echo "Change value of this option."
2003 :mouse-down-action 'custom-tag-mouse-down-action 2132 :mouse-down-action 'custom-tag-mouse-down-action
2004 :button-face 'custom-variable-button-face 2133 :button-face 'custom-variable-button-face
2005 :sample-face 'custom-variable-tag-face 2134 :sample-face 'custom-variable-tag-face
2006 tag) 2135 tag)
2007 buttons) 2136 buttons)
2008 (insert " ") 2137 (insert " ")
2009 (push (widget-create-child-and-convert 2138 (push (widget-create-child-and-convert
2010 widget 'visibility 2139 widget 'visibility
2011 :help-echo "Hide the value of this option." 2140 :help-echo "Hide the value of this option."
2012 :action 'custom-toggle-parent 2141 :action 'custom-toggle-parent
2013 t) 2142 t)
2014 buttons) 2143 buttons)
2015 (push (widget-create-child-and-convert 2144 (push (widget-create-child-and-convert
2016 widget type 2145 widget type
2017 :format value-format 2146 :format value-format
2018 :value value) 2147 :value value)
2019 children)))) 2148 children))))
2020 (unless (eq custom-buffer-style 'tree) 2149 (unless (eq custom-buffer-style 'tree)
2021 ;; Now update the state.
2022 (unless (eq (preceding-char) ?\n) 2150 (unless (eq (preceding-char) ?\n)
2023 (widget-insert "\n")) 2151 (widget-insert "\n"))
2024 (if (eq state 'hidden)
2025 (widget-put widget :custom-state state)
2026 (custom-variable-state-set widget))
2027 ;; Create the magic button. 2152 ;; Create the magic button.
2028 (let ((magic (widget-create-child-and-convert 2153 (let ((magic (widget-create-child-and-convert
2029 widget 'custom-magic nil))) 2154 widget 'custom-magic nil)))
2030 (widget-put widget :custom-magic magic) 2155 (widget-put widget :custom-magic magic)
2031 (push magic buttons)) 2156 (push magic buttons))
2032 ;; Update properties. 2157 ;; ### NOTE: this is ugly!!!! I need to do update the :buttons property
2033 (widget-put widget :custom-form form) 2158 ;; before the call to `widget-default-format-handler'. Otherwise, I
2159 ;; loose my current `buttons'. This function shouldn't be called like
2160 ;; this anyway. The doc string widget should be added like the others.
2161 ;; --dv
2034 (widget-put widget :buttons buttons) 2162 (widget-put widget :buttons buttons)
2035 (widget-put widget :children children)
2036 ;; Insert documentation. 2163 ;; Insert documentation.
2037 (widget-default-format-handler widget ?h) 2164 (widget-default-format-handler widget ?h)
2165
2166 ;; The comment field
2167 (unless (eq state 'hidden)
2168 (let* ((comment (get symbol 'variable-comment))
2169 (comment-widget
2170 (widget-create-child-and-convert
2171 widget 'custom-comment
2172 :parent widget
2173 :value (or comment ""))))
2174 (widget-put widget :comment-widget comment-widget)
2175 ;; Don't push it !!! Custom assumes that the first child is the
2176 ;; value one.
2177 (setq children (append children (list comment-widget)))))
2178 ;; Update the rest of the properties properties.
2179 (widget-put widget :custom-form form)
2180 (widget-put widget :children children)
2181 ;; Now update the state.
2182 (if (eq state 'hidden)
2183 (widget-put widget :custom-state state)
2184 (custom-variable-state-set widget))
2038 ;; See also. 2185 ;; See also.
2039 (unless (eq state 'hidden) 2186 (unless (eq state 'hidden)
2040 (when (eq (widget-get widget :custom-level) 1) 2187 (when (eq (widget-get widget :custom-level) 1)
2041 (custom-add-parent-links widget)) 2188 (custom-add-parent-links widget))
2042 (custom-add-see-also widget))))) 2189 (custom-add-see-also widget)))))
2056 (let* ((symbol (widget-value widget)) 2203 (let* ((symbol (widget-value widget))
2057 (get (or (get symbol 'custom-get) 'default-value)) 2204 (get (or (get symbol 'custom-get) 'default-value))
2058 (value (if (default-boundp symbol) 2205 (value (if (default-boundp symbol)
2059 (funcall get symbol) 2206 (funcall get symbol)
2060 (widget-get widget :value))) 2207 (widget-get widget :value)))
2208 (comment (get symbol 'variable-comment))
2061 tmp 2209 tmp
2062 (state (cond ((setq tmp (get symbol 'customized-value)) 2210 temp
2211 (state (cond ((progn (setq tmp (get symbol 'customized-value))
2212 (setq temp
2213 (get symbol 'customized-variable-comment))
2214 (or tmp temp))
2063 (if (condition-case nil 2215 (if (condition-case nil
2064 (equal value (eval (car tmp))) 2216 (and (equal value (eval (car tmp)))
2217 (equal comment temp))
2065 (error nil)) 2218 (error nil))
2066 'set 2219 'set
2067 'changed)) 2220 'changed))
2068 ((setq tmp (get symbol 'saved-value)) 2221 ((progn (setq tmp (get symbol 'saved-value))
2222 (setq temp (get symbol 'saved-variable-comment))
2223 (or tmp temp))
2069 (if (condition-case nil 2224 (if (condition-case nil
2070 (equal value (eval (car tmp))) 2225 (and (equal value (eval (car tmp)))
2226 (equal comment temp))
2071 (error nil)) 2227 (error nil))
2072 'saved 2228 'saved
2073 'changed)) 2229 'changed))
2074 ((setq tmp (get symbol 'standard-value)) 2230 ((setq tmp (get symbol 'standard-value))
2075 (if (condition-case nil 2231 (if (condition-case nil
2076 (equal value (eval (car tmp))) 2232 (and (equal value (eval (car tmp)))
2233 (equal comment nil))
2077 (error nil)) 2234 (error nil))
2078 'standard 2235 'standard
2079 'changed)) 2236 'changed))
2080 (t 'rogue)))) 2237 (t 'rogue))))
2081 (widget-put widget :custom-state state))) 2238 (widget-put widget :custom-state state)))
2082 2239
2083 (defvar custom-variable-menu 2240 (defvar custom-variable-menu
2084 '(("Set for Current Session" custom-variable-set 2241 '(("Set for Current Session" custom-variable-set
2085 (lambda (widget) 2242 (lambda (widget)
2086 (eq (widget-get widget :custom-state) 'modified))) 2243 (eq (widget-get widget :custom-state) 'modified)))
2087 ("Save for Future Sessions" custom-variable-save 2244 ("Save for Future Sessions" custom-variable-save
2088 (lambda (widget) 2245 (lambda (widget)
2091 (lambda (widget) 2248 (lambda (widget)
2092 (and (default-boundp (widget-value widget)) 2249 (and (default-boundp (widget-value widget))
2093 (memq (widget-get widget :custom-state) '(modified changed))))) 2250 (memq (widget-get widget :custom-state) '(modified changed)))))
2094 ("Reset to Saved" custom-variable-reset-saved 2251 ("Reset to Saved" custom-variable-reset-saved
2095 (lambda (widget) 2252 (lambda (widget)
2096 (and (get (widget-value widget) 'saved-value) 2253 (and (or (get (widget-value widget) 'saved-value)
2254 (get (widget-value widget) 'saved-variable-comment))
2097 (memq (widget-get widget :custom-state) 2255 (memq (widget-get widget :custom-state)
2098 '(modified set changed rogue))))) 2256 '(modified set changed rogue)))))
2099 ("Reset to Standard Settings" custom-variable-reset-standard 2257 ("Reset to Standard Settings" custom-variable-reset-standard
2100 (lambda (widget) 2258 (lambda (widget)
2101 (and (get (widget-value widget) 'standard-value) 2259 (and (get (widget-value widget) 'standard-value)
2102 (memq (widget-get widget :custom-state) 2260 (memq (widget-get widget :custom-state)
2103 '(modified set changed saved rogue))))) 2261 '(modified set changed saved rogue)))))
2104 ("---" ignore ignore) 2262 ("---" ignore ignore)
2105 ("Don't show as Lisp expression" custom-variable-edit 2263 ("Add Comment" custom-comment-show custom-comment-invisible-p)
2264 ("---" ignore ignore)
2265 ("Don't show as Lisp expression" custom-variable-edit
2106 (lambda (widget) 2266 (lambda (widget)
2107 (eq (widget-get widget :custom-form) 'lisp))) 2267 (eq (widget-get widget :custom-form) 'lisp)))
2108 ("Show initial Lisp expression" custom-variable-edit-lisp 2268 ("Show initial Lisp expression" custom-variable-edit-lisp
2109 (lambda (widget) 2269 (lambda (widget)
2110 (eq (widget-get widget :custom-form) 'edit)))) 2270 (eq (widget-get widget :custom-form) 'edit))))
2150 (let* ((form (widget-get widget :custom-form)) 2310 (let* ((form (widget-get widget :custom-form))
2151 (state (widget-get widget :custom-state)) 2311 (state (widget-get widget :custom-state))
2152 (child (car (widget-get widget :children))) 2312 (child (car (widget-get widget :children)))
2153 (symbol (widget-value widget)) 2313 (symbol (widget-value widget))
2154 (set (or (get symbol 'custom-set) 'set-default)) 2314 (set (or (get symbol 'custom-set) 'set-default))
2155 val) 2315 (comment-widget (widget-get widget :comment-widget))
2316 (comment (widget-value comment-widget))
2317 val)
2156 (cond ((eq state 'hidden) 2318 (cond ((eq state 'hidden)
2157 (error "Cannot set hidden variable")) 2319 (error "Cannot set hidden variable"))
2158 ((setq val (widget-apply child :validate)) 2320 ((setq val (widget-apply child :validate))
2159 (goto-char (widget-get val :from)) 2321 (goto-char (widget-get val :from))
2160 (error "%s" (widget-get val :error))) 2322 (error "%s" (widget-get val :error)))
2161 ((memq form '(lisp mismatch)) 2323 ((memq form '(lisp mismatch))
2324 (when (equal comment "")
2325 (setq comment nil)
2326 ;; Make the comment invisible by hand if it's empty
2327 (overlay-put (widget-get comment-widget :comment-overlay)
2328 'invisible t))
2162 (funcall set symbol (eval (setq val (widget-value child)))) 2329 (funcall set symbol (eval (setq val (widget-value child))))
2163 (put symbol 'customized-value (list val))) 2330 (put symbol 'customized-value (list val))
2331 (put symbol 'variable-comment comment)
2332 (put symbol 'customized-variable-comment comment))
2164 (t 2333 (t
2334 (when (equal comment "")
2335 (setq comment nil)
2336 ;; Make the comment invisible by hand if it's empty
2337 (overlay-put (widget-get comment-widget :comment-overlay)
2338 'invisible t))
2165 (funcall set symbol (setq val (widget-value child))) 2339 (funcall set symbol (setq val (widget-value child)))
2166 (put symbol 'customized-value (list (custom-quote val))))) 2340 (put symbol 'customized-value (list (custom-quote val)))
2341 (put symbol 'variable-comment comment)
2342 (put symbol 'customized-variable-comment comment)))
2167 (custom-variable-state-set widget) 2343 (custom-variable-state-set widget)
2168 (custom-redraw-magic widget))) 2344 (custom-redraw-magic widget)))
2169 2345
2170 (defun custom-variable-save (widget) 2346 (defun custom-variable-save (widget)
2171 "Set and save the value for the variable being edited by WIDGET." 2347 "Set and save the value for the variable being edited by WIDGET."
2172 (let* ((form (widget-get widget :custom-form)) 2348 (let* ((form (widget-get widget :custom-form))
2173 (state (widget-get widget :custom-state)) 2349 (state (widget-get widget :custom-state))
2174 (child (car (widget-get widget :children))) 2350 (child (car (widget-get widget :children)))
2175 (symbol (widget-value widget)) 2351 (symbol (widget-value widget))
2176 (set (or (get symbol 'custom-set) 'set-default)) 2352 (set (or (get symbol 'custom-set) 'set-default))
2353 (comment-widget (widget-get widget :comment-widget))
2354 (comment (widget-value comment-widget))
2177 val) 2355 val)
2178 (cond ((eq state 'hidden) 2356 (cond ((eq state 'hidden)
2179 (error "Cannot set hidden variable")) 2357 (error "Cannot set hidden variable"))
2180 ((setq val (widget-apply child :validate)) 2358 ((setq val (widget-apply child :validate))
2181 (goto-char (widget-get val :from)) 2359 (goto-char (widget-get val :from))
2182 (error "%s" (widget-get val :error))) 2360 (error "%s" (widget-get val :error)))
2183 ((memq form '(lisp mismatch)) 2361 ((memq form '(lisp mismatch))
2362 (when (equal comment "")
2363 (setq comment nil)
2364 ;; Make the comment invisible by hand if it's empty
2365 (overlay-put (widget-get comment-widget :comment-overlay)
2366 'invisible t))
2184 (put symbol 'saved-value (list (widget-value child))) 2367 (put symbol 'saved-value (list (widget-value child)))
2185 (funcall set symbol (eval (widget-value child)))) 2368 (funcall set symbol (eval (widget-value child)))
2369 (put symbol 'variable-comment comment)
2370 (put symbol 'saved-variable-comment comment))
2186 (t 2371 (t
2187 (put symbol 2372 (when (equal comment "")
2188 'saved-value (list (custom-quote (widget-value 2373 (setq comment nil)
2189 child)))) 2374 ;; Make the comment invisible by hand if it's empty
2190 (funcall set symbol (widget-value child)))) 2375 (overlay-put (widget-get comment-widget :comment-overlay)
2376 'invisible t))
2377 (put symbol 'saved-value
2378 (list (custom-quote (widget-value child))))
2379 (funcall set symbol (widget-value child))
2380 (put symbol 'variable-comment comment)
2381 (put symbol 'saved-variable-comment comment)))
2191 (put symbol 'customized-value nil) 2382 (put symbol 'customized-value nil)
2383 (put symbol 'customized-variable-comment nil)
2192 (custom-save-all) 2384 (custom-save-all)
2193 (custom-variable-state-set widget) 2385 (custom-variable-state-set widget)
2194 (custom-redraw-magic widget))) 2386 (custom-redraw-magic widget)))
2195 2387
2196 (defun custom-variable-reset-saved (widget) 2388 (defun custom-variable-reset-saved (widget)
2197 "Restore the saved value for the variable being edited by WIDGET." 2389 "Restore the saved value for the variable being edited by WIDGET."
2198 (let* ((symbol (widget-value widget)) 2390 (let* ((symbol (widget-value widget))
2199 (set (or (get symbol 'custom-set) 'set-default))) 2391 (set (or (get symbol 'custom-set) 'set-default))
2200 (if (get symbol 'saved-value) 2392 (comment-widget (widget-get widget :comment-widget))
2201 (condition-case nil 2393 (value (get symbol 'saved-value))
2202 (funcall set symbol (eval (car (get symbol 'saved-value)))) 2394 (comment (get symbol 'saved-variable-comment)))
2203 (error nil)) 2395 (cond ((or value comment)
2204 (error "No saved value for %s" symbol)) 2396 (put symbol 'variable-comment comment)
2397 (condition-case nil
2398 (funcall set symbol (eval (car value)))
2399 (error nil)))
2400 (t
2401 (error "No saved value for %s" symbol)))
2205 (put symbol 'customized-value nil) 2402 (put symbol 'customized-value nil)
2403 (put symbol 'customized-variable-comment nil)
2206 (widget-put widget :custom-state 'unknown) 2404 (widget-put widget :custom-state 'unknown)
2405 ;; This call will possibly make the comment invisible
2207 (custom-redraw widget))) 2406 (custom-redraw widget)))
2208 2407
2209 (defun custom-variable-reset-standard (widget) 2408 (defun custom-variable-reset-standard (widget)
2210 "Restore the standard setting for the variable being edited by WIDGET." 2409 "Restore the standard setting for the variable being edited by WIDGET."
2211 (let* ((symbol (widget-value widget)) 2410 (let* ((symbol (widget-value widget))
2212 (set (or (get symbol 'custom-set) 'set-default))) 2411 (set (or (get symbol 'custom-set) 'set-default))
2412 (comment-widget (widget-get widget :comment-widget)))
2213 (if (get symbol 'standard-value) 2413 (if (get symbol 'standard-value)
2214 (funcall set symbol (eval (car (get symbol 'standard-value)))) 2414 (funcall set symbol (eval (car (get symbol 'standard-value))))
2215 (error "No standard setting known for %S" symbol)) 2415 (error "No standard setting known for %S" symbol))
2416 n (put symbol 'variable-comment nil)
2216 (put symbol 'customized-value nil) 2417 (put symbol 'customized-value nil)
2217 (when (get symbol 'saved-value) 2418 (put symbol 'customized-variable-comment nil)
2419 (when (or (get symbol 'saved-value) (get symbol 'saved-variable-comment))
2218 (put symbol 'saved-value nil) 2420 (put symbol 'saved-value nil)
2421 (put symbol 'saved-variable-comment nil)
2219 (custom-save-all)) 2422 (custom-save-all))
2220 (widget-put widget :custom-state 'unknown) 2423 (widget-put widget :custom-state 'unknown)
2424 ;; This call will possibly make the comment invisible
2221 (custom-redraw widget))) 2425 (custom-redraw widget)))
2222 2426
2223 ;;; The `custom-face-edit' Widget. 2427 ;;; The `custom-face-edit' Widget.
2224 2428
2225 (define-widget 'custom-face-edit 'checklist 2429 (define-widget 'custom-face-edit 'checklist
2226 "Edit face attributes." 2430 "Edit face attributes."
2227 :format "%t: %v" 2431 :format "%t: %v"
2228 :tag "Attributes" 2432 :tag "Attributes"
2229 :extra-offset 12 2433 :extra-offset 12
2230 :button-args '(:help-echo "Control whether this attribute have any effect.") 2434 :button-args '(:help-echo "Control whether this attribute has any effect.")
2231 :args (mapcar (lambda (att) 2435 :args (mapcar (lambda (att)
2232 (list 'group 2436 (list 'group
2233 :inline t 2437 :inline t
2234 :sibling-args (widget-get (nth 1 att) :sibling-args) 2438 :sibling-args (widget-get (nth 1 att) :sibling-args)
2235 (list 'const :format "" :value (nth 0 att)) 2439 (list 'const :format "" :value (nth 0 att))
2236 (nth 1 att))) 2440 (nth 1 att)))
2237 custom-face-attributes)) 2441 custom-face-attributes))
2238 2442
2239 ;;; The `custom-display' Widget. 2443 ;;; The `custom-display' Widget.
2240 2444
2336 :custom-reset-current 'custom-redraw 2540 :custom-reset-current 'custom-redraw
2337 :custom-reset-saved 'custom-face-reset-saved 2541 :custom-reset-saved 'custom-face-reset-saved
2338 :custom-reset-standard 'custom-face-reset-standard 2542 :custom-reset-standard 'custom-face-reset-standard
2339 :custom-menu 'custom-face-menu-create) 2543 :custom-menu 'custom-face-menu-create)
2340 2544
2341 (define-widget 'custom-face-all 'editable-list 2545 (define-widget 'custom-face-all 'editable-list
2342 "An editable list of display specifications and attributes." 2546 "An editable list of display specifications and attributes."
2343 :entry-format "%i %d %v" 2547 :entry-format "%i %d %v"
2344 :insert-button-args '(:help-echo "Insert new display specification here.") 2548 :insert-button-args '(:help-echo "Insert new display specification here.")
2345 :append-button-args '(:help-echo "Append new display specification here.") 2549 :append-button-args '(:help-echo "Append new display specification here.")
2346 :delete-button-args '(:help-echo "Delete this display specification.") 2550 :delete-button-args '(:help-echo "Delete this display specification.")
2355 2559
2356 (defun custom-display-unselected-match (widget value) 2560 (defun custom-display-unselected-match (widget value)
2357 "Non-nil if VALUE is an unselected display specification." 2561 "Non-nil if VALUE is an unselected display specification."
2358 (not (face-spec-set-match-display value (selected-frame)))) 2562 (not (face-spec-set-match-display value (selected-frame))))
2359 2563
2360 (define-widget 'custom-face-selected 'group 2564 (define-widget 'custom-face-selected 'group
2361 "Edit the attributes of the selected display in a face specification." 2565 "Edit the attributes of the selected display in a face specification."
2362 :args '((repeat :format "" 2566 :args '((repeat :format ""
2363 :inline t 2567 :inline t
2364 (group custom-display-unselected sexp)) 2568 (group custom-display-unselected sexp))
2365 (group (sexp :format "") custom-face-edit) 2569 (group (sexp :format "") custom-face-edit)
2371 "Converted version of the `custom-face-selected' widget.") 2575 "Converted version of the `custom-face-selected' widget.")
2372 2576
2373 (defun custom-face-value-create (widget) 2577 (defun custom-face-value-create (widget)
2374 "Create a list of the display specifications for WIDGET." 2578 "Create a list of the display specifications for WIDGET."
2375 (let ((buttons (widget-get widget :buttons)) 2579 (let ((buttons (widget-get widget :buttons))
2580 children
2376 (symbol (widget-get widget :value)) 2581 (symbol (widget-get widget :value))
2377 (tag (widget-get widget :tag)) 2582 (tag (widget-get widget :tag))
2378 (state (widget-get widget :custom-state)) 2583 (state (widget-get widget :custom-state))
2379 (begin (point)) 2584 (begin (point))
2380 (is-last (widget-get widget :custom-last)) 2585 (is-last (widget-get widget :custom-last))
2394 (if (eq custom-buffer-style 'face) 2599 (if (eq custom-buffer-style 'face)
2395 (insert " ") 2600 (insert " ")
2396 (widget-specify-sample widget begin (point)) 2601 (widget-specify-sample widget begin (point))
2397 (insert ": ")) 2602 (insert ": "))
2398 ;; Sample. 2603 ;; Sample.
2399 (and (string-match "XEmacs" emacs-version)
2400 ;; XEmacs cannot display uninitialized faces.
2401 (not (custom-facep symbol))
2402 (copy-face 'custom-face-empty symbol))
2403 (push (widget-create-child-and-convert widget 'item 2604 (push (widget-create-child-and-convert widget 'item
2404 :format "(%{%t%})" 2605 :format "(%{%t%})"
2405 :sample-face symbol 2606 :sample-face symbol
2406 :tag "sample") 2607 :tag "sample")
2407 buttons) 2608 buttons)
2408 ;; Visibility. 2609 ;; Visibility.
2409 (insert " ") 2610 (insert " ")
2410 (push (widget-create-child-and-convert 2611 (push (widget-create-child-and-convert
2411 widget 'visibility 2612 widget 'visibility
2412 :help-echo "Hide or show this face." 2613 :help-echo "Hide or show this face."
2413 :action 'custom-toggle-parent 2614 :action 'custom-toggle-parent
2414 (not (eq state 'hidden))) 2615 (not (eq state 'hidden)))
2415 buttons) 2616 buttons)
2421 (push magic buttons)) 2622 (push magic buttons))
2422 ;; Update buttons. 2623 ;; Update buttons.
2423 (widget-put widget :buttons buttons) 2624 (widget-put widget :buttons buttons)
2424 ;; Insert documentation. 2625 ;; Insert documentation.
2425 (widget-default-format-handler widget ?h) 2626 (widget-default-format-handler widget ?h)
2627 ;; The comment field
2628 (unless (eq state 'hidden)
2629 (let* ((comment (get symbol 'face-comment))
2630 (comment-widget
2631 (widget-create-child-and-convert
2632 widget 'custom-comment
2633 :parent widget
2634 :value (or comment ""))))
2635 (widget-put widget :comment-widget comment-widget)
2636 (push comment-widget children)))
2426 ;; See also. 2637 ;; See also.
2427 (unless (eq state 'hidden) 2638 (unless (eq state 'hidden)
2428 (when (eq (widget-get widget :custom-level) 1) 2639 (when (eq (widget-get widget :custom-level) 1)
2429 (custom-add-parent-links widget)) 2640 (custom-add-parent-links widget))
2430 (custom-add-see-also widget)) 2641 (custom-add-see-also widget))
2438 (widget-put widget :custom-form custom-face-default-form)) 2649 (widget-put widget :custom-form custom-face-default-form))
2439 (let* ((symbol (widget-value widget)) 2650 (let* ((symbol (widget-value widget))
2440 (spec (or (get symbol 'saved-face) 2651 (spec (or (get symbol 'saved-face)
2441 (get symbol 'face-defface-spec) 2652 (get symbol 'face-defface-spec)
2442 ;; Attempt to construct it. 2653 ;; Attempt to construct it.
2443 (list (list t (custom-face-attributes-get 2654 (list (list t (custom-face-attributes-get
2444 symbol (selected-frame)))))) 2655 symbol (selected-frame))))))
2445 (form (widget-get widget :custom-form)) 2656 (form (widget-get widget :custom-form))
2446 (indent (widget-get widget :indent)) 2657 (indent (widget-get widget :indent))
2447 edit) 2658 edit)
2448 ;; If the user has changed this face in some other way, 2659 ;; If the user has changed this face in some other way,
2450 (if (not (face-spec-match-p symbol spec (selected-frame))) 2661 (if (not (face-spec-match-p symbol spec (selected-frame)))
2451 (setq spec (list (list t (face-attr-construct symbol (selected-frame)))))) 2662 (setq spec (list (list t (face-attr-construct symbol (selected-frame))))))
2452 (setq edit (widget-create-child-and-convert 2663 (setq edit (widget-create-child-and-convert
2453 widget 2664 widget
2454 (cond ((and (eq form 'selected) 2665 (cond ((and (eq form 'selected)
2455 (widget-apply custom-face-selected 2666 (widget-apply custom-face-selected
2456 :match spec)) 2667 :match spec))
2457 (when indent (insert-char ?\ indent)) 2668 (when indent (insert-char ?\ indent))
2458 'custom-face-selected) 2669 'custom-face-selected)
2459 ((and (not (eq form 'lisp)) 2670 ((and (not (eq form 'lisp))
2460 (widget-apply custom-face-all 2671 (widget-apply custom-face-all
2461 :match spec)) 2672 :match spec))
2462 'custom-face-all) 2673 'custom-face-all)
2463 (t 2674 (t
2464 (when indent (insert-char ?\ indent)) 2675 (when indent (insert-char ?\ indent))
2465 'sexp)) 2676 'sexp))
2466 :value spec)) 2677 :value spec))
2467 (custom-face-state-set widget) 2678 (custom-face-state-set widget)
2468 (widget-put widget :children (list edit))) 2679 (push edit children)
2680 (widget-put widget :children children))
2469 (message "Creating face editor...done")))))) 2681 (message "Creating face editor...done"))))))
2470 2682
2471 (defvar custom-face-menu 2683 (defvar custom-face-menu
2472 '(("Set for Current Session" custom-face-set) 2684 '(("Set for Current Session" custom-face-set)
2473 ("Save for Future Sessions" custom-face-save-command) 2685 ("Save for Future Sessions" custom-face-save-command)
2474 ("Reset to Saved" custom-face-reset-saved 2686 ("Reset to Saved" custom-face-reset-saved
2475 (lambda (widget) 2687 (lambda (widget)
2476 (get (widget-value widget) 'saved-face))) 2688 (or (get (widget-value widget) 'saved-face)
2689 (get (widget-value widget) 'saved-face-comment))))
2477 ("Reset to Standard Setting" custom-face-reset-standard 2690 ("Reset to Standard Setting" custom-face-reset-standard
2478 (lambda (widget) 2691 (lambda (widget)
2479 (get (widget-value widget) 'face-defface-spec))) 2692 (get (widget-value widget) 'face-defface-spec)))
2693 ("---" ignore ignore)
2694 ("Add Comment" custom-comment-show custom-comment-invisible-p)
2480 ("---" ignore ignore) 2695 ("---" ignore ignore)
2481 ("Show all display specs" custom-face-edit-all 2696 ("Show all display specs" custom-face-edit-all
2482 (lambda (widget) 2697 (lambda (widget)
2483 (not (eq (widget-get widget :custom-form) 'all)))) 2698 (not (eq (widget-get widget :custom-form) 'all))))
2484 ("Just current attributes" custom-face-edit-selected 2699 ("Just current attributes" custom-face-edit-selected
2512 (widget-put widget :custom-form 'lisp) 2727 (widget-put widget :custom-form 'lisp)
2513 (custom-redraw widget)) 2728 (custom-redraw widget))
2514 2729
2515 (defun custom-face-state-set (widget) 2730 (defun custom-face-state-set (widget)
2516 "Set the state of WIDGET." 2731 "Set the state of WIDGET."
2517 (let ((symbol (widget-value widget))) 2732 (let* ((symbol (widget-value widget))
2518 (widget-put widget :custom-state (cond ((get symbol 'customized-face) 2733 (comment (get symbol 'face-comment))
2519 'set) 2734 tmp temp)
2520 ((get symbol 'saved-face) 2735 (widget-put widget :custom-state
2521 'saved) 2736 (cond ((progn
2522 ((get symbol 'face-defface-spec) 2737 (setq tmp (get symbol 'customized-face))
2523 'standard) 2738 (setq temp (get symbol 'customized-face-comment))
2524 (t 2739 (or tmp temp))
2525 'rogue))))) 2740 (if (equal temp comment)
2741 'set
2742 'changed))
2743 ((progn
2744 (setq tmp (get symbol 'saved-face))
2745 (setq temp (get symbol 'saved-face-comment))
2746 (or tmp temp))
2747 (if (equal temp comment)
2748 'saved
2749 'changed))
2750 ((get symbol 'face-defface-spec)
2751 (if (equal comment nil)
2752 'standard
2753 'changed))
2754 (t
2755 'rogue)))))
2526 2756
2527 (defun custom-face-action (widget &optional event) 2757 (defun custom-face-action (widget &optional event)
2528 "Show the menu for `custom-face' WIDGET. 2758 "Show the menu for `custom-face' WIDGET.
2529 Optional EVENT is the location for the menu." 2759 Optional EVENT is the location for the menu."
2530 (if (eq (widget-get widget :custom-state) 'hidden) 2760 (if (eq (widget-get widget :custom-state) 'hidden)
2541 2771
2542 (defun custom-face-set (widget) 2772 (defun custom-face-set (widget)
2543 "Make the face attributes in WIDGET take effect." 2773 "Make the face attributes in WIDGET take effect."
2544 (let* ((symbol (widget-value widget)) 2774 (let* ((symbol (widget-value widget))
2545 (child (car (widget-get widget :children))) 2775 (child (car (widget-get widget :children)))
2546 (value (widget-value child))) 2776 (value (widget-value child))
2777 (comment-widget (widget-get widget :comment-widget))
2778 (comment (widget-value comment-widget)))
2779 (when (equal comment "")
2780 (setq comment nil)
2781 ;; Make the comment invisible by hand if it's empty
2782 (overlay-put (widget-get comment-widget :comment-overlay)
2783 'invisible t))
2547 (put symbol 'customized-face value) 2784 (put symbol 'customized-face value)
2548 (face-spec-set symbol value) 2785 (face-spec-set symbol value)
2786 (put symbol 'customized-face-comment comment)
2787 (put symbol 'face-comment comment)
2549 (custom-face-state-set widget) 2788 (custom-face-state-set widget)
2550 (custom-redraw-magic widget))) 2789 (custom-redraw-magic widget)))
2551 2790
2552 (defun custom-face-save-command (widget) 2791 (defun custom-face-save-command (widget)
2553 "Save in `.emacs' the face attributes in WIDGET." 2792 "Save in `.emacs' the face attributes in WIDGET."
2556 2795
2557 (defun custom-face-save (widget) 2796 (defun custom-face-save (widget)
2558 "Prepare for saving WIDGET's face attributes, but don't write `.emacs'." 2797 "Prepare for saving WIDGET's face attributes, but don't write `.emacs'."
2559 (let* ((symbol (widget-value widget)) 2798 (let* ((symbol (widget-value widget))
2560 (child (car (widget-get widget :children))) 2799 (child (car (widget-get widget :children)))
2561 (value (widget-value child))) 2800 (value (widget-value child))
2801 (comment-widget (widget-get widget :comment-widget))
2802 (comment (widget-value comment-widget)))
2803 (when (equal comment "")
2804 (setq comment nil)
2805 ;; Make the comment invisible by hand if it's empty
2806 (overlay-put (widget-get comment-widget :comment-overlay)
2807 'invisible t))
2562 (face-spec-set symbol value) 2808 (face-spec-set symbol value)
2563 (put symbol 'saved-face value) 2809 (put symbol 'saved-face value)
2564 (put symbol 'customized-face nil) 2810 (put symbol 'customized-face nil)
2811 (put symbol 'face-comment comment)
2812 (put symbol 'customized-face-comment nil)
2813 (put symbol 'saved-face-comment comment)
2565 (custom-save-all) 2814 (custom-save-all)
2566 (custom-face-state-set widget) 2815 (custom-face-state-set widget)
2567 (custom-redraw-magic widget))) 2816 (custom-redraw-magic widget)))
2568 2817
2569 (defun custom-face-reset-saved (widget) 2818 (defun custom-face-reset-saved (widget)
2570 "Restore WIDGET to the face's default attributes." 2819 "Restore WIDGET to the face's default attributes."
2571 (let* ((symbol (widget-value widget)) 2820 (let* ((symbol (widget-value widget))
2572 (child (car (widget-get widget :children))) 2821 (child (car (widget-get widget :children)))
2573 (value (get symbol 'saved-face))) 2822 (value (get symbol 'saved-face))
2574 (unless value 2823 (comment (get symbol 'saved-face-comment))
2824 (comment-widget (widget-get widget :comment-widget)))
2825 (unless (or value comment)
2575 (error "No saved value for this face")) 2826 (error "No saved value for this face"))
2576 (put symbol 'customized-face nil) 2827 (put symbol 'customized-face nil)
2828 (put symbol 'customized-face-comment nil)
2577 (face-spec-set symbol value) 2829 (face-spec-set symbol value)
2830 (put symbol 'face-comment comment)
2578 (widget-value-set child value) 2831 (widget-value-set child value)
2832 ;; This call manages the comment visibility
2833 (widget-value-set comment-widget (or comment ""))
2579 (custom-face-state-set widget) 2834 (custom-face-state-set widget)
2580 (custom-redraw-magic widget))) 2835 (custom-redraw-magic widget)))
2581 2836
2582 (defun custom-face-reset-standard (widget) 2837 (defun custom-face-reset-standard (widget)
2583 "Restore WIDGET to the face's standard settings." 2838 "Restore WIDGET to the face's standard settings."
2584 (let* ((symbol (widget-value widget)) 2839 (let* ((symbol (widget-value widget))
2585 (child (car (widget-get widget :children))) 2840 (child (car (widget-get widget :children)))
2586 (value (get symbol 'face-defface-spec))) 2841 (value (get symbol 'face-defface-spec))
2842 (comment-widget (widget-get widget :comment-widget)))
2587 (unless value 2843 (unless value
2588 (error "No standard setting for this face")) 2844 (error "No standard setting for this face"))
2589 (put symbol 'customized-face nil) 2845 (put symbol 'customized-face nil)
2590 (when (get symbol 'saved-face) 2846 (put symbol 'customized-face-comment nil)
2847 (when (or (get symbol 'saved-face) (get symbol 'saved-face-comment))
2591 (put symbol 'saved-face nil) 2848 (put symbol 'saved-face nil)
2849 (put symbol 'saved-face-comment nil)
2592 (custom-save-all)) 2850 (custom-save-all))
2593 (face-spec-set symbol value) 2851 (face-spec-set symbol value)
2852 (put symbol 'face-comment nil)
2594 (widget-value-set child value) 2853 (widget-value-set child value)
2854 ;; This call manages the comment visibility
2855 (widget-value-set comment-widget "")
2595 (custom-face-state-set widget) 2856 (custom-face-state-set widget)
2596 (custom-redraw-magic widget))) 2857 (custom-redraw-magic widget)))
2597 2858
2598 ;;; The `face' Widget. 2859 ;;; The `face' Widget.
2599 2860
2637 "Prompt for a face." 2898 "Prompt for a face."
2638 (let ((answer (completing-read "Face: " 2899 (let ((answer (completing-read "Face: "
2639 (mapcar (lambda (face) 2900 (mapcar (lambda (face)
2640 (list (symbol-name face))) 2901 (list (symbol-name face)))
2641 (face-list)) 2902 (face-list))
2642 nil nil nil 2903 nil nil nil
2643 'face-history))) 2904 'face-history)))
2644 (unless (zerop (length answer)) 2905 (unless (zerop (length answer))
2645 (widget-value-set widget (intern answer)) 2906 (widget-value-set widget (intern answer))
2646 (widget-apply widget :notify widget event) 2907 (widget-apply widget :notify widget event)
2647 (widget-setup)))) 2908 (widget-setup))))
2661 :tag "Hook") 2922 :tag "Hook")
2662 2923
2663 (defun custom-hook-convert-widget (widget) 2924 (defun custom-hook-convert-widget (widget)
2664 ;; Handle `:custom-options'. 2925 ;; Handle `:custom-options'.
2665 (let* ((options (widget-get widget :options)) 2926 (let* ((options (widget-get widget :options))
2666 (other `(editable-list :inline t 2927 (other `(editable-list :inline t
2667 :entry-format "%i %d%v" 2928 :entry-format "%i %d%v"
2668 (function :format " %v"))) 2929 (function :format " %v")))
2669 (args (if options 2930 (args (if options
2670 (list `(checklist :inline t 2931 (list `(checklist :inline t
2671 ,@(mapcar (lambda (entry) 2932 ,@(mapcar (lambda (entry)
2688 2949
2689 ;;; The `custom-group' Widget. 2950 ;;; The `custom-group' Widget.
2690 2951
2691 (defcustom custom-group-tag-faces nil 2952 (defcustom custom-group-tag-faces nil
2692 ;; In XEmacs, this ought to play games with font size. 2953 ;; In XEmacs, this ought to play games with font size.
2954 ;; Fixme: make it do so in Emacs.
2693 "Face used for group tags. 2955 "Face used for group tags.
2694 The first member is used for level 1 groups, the second for level 2, 2956 The first member is used for level 1 groups, the second for level 2,
2695 and so forth. The remaining group tags are shown with 2957 and so forth. The remaining group tags are shown with
2696 `custom-group-tag-face'." 2958 `custom-group-tag-face'."
2697 :type '(repeat face) 2959 :type '(repeat face)
2773 (cond ((and (eq custom-buffer-style 'tree) 3035 (cond ((and (eq custom-buffer-style 'tree)
2774 (eq state 'hidden) 3036 (eq state 'hidden)
2775 (or members (custom-unloaded-widget-p widget))) 3037 (or members (custom-unloaded-widget-p widget)))
2776 (custom-browse-insert-prefix prefix) 3038 (custom-browse-insert-prefix prefix)
2777 (push (widget-create-child-and-convert 3039 (push (widget-create-child-and-convert
2778 widget 'custom-browse-visibility 3040 widget 'custom-browse-visibility
2779 ;; :tag-glyph "plus" 3041 ;; :tag-glyph "plus"
2780 :tag "+") 3042 :tag "+")
2781 buttons) 3043 buttons)
2782 (insert "-- ") 3044 (insert "-- ")
2783 ;; (widget-glyph-insert nil "-- " "horizontal") 3045 ;; (widget-glyph-insert nil "-- " "horizontal")
2790 (zerop (length members))) 3052 (zerop (length members)))
2791 (custom-browse-insert-prefix prefix) 3053 (custom-browse-insert-prefix prefix)
2792 (insert "[ ]-- ") 3054 (insert "[ ]-- ")
2793 ;; (widget-glyph-insert nil "[ ]" "empty") 3055 ;; (widget-glyph-insert nil "[ ]" "empty")
2794 ;; (widget-glyph-insert nil "-- " "horizontal") 3056 ;; (widget-glyph-insert nil "-- " "horizontal")
2795 (push (widget-create-child-and-convert 3057 (push (widget-create-child-and-convert
2796 widget 'custom-browse-group-tag) 3058 widget 'custom-browse-group-tag)
2797 buttons) 3059 buttons)
2798 (insert " " tag "\n") 3060 (insert " " tag "\n")
2799 (widget-put widget :buttons buttons)) 3061 (widget-put widget :buttons buttons))
2800 ((eq custom-buffer-style 'tree) 3062 ((eq custom-buffer-style 'tree)
2801 (custom-browse-insert-prefix prefix) 3063 (custom-browse-insert-prefix prefix)
2802 (custom-load-widget widget) 3064 (custom-load-widget widget)
2803 (if (zerop (length members)) 3065 (if (zerop (length members))
2804 (progn 3066 (progn
2805 (custom-browse-insert-prefix prefix) 3067 (custom-browse-insert-prefix prefix)
2806 (insert "[ ]-- ") 3068 (insert "[ ]-- ")
2807 ;; (widget-glyph-insert nil "[ ]" "empty") 3069 ;; (widget-glyph-insert nil "[ ]" "empty")
2808 ;; (widget-glyph-insert nil "-- " "horizontal") 3070 ;; (widget-glyph-insert nil "-- " "horizontal")
2809 (push (widget-create-child-and-convert 3071 (push (widget-create-child-and-convert
2810 widget 'custom-browse-group-tag) 3072 widget 'custom-browse-group-tag)
2811 buttons) 3073 buttons)
2812 (insert " " tag "\n") 3074 (insert " " tag "\n")
2813 (widget-put widget :buttons buttons)) 3075 (widget-put widget :buttons buttons))
2814 (push (widget-create-child-and-convert 3076 (push (widget-create-child-and-convert
2815 widget 'custom-browse-visibility 3077 widget 'custom-browse-visibility
2816 ;; :tag-glyph "minus" 3078 ;; :tag-glyph "minus"
2817 :tag "-") 3079 :tag "-")
2818 buttons) 3080 buttons)
2819 (insert "-\\ ") 3081 (insert "-\\ ")
2820 ;; (widget-glyph-insert nil "-\\ " "top") 3082 ;; (widget-glyph-insert nil "-\\ " "top")
2821 (push (widget-create-child-and-convert 3083 (push (widget-create-child-and-convert
2822 widget 'custom-browse-group-tag) 3084 widget 'custom-browse-group-tag)
2823 buttons) 3085 buttons)
2824 (insert " " tag "\n") 3086 (insert " " tag "\n")
2825 (widget-put widget :buttons buttons) 3087 (widget-put widget :buttons buttons)
2826 (message "Creating group...") 3088 (message "Creating group...")
2861 (widget-specify-sample widget begin (point))) 3123 (widget-specify-sample widget begin (point)))
2862 (insert " group: ") 3124 (insert " group: ")
2863 ;; Create link/visibility indicator. 3125 ;; Create link/visibility indicator.
2864 (if (eq custom-buffer-style 'links) 3126 (if (eq custom-buffer-style 'links)
2865 (push (widget-create-child-and-convert 3127 (push (widget-create-child-and-convert
2866 widget 'custom-group-link 3128 widget 'custom-group-link
2867 :tag "Go to Group" 3129 :tag "Go to Group"
2868 symbol) 3130 symbol)
2869 buttons) 3131 buttons)
2870 (push (widget-create-child-and-convert 3132 (push (widget-create-child-and-convert
2871 widget 'custom-group-visibility 3133 widget 'custom-group-visibility
2872 :help-echo "Show members of this group." 3134 :help-echo "Show members of this group."
2873 :action 'custom-toggle-parent 3135 :action 'custom-toggle-parent
2874 (not (eq state 'hidden))) 3136 (not (eq state 'hidden)))
2875 buttons)) 3137 buttons))
2903 (widget-specify-sample widget start (point))) 3165 (widget-specify-sample widget start (point)))
2904 (insert " group: ") 3166 (insert " group: ")
2905 ;; Create visibility indicator. 3167 ;; Create visibility indicator.
2906 (unless (eq custom-buffer-style 'links) 3168 (unless (eq custom-buffer-style 'links)
2907 (insert "--------") 3169 (insert "--------")
2908 (push (widget-create-child-and-convert 3170 (push (widget-create-child-and-convert
2909 widget 'visibility 3171 widget 'visibility
2910 :help-echo "Hide members of this group." 3172 :help-echo "Hide members of this group."
2911 :action 'custom-toggle-parent 3173 :action 'custom-toggle-parent
2912 (not (eq state 'hidden))) 3174 (not (eq state 'hidden)))
2913 buttons) 3175 buttons)
2914 (insert " ")) 3176 (insert " "))
2915 ;; Create more dashes. 3177 ;; Create more dashes.
2916 ;; Use 76 instead of 75 to compensate for the temporary "<" 3178 ;; Use 76 instead of 75 to compensate for the temporary "<"
2917 ;; added by `widget-insert'. 3179 ;; added by `widget-insert'.
2918 (insert-char ?- (- 76 (current-column) 3180 (insert-char ?- (- 76 (current-column)
2919 (* custom-buffer-indent level))) 3181 (* custom-buffer-indent level)))
2920 (insert "\\\n") 3182 (insert "\\\n")
2921 ;; Create magic button. 3183 ;; Create magic button.
2922 (let ((magic (widget-create-child-and-convert 3184 (let ((magic (widget-create-child-and-convert
2923 widget 'custom-magic 3185 widget 'custom-magic
2924 :indent 0 3186 :indent 0
2925 nil))) 3187 nil)))
2926 (widget-put widget :custom-magic magic) 3188 (widget-put widget :custom-magic magic)
2927 (push magic buttons)) 3189 (push magic buttons))
2928 ;; Update buttons. 3190 ;; Update buttons.
2933 (if nil ;;; This should test that the buffer 3195 (if nil ;;; This should test that the buffer
2934 ;;; was not made to display a group. 3196 ;;; was not made to display a group.
2935 (when (eq level 1) 3197 (when (eq level 1)
2936 (insert-char ?\ custom-buffer-indent) 3198 (insert-char ?\ custom-buffer-indent)
2937 (custom-add-parent-links widget))) 3199 (custom-add-parent-links widget)))
2938 (custom-add-see-also widget 3200 (custom-add-see-also widget
2939 (make-string (* custom-buffer-indent level) 3201 (make-string (* custom-buffer-indent level)
2940 ?\ )) 3202 ?\ ))
2941 ;; Members. 3203 ;; Members.
2942 (message "Creating group...") 3204 (message "Creating group...")
2943 (custom-load-widget widget) 3205 (custom-load-widget widget)
2977 (insert-char ?\ (* custom-buffer-indent (1- level))) 3239 (insert-char ?\ (* custom-buffer-indent (1- level)))
2978 (insert "\\- " (widget-get widget :tag) " group end ") 3240 (insert "\\- " (widget-get widget :tag) " group end ")
2979 (insert-char ?- (- 75 (current-column) (* custom-buffer-indent level))) 3241 (insert-char ?- (- 75 (current-column) (* custom-buffer-indent level)))
2980 (insert "/\n"))))) 3242 (insert "/\n")))))
2981 3243
2982 (defvar custom-group-menu 3244 (defvar custom-group-menu
2983 '(("Set for Current Session" custom-group-set 3245 '(("Set for Current Session" custom-group-set
2984 (lambda (widget) 3246 (lambda (widget)
2985 (eq (widget-get widget :custom-state) 'modified))) 3247 (eq (widget-get widget :custom-state) 'modified)))
2986 ("Save for Future Sessions" custom-group-save 3248 ("Save for Future Sessions" custom-group-save
2987 (lambda (widget) 3249 (lambda (widget)
2998 "Alist of actions for the `custom-group' widget. 3260 "Alist of actions for the `custom-group' widget.
2999 Each entry has the form (NAME ACTION FILTER) where NAME is the name of 3261 Each entry has the form (NAME ACTION FILTER) where NAME is the name of
3000 the menu entry, ACTION is the function to call on the widget when the 3262 the menu entry, ACTION is the function to call on the widget when the
3001 menu is selected, and FILTER is a predicate which takes a `custom-group' 3263 menu is selected, and FILTER is a predicate which takes a `custom-group'
3002 widget as an argument, and returns non-nil if ACTION is valid on that 3264 widget as an argument, and returns non-nil if ACTION is valid on that
3003 widget. If FILTER is nil, ACTION is always valid.") 3265 widget. If FILTER is nil, ACTION is always valid.")
3004 3266
3005 (defun custom-group-action (widget &optional event) 3267 (defun custom-group-action (widget &optional event)
3006 "Show the menu for `custom-group' WIDGET. 3268 "Show the menu for `custom-group' WIDGET.
3007 Optional EVENT is the location for the menu." 3269 Optional EVENT is the location for the menu."
3008 (if (eq (widget-get widget :custom-state) 'hidden) 3270 (if (eq (widget-get widget :custom-state) 'hidden)
3138 (lambda (symbol) 3400 (lambda (symbol)
3139 (let ((value (get symbol 'saved-value)) 3401 (let ((value (get symbol 'saved-value))
3140 (requests (get symbol 'custom-requests)) 3402 (requests (get symbol 'custom-requests))
3141 (now (not (or (get symbol 'standard-value) 3403 (now (not (or (get symbol 'standard-value)
3142 (and (not (boundp symbol)) 3404 (and (not (boundp symbol))
3143 (not (get symbol 'force-value))))))) 3405 (not (get symbol 'force-value))))))
3144 (princ "\n '(") 3406 (comment (get symbol 'saved-variable-comment))
3145 (princ symbol) 3407 sep)
3146 (princ " ") 3408 (when (or value comment)
3147 (prin1 (car value)) 3409 (princ "\n '(")
3148 (cond (requests 3410 (prin1 symbol)
3149 (if now 3411 (princ " ")
3150 (princ " t ") 3412 (prin1 (car value))
3151 (princ " nil ")) 3413 (cond ((or now requests comment)
3152 (prin1 requests) 3414 (princ " ")
3153 (princ ")")) 3415 (if now
3154 (now 3416 (princ "t")
3155 (princ " t)")) 3417 (princ "nil"))
3156 (t 3418 (cond ((or requests comment)
3157 (princ ")"))))) 3419 (princ " ")
3420 (if requests
3421 (prin1 requests)
3422 (princ "nil"))
3423 (cond (comment
3424 (princ " ")
3425 (prin1 comment)
3426 (princ ")"))
3427 (t
3428 (princ ")"))))
3429 (t
3430 (princ ")"))))
3431 (t
3432 (princ ")"))))))
3158 saved-list) 3433 saved-list)
3159 (princ ")") 3434 (princ ")")
3160 (unless (looking-at "\n") 3435 (unless (looking-at "\n")
3161 (princ "\n"))))) 3436 (princ "\n")))))
3162 3437
3179 (unless (bolp) 3454 (unless (bolp)
3180 (princ "\n")) 3455 (princ "\n"))
3181 (princ "(custom-set-faces") 3456 (princ "(custom-set-faces")
3182 (mapcar 3457 (mapcar
3183 (lambda (symbol) 3458 (lambda (symbol)
3184 (let ((value (get symbol 'saved-face))) 3459 (let ((value (get symbol 'saved-face))
3460 (now (not (or (get 'default 'face-defface-spec)
3461 (and (not (custom-facep 'default))
3462 (not (get 'default 'force-face))))))
3463 (comment (get 'default 'saved-face-comment)))
3185 (unless (eq symbol 'default)) 3464 (unless (eq symbol 'default))
3186 ;; Don't print default face here. 3465 ;; Don't print default face here.
3187 (princ "\n '(") 3466 (princ "\n '(")
3188 (princ symbol) 3467 (prin1 symbol)
3189 (princ " ") 3468 (princ " ")
3190 (prin1 value) 3469 (prin1 value)
3191 (if (or (get symbol 'face-defface-spec) 3470 (cond ((or now comment)
3192 (and (not (custom-facep symbol)) 3471 (princ " ")
3193 (not (get symbol 'force-face)))) 3472 (if now
3194 (princ ")") 3473 (princ "t")
3195 (princ " t)")))) 3474 (princ "nil"))
3475 (cond (comment
3476 (princ " ")
3477 (prin1 comment)
3478 (princ ")"))
3479 (t
3480 (princ ")"))))
3481 (t
3482 (princ ")")))))
3196 saved-list) 3483 saved-list)
3197 (princ ")") 3484 (princ ")")
3198 (unless (looking-at "\n") 3485 (unless (looking-at "\n")
3199 (princ "\n"))))) 3486 (princ "\n")))))
3200 3487
3202 (defun customize-save-customized () 3489 (defun customize-save-customized ()
3203 "Save all user options which have been set in this session." 3490 "Save all user options which have been set in this session."
3204 (interactive) 3491 (interactive)
3205 (mapatoms (lambda (symbol) 3492 (mapatoms (lambda (symbol)
3206 (let ((face (get symbol 'customized-face)) 3493 (let ((face (get symbol 'customized-face))
3207 (value (get symbol 'customized-value))) 3494 (value (get symbol 'customized-value))
3208 (when face 3495 (face-comment (get symbol 'customized-face-comment))
3496 (variable-comment
3497 (get symbol 'customized-variable-comment)))
3498 (when face
3209 (put symbol 'saved-face face) 3499 (put symbol 'saved-face face)
3210 (put symbol 'customized-face nil)) 3500 (put symbol 'customized-face nil))
3211 (when value 3501 (when value
3212 (put symbol 'saved-value value) 3502 (put symbol 'saved-value value)
3213 (put symbol 'customized-value nil))))) 3503 (put symbol 'customized-value nil))
3504 (when variable-comment
3505 (put symbol 'saved-variable-comment variable-comment)
3506 (put symbol 'customized-variable-comment nil))
3507 (when face-comment
3508 (put symbol 'saved-face-comment face-comment)
3509 (put symbol 'customized-face-comment nil)))))
3214 ;; We really should update all custom buffers here. 3510 ;; We really should update all custom buffers here.
3215 (custom-save-all)) 3511 (custom-save-all))
3216 3512
3217 ;;;###autoload 3513 ;;;###autoload
3218 (defun custom-save-all () 3514 (defun custom-save-all ()
3257 (vector (custom-unlispify-menu-entry symbol) 3553 (vector (custom-unlispify-menu-entry symbol)
3258 `(customize-variable ',symbol) 3554 `(customize-variable ',symbol)
3259 ':style 'toggle 3555 ':style 'toggle
3260 ':selected symbol))) 3556 ':selected symbol)))
3261 3557
3262 (if (string-match "XEmacs" emacs-version) 3558 ;; Fixme: sort out use of :filter in Emacs
3559 (if nil ; (string-match "XEmacs" emacs-version)
3263 ;; XEmacs can create menus dynamically. 3560 ;; XEmacs can create menus dynamically.
3264 (defun custom-group-menu-create (widget symbol) 3561 (defun custom-group-menu-create (widget symbol)
3265 "Ignoring WIDGET, create a menu entry for customization group SYMBOL." 3562 "Ignoring WIDGET, create a menu entry for customization group SYMBOL."
3266 `( ,(custom-unlispify-menu-entry symbol t) 3563 `( ,(custom-unlispify-menu-entry symbol t)
3267 :filter (lambda (&rest junk) 3564 :filter (lambda (&rest junk)
3301 item))) 3598 item)))
3302 3599
3303 ;;;###autoload 3600 ;;;###autoload
3304 (defun customize-menu-create (symbol &optional name) 3601 (defun customize-menu-create (symbol &optional name)
3305 "Return a customize menu for customization group SYMBOL. 3602 "Return a customize menu for customization group SYMBOL.
3306 If optional NAME is given, use that as the name of the menu. 3603 If optional NAME is given, use that as the name of the menu.
3307 Otherwise the menu will be named `Customize'. 3604 Otherwise the menu will be named `Customize'.
3308 The format is suitable for use with `easy-menu-define'." 3605 The format is suitable for use with `easy-menu-define'."
3309 (unless name 3606 (unless name
3310 (setq name "Customize")) 3607 (setq name "Customize"))
3311 (if (string-match "XEmacs" emacs-version) 3608 ;; Fixme: sort out use of :filter in Emacs
3609 (if nil ;(string-match "XEmacs" emacs-version)
3312 ;; We can delay it under XEmacs. 3610 ;; We can delay it under XEmacs.
3313 `(,name 3611 `(,name
3314 :filter (lambda (&rest junk) 3612 :filter (lambda (&rest junk)
3315 (cdr (custom-menu-create ',symbol)))) 3613 (cdr (custom-menu-create ',symbol))))
3316 ;; But we must create it now under Emacs. 3614 ;; But we must create it now under Emacs.
3325 (setq custom-mode-map (make-sparse-keymap)) 3623 (setq custom-mode-map (make-sparse-keymap))
3326 (set-keymap-parent custom-mode-map widget-keymap) 3624 (set-keymap-parent custom-mode-map widget-keymap)
3327 (suppress-keymap custom-mode-map) 3625 (suppress-keymap custom-mode-map)
3328 (define-key custom-mode-map " " 'scroll-up) 3626 (define-key custom-mode-map " " 'scroll-up)
3329 (define-key custom-mode-map "\177" 'scroll-down) 3627 (define-key custom-mode-map "\177" 'scroll-down)
3330 (define-key custom-mode-map "q" 'bury-buffer) 3628 (define-key custom-mode-map "q" 'Custom-buffer-done)
3331 (define-key custom-mode-map "u" 'Custom-goto-parent) 3629 (define-key custom-mode-map "u" 'Custom-goto-parent)
3332 (define-key custom-mode-map "n" 'widget-forward) 3630 (define-key custom-mode-map "n" 'widget-forward)
3333 (define-key custom-mode-map "p" 'widget-backward) 3631 (define-key custom-mode-map "p" 'widget-backward)
3334 (define-key custom-mode-map [mouse-1] 'Custom-move-and-invoke)) 3632 (define-key custom-mode-map [mouse-1] 'Custom-move-and-invoke))
3335 3633
3341 (let* ((pos (widget-event-point event)) 3639 (let* ((pos (widget-event-point event))
3342 (button (get-char-property pos 'button))) 3640 (button (get-char-property pos 'button)))
3343 (if button 3641 (if button
3344 (widget-button-click event))))) 3642 (widget-button-click event)))))
3345 3643
3346 (easy-menu-define Custom-mode-menu 3644 (easy-menu-define Custom-mode-menu
3347 custom-mode-map 3645 custom-mode-map
3348 "Menu used in customization buffers." 3646 "Menu used in customization buffers."
3349 `("Custom" 3647 `("Custom"
3350 ,(customize-menu-create 'customize) 3648 ,(customize-menu-create 'customize)
3351 ["Set" Custom-set t] 3649 ["Set" Custom-set t]
3365 (let* ((button (get-char-property (point) 'button)) 3663 (let* ((button (get-char-property (point) 'button))
3366 (parent (downcase (widget-get button :tag)))) 3664 (parent (downcase (widget-get button :tag))))
3367 (customize-group parent))))) 3665 (customize-group parent)))))
3368 3666
3369 (defcustom custom-mode-hook nil 3667 (defcustom custom-mode-hook nil
3370 "Hook called when entering custom-mode." 3668 "Hook called when entering Custom mode."
3371 :type 'hook 3669 :type 'hook
3372 :group 'custom-buffer ) 3670 :group 'custom-buffer )
3373 3671
3374 (defun custom-state-buffer-message (widget) 3672 (defun custom-state-buffer-message (widget)
3375 (if (eq (widget-get (widget-get widget :parent) :custom-state) 'modified) 3673 (if (eq (widget-get (widget-get widget :parent) :custom-state) 'modified)
3403 (make-local-variable 'custom-options) 3701 (make-local-variable 'custom-options)
3404 (make-local-variable 'widget-documentation-face) 3702 (make-local-variable 'widget-documentation-face)
3405 (setq widget-documentation-face 'custom-documentation-face) 3703 (setq widget-documentation-face 'custom-documentation-face)
3406 (make-local-variable 'widget-button-face) 3704 (make-local-variable 'widget-button-face)
3407 (setq widget-button-face 'custom-button-face) 3705 (setq widget-button-face 'custom-button-face)
3706 (set (make-local-variable 'widget-button-pressed-face)
3707 'custom-button-pressed-face)
3708 (set (make-local-variable 'widget-mouse-face)
3709 'custom-button-pressed-face) ; buttons `depress' when moused
3710 ;; When possible, use relief for buttons, not bracketing. This test
3711 ;; may not be optimal.
3712 (when custom-raised-buttons
3713 (set (make-local-variable 'widget-push-button-prefix) "")
3714 (set (make-local-variable 'widget-push-button-suffix) "")
3715 (set (make-local-variable 'widget-link-prefix) "")
3716 (set (make-local-variable 'widget-link-suffix) ""))
3408 (make-local-hook 'widget-edit-functions) 3717 (make-local-hook 'widget-edit-functions)
3409 (add-hook 'widget-edit-functions 'custom-state-buffer-message nil t) 3718 (add-hook 'widget-edit-functions 'custom-state-buffer-message nil t)
3410 (run-hooks 'custom-mode-hook)) 3719 (run-hooks 'custom-mode-hook))
3411 3720
3412 ;;; The End. 3721 ;;; The End.
3413 3722
3414 (provide 'cus-edit) 3723 (provide 'cus-edit)
3415 3724
3416 ;; cus-edit.el ends here 3725 ;;; cus-edit.el ends here