diff options
| author | Chong Yidong | 2010-03-12 17:56:30 -0500 |
|---|---|---|
| committer | Chong Yidong | 2010-03-12 17:56:30 -0500 |
| commit | 647f999385fd315fe0fb0e8315447873656a89a5 (patch) | |
| tree | 2a8ac44ac1121c99b862b21ecd947e9c926a56ec | |
| parent | e3c5dd1188eb83922c21c414d671ff60ba2318c6 (diff) | |
| download | emacs-647f999385fd315fe0fb0e8315447873656a89a5.tar.gz emacs-647f999385fd315fe0fb0e8315447873656a89a5.zip | |
Improvements to the Custom interface.
* cus-edit.el: Resort topmost custom groups.
(custom-buffer-sort-alphabetically): Default to t.
(customize-apropos): Use apropos-parse-pattern.
(custom-search-field): New var.
(custom-buffer-create-internal): Add custom-apropos search field.
(custom-add-parent-links): Don't display parent doc.
(custom-group-value-create): Don't sort top-level custom group.
(custom-magic-value-create): Show visibility button before option
name.
(custom-variable-state): New fun, from custom-variable-state-set.
(custom-variable-state-set): Use it.
(custom-group-value-create): Hide options with standard values
using the :hidden-states property. Use progress reporter.
(custom-show): Simplify.
(custom-visibility): Disable images by default.
(custom-variable): New property :hidden-states.
(custom-variable-value-create): Enable images for
custom-visibility widgets. Use :hidden-states property to
determine initial visibility.
* wid-edit.el (widget-image-find): Give images center ascent.
(visibility): Add :on-image and :off-image properties.
(widget-visibility-value-create): Use them.
| -rw-r--r-- | lisp/ChangeLog | 28 | ||||
| -rw-r--r-- | lisp/cus-edit.el | 625 | ||||
| -rw-r--r-- | lisp/wid-edit.el | 41 |
3 files changed, 377 insertions, 317 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index c46604ee4b7..edc66039633 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,5 +1,33 @@ | |||
| 1 | 2010-03-12 Chong Yidong <cyd@stupidchicken.com> | 1 | 2010-03-12 Chong Yidong <cyd@stupidchicken.com> |
| 2 | 2 | ||
| 3 | * cus-edit.el: Resort topmost custom groups. | ||
| 4 | (custom-buffer-sort-alphabetically): Default to t. | ||
| 5 | (customize-apropos): Use apropos-parse-pattern. | ||
| 6 | (custom-search-field): New var. | ||
| 7 | (custom-buffer-create-internal): Add custom-apropos search field. | ||
| 8 | (custom-add-parent-links): Don't display parent doc. | ||
| 9 | (custom-group-value-create): Don't sort top-level custom group. | ||
| 10 | (custom-magic-value-create): Show visibility button before option | ||
| 11 | name. | ||
| 12 | |||
| 13 | (custom-variable-state): New fun, from custom-variable-state-set. | ||
| 14 | (custom-variable-state-set): Use it. | ||
| 15 | (custom-group-value-create): Hide options with standard values | ||
| 16 | using the :hidden-states property. Use progress reporter. | ||
| 17 | |||
| 18 | (custom-show): Simplify. | ||
| 19 | (custom-visibility): Disable images by default. | ||
| 20 | (custom-variable): New property :hidden-states. | ||
| 21 | (custom-variable-value-create): Enable images for | ||
| 22 | custom-visibility widgets. Use :hidden-states property to | ||
| 23 | determine initial visibility. | ||
| 24 | |||
| 25 | * wid-edit.el (widget-image-find): Give images center ascent. | ||
| 26 | (visibility): Add :on-image and :off-image properties. | ||
| 27 | (widget-visibility-value-create): Use them. | ||
| 28 | |||
| 29 | 2010-03-12 Chong Yidong <cyd@stupidchicken.com> | ||
| 30 | |||
| 3 | * cus-edit.el (processes): Remove from development group. | 31 | * cus-edit.el (processes): Remove from development group. |
| 4 | (oop, hypermedia): Delete group. | 32 | (oop, hypermedia): Delete group. |
| 5 | (comm): Promote to top-level group. | 33 | (comm): Promote to top-level group. |
diff --git a/lisp/cus-edit.el b/lisp/cus-edit.el index 2df9f7c955e..399a6992f41 100644 --- a/lisp/cus-edit.el +++ b/lisp/cus-edit.el | |||
| @@ -166,6 +166,23 @@ | |||
| 166 | "Basic text editing facilities." | 166 | "Basic text editing facilities." |
| 167 | :group 'emacs) | 167 | :group 'emacs) |
| 168 | 168 | ||
| 169 | (defgroup convenience nil | ||
| 170 | "Convenience features for faster editing." | ||
| 171 | :group 'emacs) | ||
| 172 | |||
| 173 | (defgroup files nil | ||
| 174 | "Support for editing files." | ||
| 175 | :group 'emacs) | ||
| 176 | |||
| 177 | (defgroup wp nil | ||
| 178 | "Support for editing text files." | ||
| 179 | :tag "Text" | ||
| 180 | :group 'emacs) | ||
| 181 | |||
| 182 | (defgroup data nil | ||
| 183 | "Support for editing binary data files." | ||
| 184 | :group 'emacs) | ||
| 185 | |||
| 169 | (defgroup abbrev nil | 186 | (defgroup abbrev nil |
| 170 | "Abbreviation handling, typing shortcuts, macros." | 187 | "Abbreviation handling, typing shortcuts, macros." |
| 171 | :tag "Abbreviations" | 188 | :tag "Abbreviations" |
| @@ -201,10 +218,6 @@ | |||
| 201 | "Process, subshell, compilation, and job control support." | 218 | "Process, subshell, compilation, and job control support." |
| 202 | :group 'external) | 219 | :group 'external) |
| 203 | 220 | ||
| 204 | (defgroup convenience nil | ||
| 205 | "Convenience features for faster editing." | ||
| 206 | :group 'emacs) | ||
| 207 | |||
| 208 | (defgroup programming nil | 221 | (defgroup programming nil |
| 209 | "Support for programming in other languages." | 222 | "Support for programming in other languages." |
| 210 | :group 'emacs) | 223 | :group 'emacs) |
| @@ -301,18 +314,6 @@ | |||
| 301 | "Support for Emacs frames and window systems." | 314 | "Support for Emacs frames and window systems." |
| 302 | :group 'environment) | 315 | :group 'environment) |
| 303 | 316 | ||
| 304 | (defgroup data nil | ||
| 305 | "Support for editing files of data." | ||
| 306 | :group 'emacs) | ||
| 307 | |||
| 308 | (defgroup files nil | ||
| 309 | "Support for editing files." | ||
| 310 | :group 'emacs) | ||
| 311 | |||
| 312 | (defgroup wp nil | ||
| 313 | "Word processing." | ||
| 314 | :group 'emacs) | ||
| 315 | |||
| 316 | (defgroup tex nil | 317 | (defgroup tex nil |
| 317 | "Code related to the TeX formatter." | 318 | "Code related to the TeX formatter." |
| 318 | :link '(custom-group-link :tag "Font Lock Faces group" font-lock-faces) | 319 | :link '(custom-group-link :tag "Font Lock Faces group" font-lock-faces) |
| @@ -671,8 +672,8 @@ If `last', order groups after non-groups." | |||
| 671 | :group 'custom-browse) | 672 | :group 'custom-browse) |
| 672 | 673 | ||
| 673 | ;;;###autoload | 674 | ;;;###autoload |
| 674 | (defcustom custom-buffer-sort-alphabetically nil | 675 | (defcustom custom-buffer-sort-alphabetically t |
| 675 | "If non-nil, sort each customization group alphabetically in Custom buffer." | 676 | "Whether to sort customization groups alphabetically in Custom buffer." |
| 676 | :type 'boolean | 677 | :type 'boolean |
| 677 | :group 'custom-buffer) | 678 | :group 'custom-buffer) |
| 678 | 679 | ||
| @@ -1373,42 +1374,52 @@ suggest to customize that face, if it's customizable." | |||
| 1373 | (custom-buffer-create (custom-sort-items found t nil) | 1374 | (custom-buffer-create (custom-sort-items found t nil) |
| 1374 | "*Customize Saved*")))) | 1375 | "*Customize Saved*")))) |
| 1375 | 1376 | ||
| 1377 | (declare-function apropos-parse-pattern "apropos" (pattern)) | ||
| 1378 | |||
| 1376 | ;;;###autoload | 1379 | ;;;###autoload |
| 1377 | (defun customize-apropos (regexp &optional all) | 1380 | (defun customize-apropos (pattern &optional type) |
| 1378 | "Customize all loaded options, faces and groups matching REGEXP. | 1381 | "Customize all loaded options, faces and groups matching PATTERN. |
| 1379 | If ALL is `options', include only options. | 1382 | PATTERN can be a word, a list of words (separated by spaces), |
| 1380 | If ALL is `faces', include only faces. | 1383 | or a regexp (using some regexp special characters). If it is a word, |
| 1381 | If ALL is `groups', include only groups. | 1384 | search for matches for that word as a substring. If it is a list of words, |
| 1382 | If ALL is t (interactively, with prefix arg), include variables | 1385 | search for matches for any two (or more) of those words. |
| 1386 | |||
| 1387 | If TYPE is `options', include only options. | ||
| 1388 | If TYPE is `faces', include only faces. | ||
| 1389 | If TYPE is `groups', include only groups. | ||
| 1390 | If TYPE is t (interactively, with prefix arg), include variables | ||
| 1383 | that are not customizable options, as well as faces and groups | 1391 | that are not customizable options, as well as faces and groups |
| 1384 | \(but we recommend using `apropos-variable' instead)." | 1392 | \(but we recommend using `apropos-variable' instead)." |
| 1385 | (interactive "sCustomize (regexp): \nP") | 1393 | (interactive (list (apropos-read-pattern "symbol") current-prefix-arg)) |
| 1386 | (let ((found nil)) | 1394 | (require 'apropos) |
| 1387 | (mapatoms (lambda (symbol) | 1395 | (apropos-parse-pattern pattern) |
| 1388 | (when (string-match regexp (symbol-name symbol)) | 1396 | (let (found tests) |
| 1389 | (when (and (not (memq all '(faces options))) | 1397 | (mapatoms |
| 1390 | (get symbol 'custom-group)) | 1398 | `(lambda (symbol) |
| 1391 | (push (list symbol 'custom-group) found)) | 1399 | (when (string-match apropos-regexp (symbol-name symbol)) |
| 1392 | (when (and (not (memq all '(options groups))) | 1400 | ,(if (not (memq type '(faces options))) |
| 1393 | (custom-facep symbol)) | 1401 | '(if (get symbol 'custom-group) |
| 1394 | (push (list symbol 'custom-face) found)) | 1402 | (push (list symbol 'custom-group) found))) |
| 1395 | (when (and (not (memq all '(groups faces))) | 1403 | ,(if (not (memq type '(options groups))) |
| 1396 | (boundp symbol) | 1404 | '(if (custom-facep symbol) |
| 1397 | (eq (indirect-variable symbol) symbol) | 1405 | (push (list symbol 'custom-face) found))) |
| 1398 | (or (get symbol 'saved-value) | 1406 | ,(if (not (memq type '(groups faces))) |
| 1399 | (custom-variable-p symbol) | 1407 | `(if (and (boundp symbol) |
| 1400 | (and (not (memq all '(nil options))) | 1408 | (eq (indirect-variable symbol) symbol) |
| 1401 | (get symbol 'variable-documentation)))) | 1409 | (or (get symbol 'saved-value) |
| 1402 | (push (list symbol 'custom-variable) found))))) | 1410 | (custom-variable-p symbol) |
| 1411 | ,(if (not (memq type '(nil options))) | ||
| 1412 | '(get symbol 'variable-documentation)))) | ||
| 1413 | (push (list symbol 'custom-variable) found)))))) | ||
| 1403 | (if (not found) | 1414 | (if (not found) |
| 1404 | (error "No %s matching %s" | 1415 | (error "No %s matching %s" |
| 1405 | (if (eq all t) | 1416 | (if (eq type t) |
| 1406 | "items" | 1417 | "items" |
| 1407 | (format "customizable %s" | 1418 | (format "customizable %s" |
| 1408 | (if (memq all '(options faces groups)) | 1419 | (if (memq type '(options faces groups)) |
| 1409 | (symbol-name all) | 1420 | (symbol-name type) |
| 1410 | "items"))) | 1421 | "items"))) |
| 1411 | regexp) | 1422 | pattern) |
| 1412 | (custom-buffer-create | 1423 | (custom-buffer-create |
| 1413 | (custom-sort-items found t custom-buffer-order-groups) | 1424 | (custom-sort-items found t custom-buffer-order-groups) |
| 1414 | "*Customize Apropos*")))) | 1425 | "*Customize Apropos*")))) |
| @@ -1531,6 +1542,12 @@ This button will have a menu with all three reset operations." | |||
| 1531 | (defvar custom-button-pressed nil | 1542 | (defvar custom-button-pressed nil |
| 1532 | "Face used for pressed buttons in customization buffers.") | 1543 | "Face used for pressed buttons in customization buffers.") |
| 1533 | 1544 | ||
| 1545 | (defcustom custom-search-field t | ||
| 1546 | "If non-nil, show a search field in Custom buffers." | ||
| 1547 | :type 'boolean | ||
| 1548 | :version "24.1" | ||
| 1549 | :group 'custom-buffer) | ||
| 1550 | |||
| 1534 | (defcustom custom-raised-buttons (not (equal (face-valid-attribute-values :box) | 1551 | (defcustom custom-raised-buttons (not (equal (face-valid-attribute-values :box) |
| 1535 | '(("unspecified" . unspecified)))) | 1552 | '(("unspecified" . unspecified)))) |
| 1536 | "If non-nil, indicate active buttons in a `raised-button' style. | 1553 | "If non-nil, indicate active buttons in a `raised-button' style. |
| @@ -1554,14 +1571,9 @@ Otherwise use brackets." | |||
| 1554 | (let ((init-file (or custom-file user-init-file))) | 1571 | (let ((init-file (or custom-file user-init-file))) |
| 1555 | ;; Insert verbose help at the top of the custom buffer. | 1572 | ;; Insert verbose help at the top of the custom buffer. |
| 1556 | (when custom-buffer-verbose-help | 1573 | (when custom-buffer-verbose-help |
| 1557 | (widget-insert "Editing a setting changes only the text in this buffer." | 1574 | (widget-insert (if init-file |
| 1558 | (if init-file | 1575 | "To apply changes, use the Save or Set buttons." |
| 1559 | " | 1576 | "Custom settings cannot be saved; maybe you started Emacs with `-q'.") |
| 1560 | To apply your changes, use the Save or Set buttons. | ||
| 1561 | Saving a change normally works by editing your init file." | ||
| 1562 | " | ||
| 1563 | Currently, these settings cannot be saved for future Emacs sessions, | ||
| 1564 | possibly because you started Emacs with `-q'.") | ||
| 1565 | "\nFor details, see ") | 1577 | "\nFor details, see ") |
| 1566 | (widget-create 'custom-manual | 1578 | (widget-create 'custom-manual |
| 1567 | :tag "Saving Customizations" | 1579 | :tag "Saving Customizations" |
| @@ -1573,6 +1585,26 @@ possibly because you started Emacs with `-q'.") | |||
| 1573 | "(emacs)Top") | 1585 | "(emacs)Top") |
| 1574 | (widget-insert ".")) | 1586 | (widget-insert ".")) |
| 1575 | (widget-insert "\n") | 1587 | (widget-insert "\n") |
| 1588 | |||
| 1589 | ;; Insert the search field. | ||
| 1590 | (when custom-search-field | ||
| 1591 | (widget-insert "\n") | ||
| 1592 | (let* ((echo "Search for custom items") | ||
| 1593 | (search-widget | ||
| 1594 | (widget-create | ||
| 1595 | 'editable-field | ||
| 1596 | :size 40 :help-echo echo | ||
| 1597 | :action `(lambda (widget &optional event) | ||
| 1598 | (customize-apropos (widget-value widget)))))) | ||
| 1599 | (widget-insert " ") | ||
| 1600 | (widget-create-child-and-convert | ||
| 1601 | search-widget 'push-button | ||
| 1602 | :tag "Search" | ||
| 1603 | :help-echo echo :action | ||
| 1604 | (lambda (widget &optional event) | ||
| 1605 | (customize-apropos (widget-value (widget-get widget :parent))))) | ||
| 1606 | (widget-insert "\n"))) | ||
| 1607 | |||
| 1576 | ;; The custom command buttons are also in the toolbar, so for a | 1608 | ;; The custom command buttons are also in the toolbar, so for a |
| 1577 | ;; time they were not inserted in the buffer if the toolbar was in use. | 1609 | ;; time they were not inserted in the buffer if the toolbar was in use. |
| 1578 | ;; But it can be a little confusing for the buffer layout to | 1610 | ;; But it can be a little confusing for the buffer layout to |
| @@ -1580,10 +1612,9 @@ possibly because you started Emacs with `-q'.") | |||
| 1580 | ;; mention that a custom buffer can in theory be created in a | 1612 | ;; mention that a custom buffer can in theory be created in a |
| 1581 | ;; frame with a toolbar, then later viewed in one without. | 1613 | ;; frame with a toolbar, then later viewed in one without. |
| 1582 | ;; So now the buttons are always inserted in the buffer. (Bug#1326) | 1614 | ;; So now the buttons are always inserted in the buffer. (Bug#1326) |
| 1583 | ;;; (when (not (and (bound-and-true-p tool-bar-mode) (display-graphic-p))) | ||
| 1584 | (if custom-buffer-verbose-help | 1615 | (if custom-buffer-verbose-help |
| 1585 | (widget-insert "\n | 1616 | (widget-insert " |
| 1586 | Operate on all settings in this buffer that are not marked HIDDEN:\n")) | 1617 | Operate on all settings in this buffer:\n")) |
| 1587 | (let ((button (lambda (tag action active help icon) | 1618 | (let ((button (lambda (tag action active help icon) |
| 1588 | (widget-insert " ") | 1619 | (widget-insert " ") |
| 1589 | (if (eval active) | 1620 | (if (eval active) |
| @@ -1979,63 +2010,64 @@ and `face'." | |||
| 1979 | (nth 3 entry))) | 2010 | (nth 3 entry))) |
| 1980 | (form (widget-get parent :custom-form)) | 2011 | (form (widget-get parent :custom-form)) |
| 1981 | children) | 2012 | children) |
| 1982 | (while (string-match "\\`\\(.*\\)%c\\(.*\\)\\'" text) | 2013 | (unless (eq state 'hidden) |
| 1983 | (setq text (concat (match-string 1 text) | 2014 | (while (string-match "\\`\\(.*\\)%c\\(.*\\)\\'" text) |
| 1984 | (symbol-name category) | 2015 | (setq text (concat (match-string 1 text) |
| 1985 | (match-string 2 text)))) | 2016 | (symbol-name category) |
| 1986 | (when (and custom-magic-show | 2017 | (match-string 2 text)))) |
| 1987 | (or (not hidden) | 2018 | (when (and custom-magic-show |
| 1988 | (memq category custom-magic-show-hidden))) | 2019 | (or (not hidden) |
| 1989 | (insert " ") | 2020 | (memq category custom-magic-show-hidden))) |
| 2021 | (insert " ") | ||
| 2022 | (when (and (eq category 'group) | ||
| 2023 | (not (and (eq custom-buffer-style 'links) | ||
| 2024 | (> (widget-get parent :custom-level) 1)))) | ||
| 2025 | (insert-char ?\ (* custom-buffer-indent | ||
| 2026 | (widget-get parent :custom-level)))) | ||
| 2027 | (push (widget-create-child-and-convert | ||
| 2028 | widget 'choice-item | ||
| 2029 | :help-echo "Change the state of this item." | ||
| 2030 | :format (if hidden "%t" "%[%t%]") | ||
| 2031 | :button-prefix 'widget-push-button-prefix | ||
| 2032 | :button-suffix 'widget-push-button-suffix | ||
| 2033 | :mouse-down-action 'widget-magic-mouse-down-action | ||
| 2034 | :tag "State") | ||
| 2035 | children) | ||
| 2036 | (insert ": ") | ||
| 2037 | (let ((start (point))) | ||
| 2038 | (if (eq custom-magic-show 'long) | ||
| 2039 | (insert text) | ||
| 2040 | (insert (symbol-name state))) | ||
| 2041 | (cond ((eq form 'lisp) | ||
| 2042 | (insert " (lisp)")) | ||
| 2043 | ((eq form 'mismatch) | ||
| 2044 | (insert " (mismatch)"))) | ||
| 2045 | (put-text-property start (point) 'face 'custom-state)) | ||
| 2046 | (insert "\n")) | ||
| 1990 | (when (and (eq category 'group) | 2047 | (when (and (eq category 'group) |
| 1991 | (not (and (eq custom-buffer-style 'links) | 2048 | (not (and (eq custom-buffer-style 'links) |
| 1992 | (> (widget-get parent :custom-level) 1)))) | 2049 | (> (widget-get parent :custom-level) 1)))) |
| 1993 | (insert-char ?\ (* custom-buffer-indent | 2050 | (insert-char ?\ (* custom-buffer-indent |
| 1994 | (widget-get parent :custom-level)))) | 2051 | (widget-get parent :custom-level)))) |
| 1995 | (push (widget-create-child-and-convert | 2052 | (when custom-magic-show-button |
| 1996 | widget 'choice-item | 2053 | (when custom-magic-show |
| 1997 | :help-echo "Change the state of this item." | 2054 | (let ((indent (widget-get parent :indent))) |
| 1998 | :format (if hidden "%t" "%[%t%]") | 2055 | (when indent |
| 1999 | :button-prefix 'widget-push-button-prefix | 2056 | (insert-char ? indent)))) |
| 2000 | :button-suffix 'widget-push-button-suffix | 2057 | (push (widget-create-child-and-convert |
| 2001 | :mouse-down-action 'widget-magic-mouse-down-action | 2058 | widget 'choice-item |
| 2002 | :tag "State") | 2059 | :mouse-down-action 'widget-magic-mouse-down-action |
| 2003 | children) | 2060 | :button-face face |
| 2004 | (insert ": ") | 2061 | :button-prefix "" |
| 2005 | (let ((start (point))) | 2062 | :button-suffix "" |
| 2006 | (if (eq custom-magic-show 'long) | 2063 | :help-echo "Change the state." |
| 2007 | (insert text) | 2064 | :format (if hidden "%t" "%[%t%]") |
| 2008 | (insert (symbol-name state))) | 2065 | :tag (if (memq form '(lisp mismatch)) |
| 2009 | (cond ((eq form 'lisp) | 2066 | (concat "(" magic ")") |
| 2010 | (insert " (lisp)")) | 2067 | (concat "[" magic "]"))) |
| 2011 | ((eq form 'mismatch) | 2068 | children) |
| 2012 | (insert " (mismatch)"))) | 2069 | (insert " ")) |
| 2013 | (put-text-property start (point) 'face 'custom-state)) | 2070 | (widget-put widget :children children)))) |
| 2014 | (insert "\n")) | ||
| 2015 | (when (and (eq category 'group) | ||
| 2016 | (not (and (eq custom-buffer-style 'links) | ||
| 2017 | (> (widget-get parent :custom-level) 1)))) | ||
| 2018 | (insert-char ?\ (* custom-buffer-indent | ||
| 2019 | (widget-get parent :custom-level)))) | ||
| 2020 | (when custom-magic-show-button | ||
| 2021 | (when custom-magic-show | ||
| 2022 | (let ((indent (widget-get parent :indent))) | ||
| 2023 | (when indent | ||
| 2024 | (insert-char ? indent)))) | ||
| 2025 | (push (widget-create-child-and-convert | ||
| 2026 | widget 'choice-item | ||
| 2027 | :mouse-down-action 'widget-magic-mouse-down-action | ||
| 2028 | :button-face face | ||
| 2029 | :button-prefix "" | ||
| 2030 | :button-suffix "" | ||
| 2031 | :help-echo "Change the state." | ||
| 2032 | :format (if hidden "%t" "%[%t%]") | ||
| 2033 | :tag (if (memq form '(lisp mismatch)) | ||
| 2034 | (concat "(" magic ")") | ||
| 2035 | (concat "[" magic "]"))) | ||
| 2036 | children) | ||
| 2037 | (insert " ")) | ||
| 2038 | (widget-put widget :children children))) | ||
| 2039 | 2071 | ||
| 2040 | (defun custom-magic-reset (widget) | 2072 | (defun custom-magic-reset (widget) |
| 2041 | "Redraw the :custom-magic property of WIDGET." | 2073 | "Redraw the :custom-magic property of WIDGET." |
| @@ -2197,12 +2229,9 @@ and `face'." | |||
| 2197 | (defun custom-show (widget value) | 2229 | (defun custom-show (widget value) |
| 2198 | "Non-nil if WIDGET should be shown with VALUE by default." | 2230 | "Non-nil if WIDGET should be shown with VALUE by default." |
| 2199 | (let ((show (widget-get widget :custom-show))) | 2231 | (let ((show (widget-get widget :custom-show))) |
| 2200 | (cond ((null show) | 2232 | (if (functionp show) |
| 2201 | nil) | 2233 | (funcall show widget value) |
| 2202 | ((eq t show) | 2234 | show))) |
| 2203 | t) | ||
| 2204 | (t | ||
| 2205 | (funcall show widget value))))) | ||
| 2206 | 2235 | ||
| 2207 | (defun custom-load-widget (widget) | 2236 | (defun custom-load-widget (widget) |
| 2208 | "Load all dependencies for WIDGET." | 2237 | "Load all dependencies for WIDGET." |
| @@ -2280,8 +2309,7 @@ Insert PREFIX first if non-nil." | |||
| 2280 | (insert ", ")))) | 2309 | (insert ", ")))) |
| 2281 | (widget-put widget :buttons buttons)))) | 2310 | (widget-put widget :buttons buttons)))) |
| 2282 | 2311 | ||
| 2283 | (defun custom-add-parent-links (widget &optional initial-string | 2312 | (defun custom-add-parent-links (widget &optional initial-string doc-initial-string) |
| 2284 | doc-initial-string) | ||
| 2285 | "Add \"Parent groups: ...\" to WIDGET if the group has parents. | 2313 | "Add \"Parent groups: ...\" to WIDGET if the group has parents. |
| 2286 | The value is non-nil if any parents were found. | 2314 | The value is non-nil if any parents were found. |
| 2287 | If INITIAL-STRING is non-nil, use that rather than \"Parent groups:\"." | 2315 | If INITIAL-STRING is non-nil, use that rather than \"Parent groups:\"." |
| @@ -2300,36 +2328,6 @@ If INITIAL-STRING is non-nil, use that rather than \"Parent groups:\"." | |||
| 2300 | symbol) | 2328 | symbol) |
| 2301 | buttons) | 2329 | buttons) |
| 2302 | (setq parents (cons symbol parents))))) | 2330 | (setq parents (cons symbol parents))))) |
| 2303 | (and (null (get name 'custom-links)) ;No links of its own. | ||
| 2304 | (= (length parents) 1) ;A single parent. | ||
| 2305 | (let* ((links (delq nil (mapcar (lambda (w) | ||
| 2306 | (unless (eq (widget-type w) | ||
| 2307 | 'custom-group-link) | ||
| 2308 | w)) | ||
| 2309 | (get (car parents) 'custom-links)))) | ||
| 2310 | (many (> (length links) 2))) | ||
| 2311 | (when links | ||
| 2312 | (let ((pt (point)) | ||
| 2313 | (left-margin (+ left-margin 2))) | ||
| 2314 | (insert "\n" (or doc-initial-string "Group documentation:") " ") | ||
| 2315 | (while links | ||
| 2316 | (push (widget-create-child-and-convert | ||
| 2317 | widget (car links) | ||
| 2318 | :button-face 'custom-link | ||
| 2319 | :mouse-face 'highlight | ||
| 2320 | :pressed-face 'highlight) | ||
| 2321 | buttons) | ||
| 2322 | (setq links (cdr links)) | ||
| 2323 | (cond ((null links) | ||
| 2324 | (insert ".\n")) | ||
| 2325 | ((null (cdr links)) | ||
| 2326 | (if many | ||
| 2327 | (insert ", and ") | ||
| 2328 | (insert " and "))) | ||
| 2329 | (t | ||
| 2330 | (insert ", ")))) | ||
| 2331 | (fill-region-as-paragraph pt (point)) | ||
| 2332 | (delete-to-left-margin (1+ pt) (+ pt 2)))))) | ||
| 2333 | (if parents | 2331 | (if parents |
| 2334 | (insert "\n") | 2332 | (insert "\n") |
| 2335 | (delete-region start (point))) | 2333 | (delete-region start (point))) |
| @@ -2404,8 +2402,6 @@ If INITIAL-STRING is non-nil, use that rather than \"Parent groups:\"." | |||
| 2404 | 2402 | ||
| 2405 | ;;; The `custom-variable' Widget. | 2403 | ;;; The `custom-variable' Widget. |
| 2406 | 2404 | ||
| 2407 | ;; When this was underlined blue, users confused it with a | ||
| 2408 | ;; Mosaic-style hyperlink... | ||
| 2409 | (defface custom-variable-tag | 2405 | (defface custom-variable-tag |
| 2410 | `((((class color) | 2406 | `((((class color) |
| 2411 | (background dark)) | 2407 | (background dark)) |
| @@ -2450,7 +2446,11 @@ However, setting it through Custom sets the default value.") | |||
| 2450 | (documentation-property variable 'variable-documentation))) | 2446 | (documentation-property variable 'variable-documentation))) |
| 2451 | 2447 | ||
| 2452 | (define-widget 'custom-variable 'custom | 2448 | (define-widget 'custom-variable 'custom |
| 2453 | "Customize variable." | 2449 | "A widget for displaying a Custom variable. |
| 2450 | |||
| 2451 | The following property has a special meaning for this widget: | ||
| 2452 | :hidden-states - A list of widget states for which the widget's initial | ||
| 2453 | contents should be hidden." | ||
| 2454 | :format "%v" | 2454 | :format "%v" |
| 2455 | :help-echo "Set or reset this variable." | 2455 | :help-echo "Set or reset this variable." |
| 2456 | :documentation-property #'custom-variable-documentation | 2456 | :documentation-property #'custom-variable-documentation |
| @@ -2460,6 +2460,7 @@ However, setting it through Custom sets the default value.") | |||
| 2460 | :custom-form nil ; defaults to value of `custom-variable-default-form' | 2460 | :custom-form nil ; defaults to value of `custom-variable-default-form' |
| 2461 | :value-create 'custom-variable-value-create | 2461 | :value-create 'custom-variable-value-create |
| 2462 | :action 'custom-variable-action | 2462 | :action 'custom-variable-action |
| 2463 | :hidden-states '(standard) | ||
| 2463 | :custom-set 'custom-variable-set | 2464 | :custom-set 'custom-variable-set |
| 2464 | :custom-mark-to-save 'custom-variable-mark-to-save | 2465 | :custom-mark-to-save 'custom-variable-mark-to-save |
| 2465 | :custom-reset-current 'custom-redraw | 2466 | :custom-reset-current 'custom-redraw |
| @@ -2494,7 +2495,6 @@ try matching its doc string against `custom-guess-doc-alist'." | |||
| 2494 | (let* ((buttons (widget-get widget :buttons)) | 2495 | (let* ((buttons (widget-get widget :buttons)) |
| 2495 | (children (widget-get widget :children)) | 2496 | (children (widget-get widget :children)) |
| 2496 | (form (widget-get widget :custom-form)) | 2497 | (form (widget-get widget :custom-form)) |
| 2497 | (state (widget-get widget :custom-state)) | ||
| 2498 | (symbol (widget-get widget :value)) | 2498 | (symbol (widget-get widget :value)) |
| 2499 | (tag (widget-get widget :tag)) | 2499 | (tag (widget-get widget :tag)) |
| 2500 | (type (custom-variable-type symbol)) | 2500 | (type (custom-variable-type symbol)) |
| @@ -2504,17 +2504,17 @@ try matching its doc string against `custom-guess-doc-alist'." | |||
| 2504 | (last (widget-get widget :custom-last)) | 2504 | (last (widget-get widget :custom-last)) |
| 2505 | (value (if (default-boundp symbol) | 2505 | (value (if (default-boundp symbol) |
| 2506 | (funcall get symbol) | 2506 | (funcall get symbol) |
| 2507 | (widget-get conv :value)))) | 2507 | (widget-get conv :value))) |
| 2508 | ;; If the widget is new, the child determines whether it is hidden. | 2508 | (state (or (widget-get widget :custom-state) |
| 2509 | (cond (state) | 2509 | (if (memq (custom-variable-state symbol value) |
| 2510 | ((custom-show type value) | 2510 | (widget-get widget :hidden-states)) |
| 2511 | (setq state 'unknown)) | 2511 | 'hidden)))) |
| 2512 | (t | 2512 | |
| 2513 | (setq state 'hidden))) | ||
| 2514 | ;; If we don't know the state, see if we need to edit it in lisp form. | 2513 | ;; If we don't know the state, see if we need to edit it in lisp form. |
| 2514 | (unless state | ||
| 2515 | (setq state (if (custom-show type value) 'unknown 'hidden))) | ||
| 2515 | (when (eq state 'unknown) | 2516 | (when (eq state 'unknown) |
| 2516 | (unless (widget-apply conv :match value) | 2517 | (unless (widget-apply conv :match value) |
| 2517 | ;; (widget-apply (widget-convert type) :match value) | ||
| 2518 | (setq form 'mismatch))) | 2518 | (setq form 'mismatch))) |
| 2519 | ;; Now we can create the child widget. | 2519 | ;; Now we can create the child widget. |
| 2520 | (cond ((eq custom-buffer-style 'tree) | 2520 | (cond ((eq custom-buffer-style 'tree) |
| @@ -2527,21 +2527,36 @@ try matching its doc string against `custom-guess-doc-alist'." | |||
| 2527 | ((eq state 'hidden) | 2527 | ((eq state 'hidden) |
| 2528 | ;; Indicate hidden value. | 2528 | ;; Indicate hidden value. |
| 2529 | (push (widget-create-child-and-convert | 2529 | (push (widget-create-child-and-convert |
| 2530 | widget 'item | 2530 | widget 'custom-visibility |
| 2531 | :format "%{%t%}: " | ||
| 2532 | :sample-face 'custom-variable-tag | ||
| 2533 | :tag tag | ||
| 2534 | :parent widget) | ||
| 2535 | buttons) | ||
| 2536 | (push (widget-create-child-and-convert | ||
| 2537 | widget 'visibility | ||
| 2538 | :help-echo "Show the value of this option." | 2531 | :help-echo "Show the value of this option." |
| 2532 | :on-image "down" | ||
| 2533 | :on "Hide" | ||
| 2534 | :off-image "right" | ||
| 2539 | :off "Show Value" | 2535 | :off "Show Value" |
| 2540 | :action 'custom-toggle-parent | 2536 | :action 'custom-toggle-parent |
| 2541 | nil) | 2537 | nil) |
| 2538 | buttons) | ||
| 2539 | (insert " ") | ||
| 2540 | (push (widget-create-child-and-convert | ||
| 2541 | widget 'item | ||
| 2542 | :format "%{%t%} " | ||
| 2543 | :sample-face 'custom-variable-tag | ||
| 2544 | :tag tag | ||
| 2545 | :parent widget) | ||
| 2542 | buttons)) | 2546 | buttons)) |
| 2543 | ((memq form '(lisp mismatch)) | 2547 | ((memq form '(lisp mismatch)) |
| 2544 | ;; In lisp mode edit the saved value when possible. | 2548 | ;; In lisp mode edit the saved value when possible. |
| 2549 | (push (widget-create-child-and-convert | ||
| 2550 | widget 'custom-visibility | ||
| 2551 | :help-echo "Hide the value of this option." | ||
| 2552 | :on "Hide" | ||
| 2553 | :off "Show" | ||
| 2554 | :on-image "down" | ||
| 2555 | :off-image "right" | ||
| 2556 | :action 'custom-toggle-parent | ||
| 2557 | t) | ||
| 2558 | buttons) | ||
| 2559 | (insert " ") | ||
| 2545 | (let* ((value (cond ((get symbol 'saved-value) | 2560 | (let* ((value (cond ((get symbol 'saved-value) |
| 2546 | (car (get symbol 'saved-value))) | 2561 | (car (get symbol 'saved-value))) |
| 2547 | ((get symbol 'standard-value) | 2562 | ((get symbol 'standard-value) |
| @@ -2552,15 +2567,6 @@ try matching its doc string against `custom-guess-doc-alist'." | |||
| 2552 | (custom-quote (widget-get conv :value)))))) | 2567 | (custom-quote (widget-get conv :value)))))) |
| 2553 | (insert (symbol-name symbol) ": ") | 2568 | (insert (symbol-name symbol) ": ") |
| 2554 | (push (widget-create-child-and-convert | 2569 | (push (widget-create-child-and-convert |
| 2555 | widget 'visibility | ||
| 2556 | :help-echo "Hide the value of this option." | ||
| 2557 | :on "Hide Value" | ||
| 2558 | :off "Show Value" | ||
| 2559 | :action 'custom-toggle-parent | ||
| 2560 | t) | ||
| 2561 | buttons) | ||
| 2562 | (insert " ") | ||
| 2563 | (push (widget-create-child-and-convert | ||
| 2564 | widget 'sexp | 2570 | widget 'sexp |
| 2565 | :button-face 'custom-variable-button-face | 2571 | :button-face 'custom-variable-button-face |
| 2566 | :format "%v" | 2572 | :format "%v" |
| @@ -2570,6 +2576,17 @@ try matching its doc string against `custom-guess-doc-alist'." | |||
| 2570 | children))) | 2576 | children))) |
| 2571 | (t | 2577 | (t |
| 2572 | ;; Edit mode. | 2578 | ;; Edit mode. |
| 2579 | (push (widget-create-child-and-convert | ||
| 2580 | widget 'custom-visibility | ||
| 2581 | :help-echo "Hide or show this option." | ||
| 2582 | :on "Hide" | ||
| 2583 | :off "Show" | ||
| 2584 | :on-image "down" | ||
| 2585 | :off-image "right" | ||
| 2586 | :action 'custom-toggle-parent | ||
| 2587 | t) | ||
| 2588 | buttons) | ||
| 2589 | (insert " ") | ||
| 2573 | (let* ((format (widget-get type :format)) | 2590 | (let* ((format (widget-get type :format)) |
| 2574 | tag-format value-format) | 2591 | tag-format value-format) |
| 2575 | (unless (string-match ":" format) | 2592 | (unless (string-match ":" format) |
| @@ -2586,15 +2603,6 @@ try matching its doc string against `custom-guess-doc-alist'." | |||
| 2586 | :sample-face 'custom-variable-tag | 2603 | :sample-face 'custom-variable-tag |
| 2587 | tag) | 2604 | tag) |
| 2588 | buttons) | 2605 | buttons) |
| 2589 | (insert " ") | ||
| 2590 | (push (widget-create-child-and-convert | ||
| 2591 | widget 'visibility | ||
| 2592 | :help-echo "Hide the value of this option." | ||
| 2593 | :on "Hide Value" | ||
| 2594 | :off "Show Value" | ||
| 2595 | :action 'custom-toggle-parent | ||
| 2596 | t) | ||
| 2597 | buttons) | ||
| 2598 | (push (widget-create-child-and-convert | 2606 | (push (widget-create-child-and-convert |
| 2599 | widget type | 2607 | widget type |
| 2600 | :format value-format | 2608 | :format value-format |
| @@ -2626,7 +2634,7 @@ try matching its doc string against `custom-guess-doc-alist'." | |||
| 2626 | ;; Don't push it !!! Custom assumes that the first child is the | 2634 | ;; Don't push it !!! Custom assumes that the first child is the |
| 2627 | ;; value one. | 2635 | ;; value one. |
| 2628 | (setq children (append children (list comment-widget))))) | 2636 | (setq children (append children (list comment-widget))))) |
| 2629 | ;; Update the rest of the properties properties. | 2637 | ;; Update the rest of the properties. |
| 2630 | (widget-put widget :custom-form form) | 2638 | (widget-put widget :custom-form form) |
| 2631 | (widget-put widget :children children) | 2639 | (widget-put widget :children children) |
| 2632 | ;; Now update the state. | 2640 | ;; Now update the state. |
| @@ -2649,61 +2657,69 @@ try matching its doc string against `custom-guess-doc-alist'." | |||
| 2649 | (apply 'widget-apply (car (widget-get (widget-get widget :parent) :children)) | 2657 | (apply 'widget-apply (car (widget-get (widget-get widget :parent) :children)) |
| 2650 | :mouse-down-action args)) | 2658 | :mouse-down-action args)) |
| 2651 | 2659 | ||
| 2652 | (defun custom-variable-state-set (widget) | 2660 | (defun custom-variable-state (symbol val) |
| 2653 | "Set the state of WIDGET." | 2661 | "Return the state of SYMBOL if its value is VAL. |
| 2654 | (let* ((symbol (widget-value widget)) | 2662 | If SYMBOL has a non-nil `custom-get' property, it overrides VAL. |
| 2655 | (get (or (get symbol 'custom-get) 'default-value)) | 2663 | Possible return values are `standard', `saved', `set', `themed', |
| 2664 | `changed', and `rogue'." | ||
| 2665 | (let* ((get (or (get symbol 'custom-get) 'default-value)) | ||
| 2656 | (value (if (default-boundp symbol) | 2666 | (value (if (default-boundp symbol) |
| 2657 | (funcall get symbol) | 2667 | (funcall get symbol) |
| 2658 | (widget-get widget :value))) | 2668 | val)) |
| 2659 | (comment (get symbol 'variable-comment)) | 2669 | (comment (get symbol 'variable-comment)) |
| 2660 | tmp | 2670 | tmp |
| 2661 | temp | 2671 | temp) |
| 2662 | (state (cond ((progn (setq tmp (get symbol 'customized-value)) | 2672 | (cond ((progn (setq tmp (get symbol 'customized-value)) |
| 2663 | (setq temp | 2673 | (setq temp |
| 2664 | (get symbol 'customized-variable-comment)) | 2674 | (get symbol 'customized-variable-comment)) |
| 2665 | (or tmp temp)) | 2675 | (or tmp temp)) |
| 2666 | (if (condition-case nil | 2676 | (if (condition-case nil |
| 2667 | (and (equal value (eval (car tmp))) | 2677 | (and (equal value (eval (car tmp))) |
| 2668 | (equal comment temp)) | 2678 | (equal comment temp)) |
| 2669 | (error nil)) | 2679 | (error nil)) |
| 2670 | 'set | 2680 | 'set |
| 2671 | 'changed)) | 2681 | 'changed)) |
| 2672 | ((progn (setq tmp (get symbol 'theme-value)) | 2682 | ((progn (setq tmp (get symbol 'theme-value)) |
| 2673 | (setq temp (get symbol 'saved-variable-comment)) | 2683 | (setq temp (get symbol 'saved-variable-comment)) |
| 2674 | (or tmp temp)) | 2684 | (or tmp temp)) |
| 2675 | (if (condition-case nil | 2685 | (if (condition-case nil |
| 2676 | (and (equal comment temp) | 2686 | (and (equal comment temp) |
| 2677 | (equal value | 2687 | (equal value |
| 2678 | (eval | 2688 | (eval |
| 2679 | (car (custom-variable-theme-value | 2689 | (car (custom-variable-theme-value |
| 2680 | symbol))))) | 2690 | symbol))))) |
| 2681 | (error nil)) | 2691 | (error nil)) |
| 2682 | (cond | 2692 | (cond |
| 2683 | ((eq (caar tmp) 'user) 'saved) | 2693 | ((eq (caar tmp) 'user) 'saved) |
| 2684 | ((eq (caar tmp) 'changed) | 2694 | ((eq (caar tmp) 'changed) |
| 2685 | (if (condition-case nil | 2695 | (if (condition-case nil |
| 2686 | (and (null comment) | 2696 | (and (null comment) |
| 2687 | (equal value | 2697 | (equal value |
| 2688 | (eval | 2698 | (eval |
| 2689 | (car (get symbol 'standard-value))))) | 2699 | (car (get symbol 'standard-value))))) |
| 2690 | (error nil)) | 2700 | (error nil)) |
| 2691 | ;; The value was originally set outside | 2701 | ;; The value was originally set outside |
| 2692 | ;; custom, but it was set to the standard | 2702 | ;; custom, but it was set to the standard |
| 2693 | ;; value (probably an autoloaded defcustom). | 2703 | ;; value (probably an autoloaded defcustom). |
| 2694 | 'standard | 2704 | 'standard |
| 2695 | 'changed)) | 2705 | 'changed)) |
| 2696 | (t 'themed)) | 2706 | (t 'themed)) |
| 2697 | 'changed)) | 2707 | 'changed)) |
| 2698 | ((setq tmp (get symbol 'standard-value)) | 2708 | ((setq tmp (get symbol 'standard-value)) |
| 2699 | (if (condition-case nil | 2709 | (if (condition-case nil |
| 2700 | (and (equal value (eval (car tmp))) | 2710 | (and (equal value (eval (car tmp))) |
| 2701 | (equal comment nil)) | 2711 | (equal comment nil)) |
| 2702 | (error nil)) | 2712 | (error nil)) |
| 2703 | 'standard | 2713 | 'standard |
| 2704 | 'changed)) | 2714 | 'changed)) |
| 2705 | (t 'rogue)))) | 2715 | (t 'rogue)))) |
| 2706 | (widget-put widget :custom-state state))) | 2716 | |
| 2717 | (defun custom-variable-state-set (widget &optional state) | ||
| 2718 | "Set the state of WIDGET to STATE. | ||
| 2719 | If STATE is nil, the value is computed by `custom-variable-state'." | ||
| 2720 | (widget-put widget :custom-state | ||
| 2721 | (or state (custom-variable-state (widget-value widget) | ||
| 2722 | (widget-get widget :value))))) | ||
| 2707 | 2723 | ||
| 2708 | (defun custom-variable-standard-value (widget) | 2724 | (defun custom-variable-standard-value (widget) |
| 2709 | (get (widget-value widget) 'standard-value)) | 2725 | (get (widget-value widget) 'standard-value)) |
| @@ -2989,7 +3005,9 @@ to switch between two values." | |||
| 2989 | :button-face 'custom-visibility | 3005 | :button-face 'custom-visibility |
| 2990 | :pressed-face 'custom-visibility | 3006 | :pressed-face 'custom-visibility |
| 2991 | :mouse-face 'highlight | 3007 | :mouse-face 'highlight |
| 2992 | :pressed-face 'highlight) | 3008 | :pressed-face 'highlight |
| 3009 | :on-image nil | ||
| 3010 | :off-image nil) | ||
| 2993 | 3011 | ||
| 2994 | (defface custom-visibility | 3012 | (defface custom-visibility |
| 2995 | '((t :height 0.8 :inherit link)) | 3013 | '((t :height 0.8 :inherit link)) |
| @@ -3336,6 +3354,18 @@ SPEC must be a full face spec." | |||
| 3336 | (insert " " tag "\n") | 3354 | (insert " " tag "\n") |
| 3337 | (widget-put widget :buttons buttons)) | 3355 | (widget-put widget :buttons buttons)) |
| 3338 | (t | 3356 | (t |
| 3357 | ;; Visibility. | ||
| 3358 | (push (widget-create-child-and-convert | ||
| 3359 | widget 'custom-visibility | ||
| 3360 | :help-echo "Hide or show this face." | ||
| 3361 | :on "Hide" | ||
| 3362 | :off "Show" | ||
| 3363 | :on-image "down" | ||
| 3364 | :off-image "right" | ||
| 3365 | :action 'custom-toggle-parent | ||
| 3366 | (not (eq state 'hidden))) | ||
| 3367 | buttons) | ||
| 3368 | (insert " ") | ||
| 3339 | ;; Create tag. | 3369 | ;; Create tag. |
| 3340 | (insert tag) | 3370 | (insert tag) |
| 3341 | (widget-specify-sample widget begin (point)) | 3371 | (widget-specify-sample widget begin (point)) |
| @@ -3350,16 +3380,6 @@ SPEC must be a full face spec." | |||
| 3350 | :sample-face symbol | 3380 | :sample-face symbol |
| 3351 | :tag "sample") | 3381 | :tag "sample") |
| 3352 | buttons) | 3382 | buttons) |
| 3353 | ;; Visibility. | ||
| 3354 | (insert " ") | ||
| 3355 | (push (widget-create-child-and-convert | ||
| 3356 | widget 'visibility | ||
| 3357 | :help-echo "Hide or show this face." | ||
| 3358 | :on "Hide Face" | ||
| 3359 | :off "Show Face" | ||
| 3360 | :action 'custom-toggle-parent | ||
| 3361 | (not (eq state 'hidden))) | ||
| 3362 | buttons) | ||
| 3363 | ;; Magic. | 3383 | ;; Magic. |
| 3364 | (insert "\n") | 3384 | (insert "\n") |
| 3365 | (let ((magic (widget-create-child-and-convert | 3385 | (let ((magic (widget-create-child-and-convert |
| @@ -3911,8 +3931,11 @@ If GROUPS-ONLY non-nil, return only those members that are groups." | |||
| 3911 | (insert " " tag "\n") | 3931 | (insert " " tag "\n") |
| 3912 | (widget-put widget :buttons buttons) | 3932 | (widget-put widget :buttons buttons) |
| 3913 | (message "Creating group...") | 3933 | (message "Creating group...") |
| 3914 | (let* ((members (custom-sort-items members | 3934 | (let* ((members (custom-sort-items |
| 3915 | custom-browse-sort-alphabetically | 3935 | members |
| 3936 | ;; Never sort the top-level custom group. | ||
| 3937 | (unless (eq symbol 'emacs) | ||
| 3938 | custom-browse-sort-alphabetically) | ||
| 3916 | custom-browse-order-groups)) | 3939 | custom-browse-order-groups)) |
| 3917 | (prefixes (widget-get widget :custom-prefixes)) | 3940 | (prefixes (widget-get widget :custom-prefixes)) |
| 3918 | (custom-prefix-list (custom-prefix-add symbol prefixes)) | 3941 | (custom-prefix-list (custom-prefix-add symbol prefixes)) |
| @@ -3970,17 +3993,21 @@ If GROUPS-ONLY non-nil, return only those members that are groups." | |||
| 3970 | 3993 | ||
| 3971 | ;; Nested style. | 3994 | ;; Nested style. |
| 3972 | (t ;Visible. | 3995 | (t ;Visible. |
| 3996 | ;; Draw a horizontal line (this works for both graphical | ||
| 3997 | ;; and text displays): | ||
| 3998 | (let ((p (point))) | ||
| 3999 | (insert "\n") | ||
| 4000 | (put-text-property p (1+ p) 'face '(:underline t)) | ||
| 4001 | (overlay-put (make-overlay p (1+ p)) | ||
| 4002 | 'before-string | ||
| 4003 | (propertize "\n" 'face '(:underline t) | ||
| 4004 | 'display '(space :align-to 999)))) | ||
| 4005 | |||
| 3973 | ;; Add parent groups references above the group. | 4006 | ;; Add parent groups references above the group. |
| 3974 | (if t ;;; This should test that the buffer | 4007 | (when (eq level 1) |
| 3975 | ;;; was made to display a group. | 4008 | (if (custom-add-parent-links widget "Parent groups:") |
| 3976 | (when (eq level 1) | 4009 | (insert "\n"))) |
| 3977 | (if (custom-add-parent-links widget | ||
| 3978 | "Parent groups:" | ||
| 3979 | "Parent group documentation:") | ||
| 3980 | (insert "\n")))) | ||
| 3981 | ;; Create level indicator. | ||
| 3982 | (insert-char ?\ (* custom-buffer-indent (1- level))) | 4010 | (insert-char ?\ (* custom-buffer-indent (1- level))) |
| 3983 | (insert "/- ") | ||
| 3984 | ;; Create tag. | 4011 | ;; Create tag. |
| 3985 | (let ((start (point))) | 4012 | (let ((start (point))) |
| 3986 | (insert tag " group: ") | 4013 | (insert tag " group: ") |
| @@ -4000,12 +4027,7 @@ If GROUPS-ONLY non-nil, return only those members that are groups." | |||
| 4000 | (not (eq state 'hidden))) | 4027 | (not (eq state 'hidden))) |
| 4001 | buttons) | 4028 | buttons) |
| 4002 | (insert " ")) | 4029 | (insert " ")) |
| 4003 | ;; Create more dashes. | 4030 | (insert "\n") |
| 4004 | ;; Use 76 instead of 75 to compensate for the temporary "<" | ||
| 4005 | ;; added by `widget-insert'. | ||
| 4006 | (insert-char ?- (- 76 (current-column) | ||
| 4007 | (* custom-buffer-indent level))) | ||
| 4008 | (insert "\\\n") | ||
| 4009 | ;; Create magic button. | 4031 | ;; Create magic button. |
| 4010 | (let ((magic (widget-create-child-and-convert | 4032 | (let ((magic (widget-create-child-and-convert |
| 4011 | widget 'custom-magic | 4033 | widget 'custom-magic |
| @@ -4031,43 +4053,50 @@ If GROUPS-ONLY non-nil, return only those members that are groups." | |||
| 4031 | ?\ )) | 4053 | ?\ )) |
| 4032 | ;; Members. | 4054 | ;; Members. |
| 4033 | (message "Creating group...") | 4055 | (message "Creating group...") |
| 4034 | (let* ((members (custom-sort-items members | 4056 | (let* ((members (custom-sort-items |
| 4035 | custom-buffer-sort-alphabetically | 4057 | members |
| 4036 | custom-buffer-order-groups)) | 4058 | ;; Never sort the top-level custom group. |
| 4059 | (unless (eq symbol 'emacs) | ||
| 4060 | custom-buffer-sort-alphabetically) | ||
| 4061 | custom-buffer-order-groups)) | ||
| 4037 | (prefixes (widget-get widget :custom-prefixes)) | 4062 | (prefixes (widget-get widget :custom-prefixes)) |
| 4038 | (custom-prefix-list (custom-prefix-add symbol prefixes)) | 4063 | (custom-prefix-list (custom-prefix-add symbol prefixes)) |
| 4039 | (length (length members)) | 4064 | (len (length members)) |
| 4040 | (count 0) | 4065 | (count 0) |
| 4041 | (children (mapcar (lambda (entry) | 4066 | (reporter (make-progress-reporter |
| 4042 | (widget-insert "\n") | 4067 | "Creating group entries..." 0 len)) |
| 4043 | (message "\ | 4068 | children) |
| 4044 | Creating group members... %2d%%" | 4069 | (setq children |
| 4045 | (/ (* 100.0 count) length)) | 4070 | (mapcar |
| 4046 | (setq count (1+ count)) | 4071 | (lambda (entry) |
| 4047 | (prog1 | 4072 | (widget-insert "\n") |
| 4048 | (widget-create-child-and-convert | 4073 | (progress-reporter-update reporter (setq count (1+ count))) |
| 4049 | widget (nth 1 entry) | 4074 | (let ((sym (nth 0 entry)) |
| 4050 | :group widget | 4075 | (type (nth 1 entry)) |
| 4051 | :tag (custom-unlispify-tag-name | 4076 | hidden-p) |
| 4052 | (nth 0 entry)) | 4077 | (prog1 |
| 4053 | :custom-prefixes custom-prefix-list | 4078 | (widget-create-child-and-convert |
| 4054 | :custom-level (1+ level) | 4079 | widget type |
| 4055 | :value (nth 0 entry)) | 4080 | :group widget |
| 4056 | (unless (eq (preceding-char) ?\n) | 4081 | :tag (custom-unlispify-tag-name sym) |
| 4057 | (widget-insert "\n")))) | 4082 | :custom-prefixes custom-prefix-list |
| 4058 | members))) | 4083 | :custom-level (1+ level) |
| 4059 | (message "Creating group magic...") | 4084 | :value sym) |
| 4085 | (unless (eq (preceding-char) ?\n) | ||
| 4086 | (widget-insert "\n"))))) | ||
| 4087 | members)) | ||
| 4060 | (mapc 'custom-magic-reset children) | 4088 | (mapc 'custom-magic-reset children) |
| 4061 | (message "Creating group state...") | ||
| 4062 | (widget-put widget :children children) | 4089 | (widget-put widget :children children) |
| 4063 | (custom-group-state-update widget) | 4090 | (custom-group-state-update widget) |
| 4064 | (message "Creating group... done")) | 4091 | (progress-reporter-done reporter)) |
| 4065 | ;; End line | 4092 | ;; End line |
| 4066 | (insert "\n") | 4093 | (let ((p (point))) |
| 4067 | (insert-char ?\ (* custom-buffer-indent (1- level))) | 4094 | (insert "\n") |
| 4068 | (insert "\\- " (widget-get widget :tag) " group end ") | 4095 | (put-text-property p (1+ p) 'face '(:underline t)) |
| 4069 | (insert-char ?- (- 75 (current-column) (* custom-buffer-indent level))) | 4096 | (overlay-put (make-overlay p (1+ p)) |
| 4070 | (insert "/\n"))))) | 4097 | 'before-string |
| 4098 | (propertize "\n" 'face '(:underline t) | ||
| 4099 | 'display '(space :align-to 999)))))))) | ||
| 4071 | 4100 | ||
| 4072 | (defvar custom-group-menu | 4101 | (defvar custom-group-menu |
| 4073 | `(("Set for Current Session" custom-group-set | 4102 | `(("Set for Current Session" custom-group-set |
diff --git a/lisp/wid-edit.el b/lisp/wid-edit.el index a087f17a900..7633de3a202 100644 --- a/lisp/wid-edit.el +++ b/lisp/wid-edit.el | |||
| @@ -639,8 +639,7 @@ extension (xpm, xbm, gif, jpg, or png) located in | |||
| 639 | (dolist (elt widget-image-conversion) | 639 | (dolist (elt widget-image-conversion) |
| 640 | (dolist (ext (cdr elt)) | 640 | (dolist (ext (cdr elt)) |
| 641 | (push (list :type (car elt) :file (concat image ext)) specs))) | 641 | (push (list :type (car elt) :file (concat image ext)) specs))) |
| 642 | (setq specs (nreverse specs)) | 642 | (find-image (nreverse specs)))) |
| 643 | (find-image specs))) | ||
| 644 | (t | 643 | (t |
| 645 | ;; Oh well. | 644 | ;; Oh well. |
| 646 | nil))) | 645 | nil))) |
| @@ -2806,11 +2805,19 @@ Return an alist of (TYPE MATCH)." | |||
| 2806 | ;;; The `visibility' Widget. | 2805 | ;;; The `visibility' Widget. |
| 2807 | 2806 | ||
| 2808 | (define-widget 'visibility 'item | 2807 | (define-widget 'visibility 'item |
| 2809 | "An indicator and manipulator for hidden items." | 2808 | "An indicator and manipulator for hidden items. |
| 2809 | |||
| 2810 | The following properties have special meanings for this widget: | ||
| 2811 | :on-image Image filename or spec to display when the item is visible. | ||
| 2812 | :on Text shown if the \"on\" image is nil or cannot be displayed. | ||
| 2813 | :off-image Image filename or spec to display when the item is hidden. | ||
| 2814 | :off Text shown if the \"off\" image is nil cannot be displayed." | ||
| 2810 | :format "%[%v%]" | 2815 | :format "%[%v%]" |
| 2811 | :button-prefix "" | 2816 | :button-prefix "" |
| 2812 | :button-suffix "" | 2817 | :button-suffix "" |
| 2818 | :on-image "down" | ||
| 2813 | :on "Hide" | 2819 | :on "Hide" |
| 2820 | :off-image "right" | ||
| 2814 | :off "Show" | 2821 | :off "Show" |
| 2815 | :value-create 'widget-visibility-value-create | 2822 | :value-create 'widget-visibility-value-create |
| 2816 | :action 'widget-toggle-action | 2823 | :action 'widget-toggle-action |
| @@ -2818,21 +2825,17 @@ Return an alist of (TYPE MATCH)." | |||
| 2818 | 2825 | ||
| 2819 | (defun widget-visibility-value-create (widget) | 2826 | (defun widget-visibility-value-create (widget) |
| 2820 | ;; Insert text representing the `on' and `off' states. | 2827 | ;; Insert text representing the `on' and `off' states. |
| 2821 | (let ((on (widget-get widget :on)) | 2828 | (let* ((val (widget-value widget)) |
| 2822 | (off (widget-get widget :off))) | 2829 | (text (widget-get widget (if val :on :off))) |
| 2823 | (if on | 2830 | (img (widget-image-find |
| 2824 | (setq on (concat widget-push-button-prefix | 2831 | (widget-get widget (if val :on-image :off-image))))) |
| 2825 | on | 2832 | (widget-image-insert widget |
| 2826 | widget-push-button-suffix)) | 2833 | (if text |
| 2827 | (setq on "")) | 2834 | (concat widget-push-button-prefix text |
| 2828 | (if off | 2835 | widget-push-button-suffix) |
| 2829 | (setq off (concat widget-push-button-prefix | 2836 | "") |
| 2830 | off | 2837 | (if img |
| 2831 | widget-push-button-suffix)) | 2838 | (append img '(:ascent center)))))) |
| 2832 | (setq off "")) | ||
| 2833 | (if (widget-value widget) | ||
| 2834 | (widget-image-insert widget on "down" "down-pushed") | ||
| 2835 | (widget-image-insert widget off "right" "right-pushed")))) | ||
| 2836 | 2839 | ||
| 2837 | ;;; The `documentation-link' Widget. | 2840 | ;;; The `documentation-link' Widget. |
| 2838 | ;; | 2841 | ;; |
| @@ -2935,7 +2938,7 @@ link for that string." | |||
| 2935 | (widget-create-child-and-convert | 2938 | (widget-create-child-and-convert |
| 2936 | widget (widget-get widget :visibility-widget) | 2939 | widget (widget-get widget :visibility-widget) |
| 2937 | :help-echo "Show or hide rest of the documentation." | 2940 | :help-echo "Show or hide rest of the documentation." |
| 2938 | :on "Hide Rest" | 2941 | :on "Hide" |
| 2939 | :off "More" | 2942 | :off "More" |
| 2940 | :always-active t | 2943 | :always-active t |
| 2941 | :action 'widget-parent-action | 2944 | :action 'widget-parent-action |