Mercurial > emacs
changeset 18364:01666331d10f
Synched with 1.9930.
author | Per Abrahamsen <abraham@dina.kvl.dk> |
---|---|
date | Sat, 21 Jun 1997 12:48:00 +0000 |
parents | 31e4a16368c9 |
children | ceb9388fe67f |
files | lisp/cus-edit.el lisp/wid-edit.el |
diffstat | 2 files changed, 556 insertions(+), 354 deletions(-) [+] |
line wrap: on
line diff
--- a/lisp/cus-edit.el Sat Jun 21 07:37:53 1997 +0000 +++ b/lisp/cus-edit.el Sat Jun 21 12:48:00 1997 +0000 @@ -4,7 +4,7 @@ ;; ;; Author: Per Abrahamsen <abraham@dina.kvl.dk> ;; Keywords: help, faces -;; Version: 1.9924 +;; Version: 1.9929 ;; X-URL: http://www.dina.kvl.dk/~abraham/custom/ ;; This file is part of GNU Emacs. @@ -45,7 +45,8 @@ (require 'cus-start) (error nil)) -(define-widget-keywords :custom-category :custom-prefixes :custom-menu +(define-widget-keywords :custom-last :custom-prefix :custom-category + :custom-prefixes :custom-menu :custom-show :custom-magic :custom-state :custom-level :custom-form :custom-set :custom-save :custom-reset-current :custom-reset-saved @@ -343,6 +344,18 @@ ;;; Utilities. +(defun custom-last (x &optional n) + ;; Stolen from `cl.el'. + "Returns the last link in the list LIST. +With optional argument N, returns Nth-to-last link (default 1)." + (if n + (let ((m 0) (p x)) + (while (consp p) (incf m) (pop p)) + (if (<= n 0) p + (if (< n m) (nthcdr (- m n) x) x))) + (while (consp (cdr x)) (pop x)) + x)) + (defun custom-quote (sexp) "Quote SEXP iff it is not self quoting." (if (or (memq sexp '(t nil)) @@ -532,59 +545,55 @@ ;;; Sorting. -(defcustom custom-buffer-sort-predicate 'ignore - "Function used for sorting group members in buffers. -The value should be useful as a predicate for `sort'. -The list to be sorted is the value of the groups `custom-group' property." - :type '(radio (const :tag "Unsorted" ignore) - (const :tag "Alphabetic" custom-sort-items-alphabetically) - (function :tag "Other")) +(defcustom custom-buffer-sort-alphabetically nil + "If non-nil, sort the members of each customization group alphabetically." + :type 'boolean :group 'custom-buffer) -(defcustom custom-buffer-order-predicate 'custom-sort-groups-last - "Function used for sorting group members in buffers. -The value should be useful as a predicate for `sort'. -The list to be sorted is the value of the groups `custom-group' property." - :type '(radio (const :tag "Groups first" custom-sort-groups-first) - (const :tag "Groups last" custom-sort-groups-last) - (function :tag "Other")) +(defcustom custom-buffer-groups-last nil + "If non-nil, put subgroups after all ordinary options within a group." + :type 'boolean :group 'custom-buffer) -(defcustom custom-menu-sort-predicate 'ignore - "Function used for sorting group members in menus. -The value should be useful as a predicate for `sort'. -The list to be sorted is the value of the groups `custom-group' property." - :type '(radio (const :tag "Unsorted" ignore) - (const :tag "Alphabetic" custom-sort-items-alphabetically) - (function :tag "Other")) +(defcustom custom-menu-sort-alphabetically nil + "If non-nil, sort the members of each customization group alphabetically." + :type 'boolean + :group 'custom-menu) + +(defcustom custom-menu-groups-first t + "If non-nil, put subgroups before all ordinary options within a group." + :type 'boolean :group 'custom-menu) -(defcustom custom-menu-order-predicate 'custom-sort-groups-first - "Function used for sorting group members in menus. -The value should be useful as a predicate for `sort'. -The list to be sorted is the value of the groups `custom-group' property." - :type '(radio (const :tag "Groups first" custom-sort-groups-first) - (const :tag "Groups last" custom-sort-groups-last) - (function :tag "Other")) - :group 'custom-menu) - -(defun custom-sort-items-alphabetically (a b) - "Return t iff A is alphabetically before B and the same custom type. +(defun custom-buffer-sort-predicate (a b) + "Return t iff A should come before B in a customization buffer. A and B should be members of a `custom-group' property." - (and (eq (nth 1 a) (nth 1 b)) - (string-lessp (symbol-name (nth 0 a)) (symbol-name (nth 0 b))))) + (cond ((and (not custom-buffer-groups-last) + (not custom-buffer-sort-alphabetically)) + nil) + ((or (eq (eq (nth 1 a) 'custom-group) (eq (nth 1 b) 'custom-group)) + (not custom-buffer-groups-last)) + (if custom-buffer-sort-alphabetically + (string-lessp (symbol-name (nth 0 a)) (symbol-name (nth 0 b))) + nil)) + (t + (not (eq (nth 1 a) 'custom-group) )))) -(defun custom-sort-groups-first (a b) - "Return t iff A a custom group and B is a not. +(defalias 'custom-browse-sort-predicate 'ignore) + +(defun custom-menu-sort-predicate (a b) + "Return t iff A should come before B in a customization menu. A and B should be members of a `custom-group' property." - (and (eq (nth 1 a) 'custom-group) - (not (eq (nth 1 b) 'custom-group)))) - -(defun custom-sort-groups-last (a b) - "Return t iff B a custom group and A is a not. -A and B should be members of a `custom-group' property." - (and (eq (nth 1 b) 'custom-group) - (not (eq (nth 1 a) 'custom-group)))) + (cond ((and (not custom-menu-groups-first) + (not custom-menu-sort-alphabetically)) + nil) + ((or (eq (eq (nth 1 a) 'custom-group) (eq (nth 1 b) 'custom-group)) + (not custom-menu-groups-first)) + (if custom-menu-sort-alphabetically + (string-lessp (symbol-name (nth 0 a)) (symbol-name (nth 0 b))) + nil)) + (t + (eq (nth 1 a) 'custom-group) ))) ;;; Custom Mode Commands. @@ -894,11 +903,9 @@ (push (list symbol 'custom-variable) found))))) (if (not found) (error "No matches") - (custom-buffer-create (sort (sort found - ;; Apropos should always be sorted. - 'custom-sort-items-alphabetically) - custom-buffer-order-predicate) - "*Customize Apropos*")))) + (let ((custom-buffer-sort-alphabetically t)) + (custom-buffer-create (sort found 'custom-buffer-sort-predicate) + "*Customize Apropos*"))))) ;;;###autoload (defun customize-apropos-options (regexp &optional arg) @@ -921,6 +928,21 @@ ;;; Buffer. +(defcustom custom-buffer-style 'links + "Control the presentation style for customization buffers. +The value should be a symbol, one of: + +brackets: groups nest within each other with big horizontal brackets. +links: groups have links to subgroups." + :type '(radio (const brackets) + (const links)) + :group 'custom-buffer) + +(defcustom custom-buffer-indent 3 + "Number of spaces to indent nested groups." + :type 'integer + :group 'custom-buffer) + ;;;###autoload (defun custom-buffer-create (options &optional name) "Create a buffer containing OPTIONS. @@ -1036,41 +1058,73 @@ options)))) (unless (eq (preceding-char) ?\n) (widget-insert "\n")) - (when (= (length options) 1) - (message "Creating parent links...") - (let* ((entry (nth 0 options)) - (name (nth 0 entry)) - (type (nth 1 entry)) - parents) - (mapatoms (lambda (symbol) - (let ((group (get symbol 'custom-group))) - (when (assq name group) - (when (eq type (nth 1 (assq name group))) - (push symbol parents)))))) - (when parents - (goto-char (point-min)) - (search-forward "[Set]") - (forward-line 1) - (widget-insert "\nParent groups:") - (mapcar (lambda (group) - (widget-insert " ") - (widget-create 'link - :tag (custom-unlispify-tag-name group) - :help-echo (format "\ -Create customize buffer for `%S' group." group) - :action (lambda (widget &rest ignore) - (customize-group - (widget-value widget))) - group)) - parents) - (widget-insert "\n")))) - (message "Creating customization magic...") - (mapcar 'custom-magic-reset custom-options) + (unless (eq custom-buffer-style 'tree) + (mapcar 'custom-magic-reset custom-options)) (message "Creating customization setup...") (widget-setup) (goto-char (point-min)) (message "Creating customization buffer...done")) +;;; The Tree Browser. + +;;;###autoload +(defun customize-browse () + "Create a tree browser for the customize hierarchy." + (interactive) + (let ((name "*Customize Browser*")) + (kill-buffer (get-buffer-create name)) + (switch-to-buffer (get-buffer-create name))) + (custom-mode) + (widget-insert "\ +Invoke [+] below to expand items, and [-] to collapse items. +Invoke the [group], [face], and [option] buttons below to edit that +item in another window.\n\n") + (let ((custom-buffer-style 'tree)) + (widget-create 'custom-group + :custom-last t + :custom-state 'unknown + :tag (custom-unlispify-tag-name 'emacs) + :value 'emacs)) + (goto-char (point-min))) + +(define-widget 'custom-tree-visibility 'item + "Control visibility of of items in the customize tree browser." + :button-prefix "[" + :button-suffix "]" + :format "%[%t%]" + :action 'custom-tree-visibility-action) + +(defun custom-tree-visibility-action (widget &rest ignore) + (let ((custom-buffer-style 'tree)) + (custom-toggle-parent widget))) + +(define-widget 'custom-tree-group-tag 'push-button + "Show parent in other window when activated." + :tag "group" + :action 'custom-tree-group-tag-action) + +(defun custom-tree-group-tag-action (widget &rest ignore) + (let ((parent (widget-get widget :parent))) + (customize-group-other-window (widget-value parent)))) + +(define-widget 'custom-tree-variable-tag 'push-button + "Show parent in other window when activated." + :tag "option" + :action 'custom-tree-variable-tag-action) + +(defun custom-tree-variable-tag-action (widget &rest ignore) + (let ((parent (widget-get widget :parent))) + (customize-variable-other-window (widget-value parent)))) + +(define-widget 'custom-tree-face-tag 'push-button + "Show parent in other window when activated." + :tag "face" + :action 'custom-tree-face-tag-action) + +(defun custom-tree-face-tag-action (widget &rest ignore) + (let ((parent (widget-get widget :parent))) + (customize-face-other-window (widget-value parent)))) + ;;; Modification of Basic Widgets. ;; ;; We add extra properties to the basic widgets needed here. This is @@ -1269,7 +1323,8 @@ (memq category custom-magic-show-hidden))) (insert " ") (when (eq category 'group) - (insert-char ?\ (1+ (* 2 (widget-get parent :custom-level))))) + (insert-char ?\ (* custom-buffer-indent + (widget-get parent :custom-level)))) (push (widget-create-child-and-convert widget 'choice-item :help-echo "Change the state of this item." @@ -1286,6 +1341,9 @@ (when lisp (insert " (lisp)")) (insert "\n")) + (when (eq category 'group) + (insert-char ?\ (* custom-buffer-indent + (widget-get parent :custom-level)))) (when custom-magic-show-button (when custom-magic-show (let ((indent (widget-get parent :indent))) @@ -1315,9 +1373,10 @@ (define-widget 'custom 'default "Customize a user option." + :format "%v" :convert-widget 'custom-convert-widget - :format-handler 'custom-format-handler :notify 'custom-notify + :custom-prefix "" :custom-level 1 :custom-state 'hidden :documentation-property 'widget-subclass-responsibility @@ -1327,13 +1386,6 @@ :validate 'widget-children-validate :match (lambda (widget value) (symbolp value))) -(defcustom custom-nest-groups nil - "*Non-nil means display nested groups in one customization buffer. -A valoe of nil means show a subgroup in its own buffer -rather than including it within its parent's customization buffer." - :type 'boolean - :group 'custom-buffer) - (defun custom-convert-widget (widget) ;; Initialize :value and :tag from :args in WIDGET. (let ((args (widget-get widget :args))) @@ -1344,93 +1396,6 @@ (widget-put widget :args nil))) widget) -(defun custom-format-handler (widget escape) - ;; We recognize extra escape sequences. - (let* ((buttons (widget-get widget :buttons)) - (state (widget-get widget :custom-state)) - (level (widget-get widget :custom-level)) - (category (widget-get widget :custom-category))) - (cond ((eq escape ?l) - (if custom-nest-groups - (when level - (insert-char ?\ (* 3 (1- level))) - (if (eq state 'hidden) - (insert "-- ") - (insert "/- "))) - (unless (and level (> level 1)) - (insert "/- ")))) - ((eq escape ?e) - (when (and level (not (eq state 'hidden))) - (insert "\n") - (if custom-nest-groups - (insert-char ?\ (* 3 (1- level)))) - (insert "\\-") - (insert " " (widget-get widget :tag) " group end ") - (insert-char ?- (- 75 (current-column) level)) - (insert "/\n"))) - ((eq escape ?-) - (when (and level (not (eq state 'hidden))) - ;; Add 1 to compensate for the extra < character - ;; at the beginning of the line. - (insert-char ?- (- (+ 75 1) (current-column) level)) - (insert "\\"))) - ((eq escape ?i) - (if custom-nest-groups - (insert-char ?\ (* 3 level)) - (unless (and level (> level 1)) - (insert " ")))) - ((eq escape ?L) - (if custom-nest-groups - (push (widget-create-child-and-convert - widget 'group-visibility - :help-echo "Show or hide this group." - :action 'custom-toggle-parent - (not (eq state 'hidden))) - buttons) - (push (widget-create-child-and-convert - widget 'group-link - :help-echo "Select the contents of this group." - :value (widget-get widget :value) - :tag "Switch to Group" - (not (eq state 'hidden))) - buttons))) - ((eq escape ?m) - (and (eq (preceding-char) ?\n) - (widget-get widget :indent) - (insert-char ? (widget-get widget :indent))) - (let ((magic (widget-create-child-and-convert - widget 'custom-magic nil))) - (widget-put widget :custom-magic magic) - (push magic buttons) - (widget-put widget :buttons buttons))) - ((eq escape ?a) - (unless (eq state 'hidden) - (let* ((symbol (widget-get widget :value)) - (links (get symbol 'custom-links)) - (many (> (length links) 2))) - (when links - (and (eq (preceding-char) ?\n) - (widget-get widget :indent) - (insert-char ? (widget-get widget :indent))) - (when (eq category 'group) - (insert-char ?\ (1+ (* 2 level)))) - (insert "See also ") - (while links - (push (widget-create-child-and-convert widget (car links)) - buttons) - (setq links (cdr links)) - (cond ((null links) - (insert ".\n")) - ((null (cdr links)) - (if many - (insert ", and ") - (insert " and "))) - (t - (insert ", ")))) - (widget-put widget :buttons buttons))))) - (t - (widget-default-format-handler widget escape))))) - (defun custom-notify (widget &rest args) "Keep track of changes." (let ((state (widget-get widget :custom-state))) @@ -1463,11 +1428,12 @@ "Redraw WIDGET state with current settings." (while widget (let ((magic (widget-get widget :custom-magic))) - (unless magic - (debug)) - (widget-value-set magic (widget-value magic)) - (when (setq widget (widget-get widget :group)) - (custom-group-state-update widget)))) + (cond (magic + (widget-value-set magic (widget-value magic)) + (when (setq widget (widget-get widget :group)) + (custom-group-state-update widget))) + (t + (setq widget nil))))) (widget-setup)) (defun custom-show (widget value) @@ -1529,6 +1495,57 @@ "Toggle visibility of parent to WIDGET." (custom-toggle-hide (widget-get widget :parent))) +(defun custom-add-see-also (widget &optional prefix) + "Add `See also ...' to WIDGET if there are any links. +Insert PREFIX first if non-nil." + (let* ((symbol (widget-get widget :value)) + (links (get symbol 'custom-links)) + (many (> (length links) 2)) + (buttons (widget-get widget :buttons)) + (indent (widget-get widget :indent))) + (when links + (when indent + (insert-char ?\ indent)) + (when prefix + (insert prefix)) + (insert "See also ") + (while links + (push (widget-create-child-and-convert widget (car links)) + buttons) + (setq links (cdr links)) + (cond ((null links) + (insert ".\n")) + ((null (cdr links)) + (if many + (insert ", and ") + (insert " and "))) + (t + (insert ", ")))) + (widget-put widget :buttons buttons)))) + +(defun custom-add-parent-links (widget) + "Add `Parent groups: ...' to WIDGET." + (let ((name (widget-value widget)) + (type (widget-type widget)) + (buttons (widget-get widget :buttons)) + found) + (insert "Parent groups:") + (mapatoms (lambda (symbol) + (let ((group (get symbol 'custom-group))) + (when (assq name group) + (when (eq type (nth 1 (assq name group))) + (insert " ") + (push (widget-create-child-and-convert + widget 'custom-group-link + :tag (custom-unlispify-tag-name symbol) + symbol) + buttons) + (setq found t)))))) + (widget-put widget :buttons buttons) + (unless found + (insert " (none)")) + (insert "\n"))) + ;;; The `custom-variable' Widget. (defface custom-variable-sample-face '((t (:underline t))) @@ -1541,7 +1558,7 @@ (define-widget 'custom-variable 'custom "Customize variable." - :format "%v%m%h%a" + :format "%v" :help-echo "Set or reset this variable." :documentation-property 'variable-documentation :custom-category 'option @@ -1584,6 +1601,8 @@ (type (custom-variable-type symbol)) (conv (widget-convert type)) (get (or (get symbol 'custom-get) 'default-value)) + (prefix (widget-get widget :custom-prefix)) + (last (widget-get widget :custom-last)) (value (if (default-boundp symbol) (funcall get symbol) (widget-get conv :value)))) @@ -1599,7 +1618,14 @@ ;; (widget-apply (widget-convert type) :match value) (setq form 'lisp))) ;; Now we can create the child widget. - (cond ((eq state 'hidden) + (cond ((eq custom-buffer-style 'tree) + (insert prefix (if last " +--- " " |--- ")) + (push (widget-create-child-and-convert + widget 'custom-tree-variable-tag) + buttons) + (insert " " tag "\n") + (widget-put widget :buttons buttons)) + ((eq state 'hidden) ;; Indicate hidden value. (push (widget-create-child-and-convert widget 'item @@ -1626,11 +1652,11 @@ (custom-quote (widget-get conv :value)))))) (insert (symbol-name symbol) ": ") (push (widget-create-child-and-convert - widget 'visibility - :help-echo "Hide the value of this option." - :action 'custom-toggle-parent - t) - buttons) + widget 'visibility + :help-echo "Hide the value of this option." + :action 'custom-toggle-parent + t) + buttons) (insert " ") (push (widget-create-child-and-convert widget 'sexp @@ -1670,15 +1696,29 @@ :format value-format :value value) children)))) - ;; Now update the state. - (unless (eq (preceding-char) ?\n) - (widget-insert "\n")) - (if (eq state 'hidden) - (widget-put widget :custom-state state) - (custom-variable-state-set widget)) - (widget-put widget :custom-form form) - (widget-put widget :buttons buttons) - (widget-put widget :children children))) + (unless (eq custom-buffer-style 'tree) + ;; Now update the state. + (unless (eq (preceding-char) ?\n) + (widget-insert "\n")) + (if (eq state 'hidden) + (widget-put widget :custom-state state) + (custom-variable-state-set widget)) + ;; Create the magic button. + (let ((magic (widget-create-child-and-convert + widget 'custom-magic nil))) + (widget-put widget :custom-magic magic) + (push magic buttons)) + ;; Update properties. + (widget-put widget :custom-form form) + (widget-put widget :buttons buttons) + (widget-put widget :children children) + ;; Insert documentation. + (widget-default-format-handler widget ?h) + ;; See also. + (unless (eq state 'hidden) + (when (eq (widget-get widget :custom-level) 1) + (custom-add-parent-links widget)) + (custom-add-see-also widget))))) (defun custom-tag-action (widget &rest args) "Pass :action to first child of WIDGET's parent." @@ -1954,8 +1994,6 @@ (define-widget 'custom-face 'custom "Customize face." - :format "%{%t%}: %s %L\n%m%h%a%v" - :format-handler 'custom-face-format-handler :sample-face 'custom-face-tag-face :help-echo "Set or reset this face." :documentation-property '(lambda (face) @@ -1971,26 +2009,6 @@ :custom-reset-standard 'custom-face-reset-standard :custom-menu 'custom-face-menu-create) -(defun custom-face-format-handler (widget escape) - ;; We recognize extra escape sequences. - (let (child - (symbol (widget-get widget :value))) - (cond ((eq escape ?s) - (and (string-match "XEmacs" emacs-version) - ;; XEmacs cannot display initialized faces. - (not (custom-facep symbol)) - (copy-face 'custom-face-empty symbol)) - (setq child (widget-create-child-and-convert - widget 'item - :format "(%{%t%})" - :sample-face symbol - :tag "sample"))) - (t - (custom-format-handler widget escape))) - (when child - (widget-put widget - :buttons (cons child (widget-get widget :buttons)))))) - (define-widget 'custom-face-all 'editable-list "An editable list of display specifications and attributes." :entry-format "%i %d %v" @@ -2024,36 +2042,95 @@ "Converted version of the `custom-face-selected' widget.") (defun custom-face-value-create (widget) - ;; Create a list of the display specifications. - (unless (eq (preceding-char) ?\n) - (insert "\n")) - (when (not (eq (widget-get widget :custom-state) 'hidden)) - (message "Creating face editor...") - (custom-load-widget widget) - (let* ((symbol (widget-value widget)) - (spec (or (get symbol 'saved-face) - (get symbol 'face-defface-spec) - ;; Attempt to construct it. - (list (list t (custom-face-attributes-get - symbol (selected-frame)))))) - (form (widget-get widget :custom-form)) - (indent (widget-get widget :indent)) - (edit (widget-create-child-and-convert - widget - (cond ((and (eq form 'selected) - (widget-apply custom-face-selected :match spec)) - (when indent (insert-char ?\ indent)) - 'custom-face-selected) - ((and (not (eq form 'lisp)) - (widget-apply custom-face-all :match spec)) - 'custom-face-all) - (t - (when indent (insert-char ?\ indent)) - 'sexp)) - :value spec))) - (custom-face-state-set widget) - (widget-put widget :children (list edit))) - (message "Creating face editor...done"))) + "Create a list of the display specifications for WIDGET." + (let ((buttons (widget-get widget :buttons)) + (symbol (widget-get widget :value)) + (tag (widget-get widget :tag)) + (state (widget-get widget :custom-state)) + (begin (point)) + (is-last (widget-get widget :custom-last)) + (prefix (widget-get widget :custom-prefix))) + (unless tag + (setq tag (prin1-to-string symbol))) + (cond ((eq custom-buffer-style 'tree) + (insert prefix (if is-last " +--- " " |--- ")) + (push (widget-create-child-and-convert + widget 'custom-tree-face-tag) + buttons) + (insert " " tag "\n") + (widget-put widget :buttons buttons)) + (t + ;; Create tag. + (insert tag) + (if (eq custom-buffer-style 'face) + (insert " ") + (widget-specify-sample widget begin (point)) + (insert ": ")) + ;; Sample. + (and (string-match "XEmacs" emacs-version) + ;; XEmacs cannot display uninitialized faces. + (not (custom-facep symbol)) + (copy-face 'custom-face-empty symbol)) + (push (widget-create-child-and-convert widget 'item + :format "(%{%t%})" + :sample-face symbol + :tag "sample") + buttons) + ;; Visibility. + (insert " ") + (push (widget-create-child-and-convert + widget 'visibility + :help-echo "Hide or show this face." + :action 'custom-toggle-parent + (not (eq state 'hidden))) + buttons) + ;; Magic. + (insert "\n") + (let ((magic (widget-create-child-and-convert + widget 'custom-magic nil))) + (widget-put widget :custom-magic magic) + (push magic buttons)) + ;; Update buttons. + (widget-put widget :buttons buttons) + ;; Insert documentation. + (widget-default-format-handler widget ?h) + ;; See also. + (unless (eq state 'hidden) + (when (eq (widget-get widget :custom-level) 1) + (custom-add-parent-links widget)) + (custom-add-see-also widget)) + ;; Editor. + (unless (eq (preceding-char) ?\n) + (insert "\n")) + (unless (eq state 'hidden) + (message "Creating face editor...") + (custom-load-widget widget) + (let* ((symbol (widget-value widget)) + (spec (or (get symbol 'saved-face) + (get symbol 'face-defface-spec) + ;; Attempt to construct it. + (list (list t (custom-face-attributes-get + symbol (selected-frame)))))) + (form (widget-get widget :custom-form)) + (indent (widget-get widget :indent)) + (edit (widget-create-child-and-convert + widget + (cond ((and (eq form 'selected) + (widget-apply custom-face-selected + :match spec)) + (when indent (insert-char ?\ indent)) + 'custom-face-selected) + ((and (not (eq form 'lisp)) + (widget-apply custom-face-all + :match spec)) + 'custom-face-all) + (t + (when indent (insert-char ?\ indent)) + 'sexp)) + :value spec))) + (custom-face-state-set widget) + (widget-put widget :children (list edit))) + (message "Creating face editor...done")))))) (defvar custom-face-menu '(("Set" custom-face-set) @@ -2181,7 +2258,9 @@ (define-widget 'face 'default "Select and customize a face." :convert-widget 'widget-value-convert-widget - :format "%[%t%]: %v" + :button-prefix 'widget-push-button-prefix + :button-suffix 'widget-push-button-suffix + :format "%t: %[select face%] %v" :tag "Face" :value 'default :value-create 'widget-face-value-create @@ -2194,9 +2273,9 @@ (defun widget-face-value-create (widget) ;; Create a `custom-face' child. (let* ((symbol (widget-value widget)) + (custom-buffer-style 'face) (child (widget-create-child-and-convert widget 'custom-face - :format "%t %s %L\n%m%h%v" :custom-level nil :value symbol))) (custom-magic-reset child) @@ -2248,6 +2327,16 @@ (widget-put widget :args args) widget)) +;;; The `custom-group-link' Widget. + +(define-widget 'custom-group-link 'link + "Show parent in other window when activated." + :help-echo "Create customize buffer for this group group." + :action 'custom-group-link-action) + +(defun custom-group-link-action (widget &rest ignore) + (customize-group (widget-value widget))) + ;;; The `custom-group' Widget. (defcustom custom-group-tag-faces '(custom-group-tag-face-1) @@ -2280,7 +2369,7 @@ (define-widget 'custom-group 'custom "Customize group." - :format "%l%{%t%} group: %L %-\n%m%i%h%a%v%e" + :format "%v" :sample-face-get 'custom-group-sample-face-get :documentation-property 'group-documentation :help-echo "Set or reset all members of this group." @@ -2300,42 +2389,197 @@ 'custom-group-tag-face)) (defun custom-group-value-create (widget) - (let ((state (widget-get widget :custom-state))) - (unless (eq state 'hidden) - (message "Creating group...") - (custom-load-widget widget) - (let* ((level (widget-get widget :custom-level)) - (symbol (widget-value widget)) - (members (sort (sort (copy-sequence (get symbol 'custom-group)) - custom-buffer-sort-predicate) - custom-buffer-order-predicate)) - (prefixes (widget-get widget :custom-prefixes)) - (custom-prefix-list (custom-prefix-add symbol prefixes)) - (length (length members)) - (count 0) - (children (mapcar (lambda (entry) - (widget-insert "\n") - (message "Creating group members... %2d%%" - (/ (* 100.0 count) length)) - (setq count (1+ count)) - (prog1 - (widget-create-child-and-convert - widget (nth 1 entry) - :group widget - :tag (custom-unlispify-tag-name - (nth 0 entry)) - :custom-prefixes custom-prefix-list - :custom-level (1+ level) - :value (nth 0 entry)) - (unless (eq (preceding-char) ?\n) - (widget-insert "\n")))) - members))) - (message "Creating group magic...") - (mapcar 'custom-magic-reset children) - (message "Creating group state...") - (widget-put widget :children children) - (custom-group-state-update widget) - (message "Creating group... done"))))) + "Insert a customize group for WIDGET in the current buffer." + (let ((state (widget-get widget :custom-state)) + (level (widget-get widget :custom-level)) + (indent (widget-get widget :indent)) + (prefix (widget-get widget :custom-prefix)) + (buttons (widget-get widget :buttons)) + (tag (widget-get widget :tag)) + (symbol (widget-value widget))) + (cond ((and (eq custom-buffer-style 'tree) + (eq state 'hidden)) + (insert prefix) + (push (widget-create-child-and-convert + widget 'custom-tree-visibility :tag "+") + buttons) + (insert "-- ") + (push (widget-create-child-and-convert + widget 'custom-tree-group-tag) + buttons) + (insert " " tag "\n") + (widget-put widget :buttons buttons)) + ((and (eq custom-buffer-style 'tree) + (zerop (length (get symbol 'custom-group)))) + (insert prefix "[ ]-- ") + (push (widget-create-child-and-convert + widget 'custom-tree-group-tag) + buttons) + (insert " " tag "\n") + (widget-put widget :buttons buttons)) + ((eq custom-buffer-style 'tree) + (insert prefix) + (custom-load-widget widget) + (if (zerop (length (get symbol 'custom-group))) + (progn + (insert prefix "[ ]-- ") + (push (widget-create-child-and-convert + widget 'custom-tree-group-tag) + buttons) + (insert " " tag "\n") + (widget-put widget :buttons buttons)) + (push (widget-create-child-and-convert + widget 'custom-tree-visibility :tag "-") + buttons) + (insert "-+ ") + (push (widget-create-child-and-convert + widget 'custom-tree-group-tag) + buttons) + (insert " " tag "\n") + (widget-put widget :buttons buttons) + (message "Creating group...") + (let* ((members (sort (copy-sequence (get symbol 'custom-group)) + 'custom-browse-sort-predicate)) + (prefixes (widget-get widget :custom-prefixes)) + (custom-prefix-list (custom-prefix-add symbol prefixes)) + (length (length members)) + (extra-prefix (if (widget-get widget :custom-last) + " " + " | ")) + (prefix (concat prefix extra-prefix)) + children entry) + (while members + (setq entry (car members) + members (cdr members)) + (push (widget-create-child-and-convert + widget (nth 1 entry) + :group widget + :tag (custom-unlispify-tag-name + (nth 0 entry)) + :custom-prefixes custom-prefix-list + :custom-level (1+ level) + :custom-last (null members) + :value (nth 0 entry) + :custom-prefix prefix) + children)) + (widget-put widget :children (reverse children))) + (message "Creating group...done"))) + ;; Nested style. + ((eq state 'hidden) + ;; Create level indicator. + (insert-char ?\ (* custom-buffer-indent (1- level))) + (insert "-- ") + ;; Create tag. + (let ((begin (point))) + (insert tag) + (widget-specify-sample widget begin (point))) + (insert " group: ") + ;; Create link/visibility indicator. + (if (eq custom-buffer-style 'links) + (push (widget-create-child-and-convert + widget 'custom-group-link + :tag "Show" + symbol) + buttons) + (push (widget-create-child-and-convert + widget 'visibility + :help-echo "Show members of this group." + :action 'custom-toggle-parent + (not (eq state 'hidden))) + buttons)) + (insert " \n") + ;; Create magic button. + (let ((magic (widget-create-child-and-convert + widget 'custom-magic nil))) + (widget-put widget :custom-magic magic) + (push magic buttons)) + ;; Update buttons. + (widget-put widget :buttons buttons) + ;; Insert documentation. + (widget-default-format-handler widget ?h)) + ;; Nested style. + (t ;Visible. + ;; Create level indicator. + (insert-char ?\ (* custom-buffer-indent (1- level))) + (insert "/- ") + ;; Create tag. + (let ((start (point))) + (insert tag) + (widget-specify-sample widget start (point))) + (insert " group: ") + ;; Create visibility indicator. + (unless (eq custom-buffer-style 'links) + (insert "--------") + (push (widget-create-child-and-convert + widget 'visibility + :help-echo "Hide members of this group." + :action 'custom-toggle-parent + (not (eq state 'hidden))) + buttons) + (insert " ")) + ;; Create more dashes. + ;; Use 76 instead of 75 to compensate for the temporary "<" + ;; added by `widget-insert'. + (insert-char ?- (- 76 (current-column) + (* custom-buffer-indent level))) + (insert "\\\n") + ;; Create magic button. + (let ((magic (widget-create-child-and-convert + widget 'custom-magic + :indent 0 + nil))) + (widget-put widget :custom-magic magic) + (push magic buttons)) + ;; Update buttons. + (widget-put widget :buttons buttons) + ;; Insert documentation. + (widget-default-format-handler widget ?h) + ;; Parents and See also. + (when (eq level 1) + (insert-char ?\ custom-buffer-indent) + (custom-add-parent-links widget)) + (custom-add-see-also widget + (make-string (* custom-buffer-indent level) + ?\ )) + ;; Members. + (message "Creating group...") + (custom-load-widget widget) + (let* ((members (sort (copy-sequence (get symbol 'custom-group)) + 'custom-buffer-sort-predicate)) + (prefixes (widget-get widget :custom-prefixes)) + (custom-prefix-list (custom-prefix-add symbol prefixes)) + (length (length members)) + (count 0) + (children (mapcar (lambda (entry) + (widget-insert "\n") + (message "\ +Creating group members... %2d%%" + (/ (* 100.0 count) length)) + (setq count (1+ count)) + (prog1 + (widget-create-child-and-convert + widget (nth 1 entry) + :group widget + :tag (custom-unlispify-tag-name + (nth 0 entry)) + :custom-prefixes custom-prefix-list + :custom-level (1+ level) + :value (nth 0 entry)) + (unless (eq (preceding-char) ?\n) + (widget-insert "\n")))) + members))) + (message "Creating group magic...") + (mapcar 'custom-magic-reset children) + (message "Creating group state...") + (widget-put widget :children children) + (custom-group-state-update widget) + (message "Creating group... done")) + ;; End line + (insert "\n") + (insert-char ?\ (* custom-buffer-indent (1- level))) + (insert "\\- " (widget-get widget :tag) " group end ") + (insert-char ?- (- 75 (current-column) (* custom-buffer-indent level))) + (insert "/\n"))))) (defvar custom-group-menu '(("Set" custom-group-set @@ -2655,9 +2899,8 @@ (< (length (get symbol 'custom-group)) widget-menu-max-size)) (let ((custom-prefix-list (custom-prefix-add symbol custom-prefix-list)) - (members (sort (sort (copy-sequence (get symbol 'custom-group)) - custom-menu-sort-predicate) - custom-menu-order-predicate))) + (members (sort (copy-sequence (get symbol 'custom-group)) + 'custom-menu-sort-predicate))) (custom-load-symbol symbol) `(,(custom-unlispify-menu-entry symbol t) ,item @@ -2682,7 +2925,9 @@ ;; We can delay it under XEmacs. `(,name :filter (lambda (&rest junk) - (cdr (custom-menu-create ',symbol)))))) + (cdr (custom-menu-create ',symbol)))) + ;; But we must create it now under Emacs. + (cons name (cdr (custom-menu-create symbol))))) ;;; The Custom Mode. @@ -2695,20 +2940,11 @@ (suppress-keymap custom-mode-map) (define-key custom-mode-map "q" 'bury-buffer)) -(defvar custom-mode-customize-menu) -(let ((menu (customize-menu-create 'customize))) - ;; In Emacs, this returns nil, so don't make this menu. - (if menu - (easy-menu-define custom-mode-customize-menu - custom-mode-map - "Menu used to customize customization buffers." - menu) - (setq custom-mode-customize-menu nil))) - (easy-menu-define custom-mode-menu custom-mode-map "Menu used in customization buffers." `("Custom" + ,(customize-menu-create 'customize) ["Set" custom-set t] ["Save" custom-save t] ["Reset to Current" custom-reset-current t] @@ -2742,8 +2978,6 @@ (setq major-mode 'custom-mode mode-name "Custom") (use-local-map custom-mode-map) - (if custom-mode-customize-menu - (easy-menu-add custom-mode-customize-menu)) (easy-menu-add custom-mode-menu) (make-local-variable 'custom-options) (run-hooks 'custom-mode-hook))
--- a/lisp/wid-edit.el Sat Jun 21 07:37:53 1997 +0000 +++ b/lisp/wid-edit.el Sat Jun 21 12:48:00 1997 +0000 @@ -4,7 +4,7 @@ ;; ;; Author: Per Abrahamsen <abraham@dina.kvl.dk> ;; Keywords: extensions -;; Version: 1.9924 +;; Version: 1.9929 ;; X-URL: http://www.dina.kvl.dk/~abraham/custom/ ;; This file is part of GNU Emacs. @@ -439,6 +439,15 @@ (setq missing nil)))) value)) +(defun widget-get-indirect (widget property) + "In WIDGET, get the value of PROPERTY. +If the value is a symbol, return its binding. +Otherwise, just return the value." + (let ((value (widget-get widget property))) + (if (symbolp value) + (symbol-value value) + value))) + (defun widget-member (widget property) "Non-nil iff there is a definition in WIDGET for PROPERTY." (cond ((widget-plist-member (cdr widget) property) @@ -667,14 +676,6 @@ :type 'string :group 'widget-button) -(defun widget-button-insert-indirect (widget key) - "Insert value of WIDGET's KEY property." - (let ((val (widget-get widget key))) - (while (and val (symbolp val)) - (setq val (symbol-value val))) - (when val - (insert val)))) - ;;; Creating Widgets. ;;;###autoload @@ -1185,13 +1186,13 @@ (setq found field)))) found)) -;; This is how, for example, a variable changes its state to "set" -;; when it is being edited. (defun widget-before-change (from &rest ignore) + ;; This is how, for example, a variable changes its state to `modified'. + ;; when it is being edited. (condition-case nil (let ((field (widget-field-find from))) (widget-apply field :notify field)) - (error (debug "After Change")))) + (error (debug "Before Change")))) (defun widget-after-change (from to old) ;; Adjust field size and text properties. @@ -1236,7 +1237,8 @@ (unless (eq old secret) (subst-char-in-region begin (1+ begin) old secret) (put-text-property begin (1+ begin) 'secret old)) - (setq begin (1+ begin))))))))) + (setq begin (1+ begin))))))) + (widget-apply field :notify field))) (error (debug "After Change")))) ;;; Widget Functions @@ -1337,9 +1339,9 @@ (insert "%")) ((eq escape ?\[) (setq button-begin (point)) - (widget-button-insert-indirect widget :button-prefix)) + (insert (widget-get-indirect widget :button-prefix))) ((eq escape ?\]) - (widget-button-insert-indirect widget :button-suffix) + (insert (widget-get-indirect widget :button-suffix)) (setq button-end (point))) ((eq escape ?\{) (setq sample-begin (point))) @@ -1649,22 +1651,6 @@ "Open the info node specified by WIDGET." (Info-goto-node (widget-value widget))) -;;; The `group-link' Widget. - -(define-widget 'group-link 'link - "A link to a customization group." - :create 'widget-group-link-create - :action 'widget-group-link-action) - -(defun widget-group-link-create (widget) - (let ((state (widget-get (widget-get widget :parent) :custom-state))) - (if (eq state 'hidden) - (widget-default-create widget)))) - -(defun widget-group-link-action (widget &optional event) - "Open the info node specified by WIDGET." - (customize-group (widget-value widget))) - ;;; The `url-link' Widget. (define-widget 'url-link 'link @@ -2635,24 +2621,6 @@ (widget-glyph-insert widget on "down" "down-pushed") (widget-glyph-insert widget off "right" "right-pushed")))) -(define-widget 'group-visibility 'item - "An indicator and manipulator for hidden group contents." - :format "%[%v%]" - :create 'widget-group-visibility-create - :button-prefix "" - :button-suffix "" - :on "Hide" - :off "Show" - :value-create 'widget-visibility-value-create - :action 'widget-toggle-action - :match (lambda (widget value) t)) - -(defun widget-group-visibility-create (widget) - (let ((visible (widget-value widget))) - (if visible - (insert "--------"))) - (widget-default-create widget)) - ;;; The `documentation-link' Widget. ;; ;; This is a helper widget for `documentation-string'.