diff options
| author | Per Abrahamsen | 1997-05-31 06:34:12 +0000 |
|---|---|---|
| committer | Per Abrahamsen | 1997-05-31 06:34:12 +0000 |
| commit | 3acab5ef06adfb75be4e3c1bb3167c4426ac9d5e (patch) | |
| tree | f9e7feb4c76cb241f0b58187a3119d4bfb79f65e | |
| parent | 166246f79d6ad544f0058aaa5fe05207416df5da (diff) | |
| download | emacs-3acab5ef06adfb75be4e3c1bb3167c4426ac9d5e.tar.gz emacs-3acab5ef06adfb75be4e3c1bb3167c4426ac9d5e.zip | |
Synched with version 1.9901.
| -rw-r--r-- | lisp/cus-edit.el | 183 | ||||
| -rw-r--r-- | lisp/wid-edit.el | 212 | ||||
| -rw-r--r-- | lisp/widget.el | 8 |
3 files changed, 259 insertions, 144 deletions
diff --git a/lisp/cus-edit.el b/lisp/cus-edit.el index e15a39a015c..c4d6b7f6c2f 100644 --- a/lisp/cus-edit.el +++ b/lisp/cus-edit.el | |||
| @@ -4,7 +4,7 @@ | |||
| 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.9900 | 7 | ;; Version: 1.9901 |
| 8 | ;; X-URL: http://www.dina.kvl.dk/~abraham/custom/ | 8 | ;; X-URL: http://www.dina.kvl.dk/~abraham/custom/ |
| 9 | 9 | ||
| 10 | ;; This file is part of GNU Emacs. | 10 | ;; This file is part of GNU Emacs. |
| @@ -517,7 +517,7 @@ if that fails, the doc string with `custom-guess-doc-alist'." | |||
| 517 | "Function used for sorting group members in buffers. | 517 | "Function used for sorting group members in buffers. |
| 518 | The value should be useful as a predicate for `sort'. | 518 | The value should be useful as a predicate for `sort'. |
| 519 | The list to be sorted is the value of the groups `custom-group' property." | 519 | The list to be sorted is the value of the groups `custom-group' property." |
| 520 | :type '(radio (function-item 'custom-buffer-sort-alphabetically) | 520 | :type '(radio (function-item custom-buffer-sort-alphabetically) |
| 521 | (function :tag "Other")) | 521 | (function :tag "Other")) |
| 522 | :group 'customize) | 522 | :group 'customize) |
| 523 | 523 | ||
| @@ -539,7 +539,7 @@ sorted after all non-groups." | |||
| 539 | "Function used for sorting group members in menus. | 539 | "Function used for sorting group members in menus. |
| 540 | The value should be useful as a predicate for `sort'. | 540 | The value should be useful as a predicate for `sort'. |
| 541 | The list to be sorted is the value of the groups `custom-group' property." | 541 | The list to be sorted is the value of the groups `custom-group' property." |
| 542 | :type '(radio (function-item 'custom-menu-sort-alphabetically) | 542 | :type '(radio (function-item custom-menu-sort-alphabetically) |
| 543 | (function :tag "Other")) | 543 | (function :tag "Other")) |
| 544 | :group 'customize) | 544 | :group 'customize) |
| 545 | 545 | ||
| @@ -1028,8 +1028,8 @@ uninitialized, you should not see this.") | |||
| 1028 | (unknown "?" italic "\ | 1028 | (unknown "?" italic "\ |
| 1029 | unknown, you should not see this.") | 1029 | unknown, you should not see this.") |
| 1030 | (hidden "-" default "\ | 1030 | (hidden "-" default "\ |
| 1031 | hidden, invoke the state button to show." "\ | 1031 | hidden, invoke the dots above to show." "\ |
| 1032 | group now hidden, invoke the state button to show contents.") | 1032 | group now hidden, invoke the dots above to show contents.") |
| 1033 | (invalid "x" custom-invalid-face "\ | 1033 | (invalid "x" custom-invalid-face "\ |
| 1034 | the value displayed for this item is invalid and cannot be set.") | 1034 | the value displayed for this item is invalid and cannot be set.") |
| 1035 | (modified "*" custom-modified-face "\ | 1035 | (modified "*" custom-modified-face "\ |
| @@ -1088,12 +1088,18 @@ left out, ITEM-DESC will be used. | |||
| 1088 | The list should be sorted most significant first.") | 1088 | The list should be sorted most significant first.") |
| 1089 | 1089 | ||
| 1090 | (defcustom custom-magic-show 'long | 1090 | (defcustom custom-magic-show 'long |
| 1091 | "Show long description of the state of each customization option." | 1091 | "If non-nil, show textual description of the state. |
| 1092 | If non-nil and not the symbol `long', only show first word." | ||
| 1092 | :type '(choice (const :tag "no" nil) | 1093 | :type '(choice (const :tag "no" nil) |
| 1093 | (const short) | 1094 | (const short) |
| 1094 | (const long)) | 1095 | (const long)) |
| 1095 | :group 'customize) | 1096 | :group 'customize) |
| 1096 | 1097 | ||
| 1098 | (defcustom custom-magic-show-hidden nil | ||
| 1099 | "If non-nil, also show long state description of hidden options." | ||
| 1100 | :type 'boolean | ||
| 1101 | :group 'customize) | ||
| 1102 | |||
| 1097 | (defcustom custom-magic-show-button nil | 1103 | (defcustom custom-magic-show-button nil |
| 1098 | "Show a magic button indicating the state of each customization option." | 1104 | "Show a magic button indicating the state of each customization option." |
| 1099 | :type 'boolean | 1105 | :type 'boolean |
| @@ -1118,6 +1124,7 @@ The list should be sorted most significant first.") | |||
| 1118 | ;; Create compact status report for WIDGET. | 1124 | ;; Create compact status report for WIDGET. |
| 1119 | (let* ((parent (widget-get widget :parent)) | 1125 | (let* ((parent (widget-get widget :parent)) |
| 1120 | (state (widget-get parent :custom-state)) | 1126 | (state (widget-get parent :custom-state)) |
| 1127 | (hidden (eq state 'hidden)) | ||
| 1121 | (entry (assq state custom-magic-alist)) | 1128 | (entry (assq state custom-magic-alist)) |
| 1122 | (magic (nth 1 entry)) | 1129 | (magic (nth 1 entry)) |
| 1123 | (face (nth 2 entry)) | 1130 | (face (nth 2 entry)) |
| @@ -1126,13 +1133,14 @@ The list should be sorted most significant first.") | |||
| 1126 | (nth 3 entry))) | 1133 | (nth 3 entry))) |
| 1127 | (lisp (eq (widget-get parent :custom-form) 'lisp)) | 1134 | (lisp (eq (widget-get parent :custom-form) 'lisp)) |
| 1128 | children) | 1135 | children) |
| 1129 | (when custom-magic-show | 1136 | (when (and custom-magic-show |
| 1137 | (or custom-magic-show-hidden (not hidden))) | ||
| 1130 | (insert " ") | 1138 | (insert " ") |
| 1131 | (push (widget-create-child-and-convert | 1139 | (push (widget-create-child-and-convert |
| 1132 | widget 'choice-item | 1140 | widget 'choice-item |
| 1133 | :help-echo "\ | 1141 | :help-echo "\ |
| 1134 | Change the state of this item." | 1142 | Change the state of this item." |
| 1135 | :format "%[%t%]" | 1143 | :format (if hidden "%t" "%[%t%]") |
| 1136 | :button-prefix 'widget-push-button-prefix | 1144 | :button-prefix 'widget-push-button-prefix |
| 1137 | :button-suffix 'widget-push-button-suffix | 1145 | :button-suffix 'widget-push-button-suffix |
| 1138 | :mouse-down-action 'widget-magic-mouse-down-action | 1146 | :mouse-down-action 'widget-magic-mouse-down-action |
| @@ -1154,8 +1162,10 @@ Change the state of this item." | |||
| 1154 | widget 'choice-item | 1162 | widget 'choice-item |
| 1155 | :mouse-down-action 'widget-magic-mouse-down-action | 1163 | :mouse-down-action 'widget-magic-mouse-down-action |
| 1156 | :button-face face | 1164 | :button-face face |
| 1165 | :button-prefix "" | ||
| 1166 | :button-suffix "" | ||
| 1157 | :help-echo "Change the state." | 1167 | :help-echo "Change the state." |
| 1158 | :format "%[%t%]" | 1168 | :format (if hidden "%t" "%[%t%]") |
| 1159 | :tag (if lisp | 1169 | :tag (if lisp |
| 1160 | (concat "(" magic ")") | 1170 | (concat "(" magic ")") |
| 1161 | (concat "[" magic "]"))) | 1171 | (concat "[" magic "]"))) |
| @@ -1201,13 +1211,25 @@ Change the state of this item." | |||
| 1201 | (level (widget-get widget :custom-level))) | 1211 | (level (widget-get widget :custom-level))) |
| 1202 | (cond ((eq escape ?l) | 1212 | (cond ((eq escape ?l) |
| 1203 | (when level | 1213 | (when level |
| 1204 | (push (widget-create-child-and-convert | 1214 | (if (eq state 'hidden) |
| 1205 | widget 'item :format "%v " (make-string level ?*)) | 1215 | (insert-char ?- (* 2 level)) |
| 1206 | buttons) | 1216 | (insert "/" (make-string (1- (* 2 level)) ?-))))) |
| 1207 | (widget-put widget :buttons buttons))) | 1217 | ((eq escape ?e) |
| 1218 | (when (and level (not (eq state 'hidden))) | ||
| 1219 | (insert "\n\\" (make-string (1- (* 2 level)) ?-) " " | ||
| 1220 | (widget-get widget :tag) " group end ") | ||
| 1221 | (insert (make-string (- 75 (current-column)) ?-) "/\n"))) | ||
| 1222 | ((eq escape ?-) | ||
| 1223 | (when level | ||
| 1224 | (if (eq state 'hidden) | ||
| 1225 | (insert-char ?- (- 77 (current-column))) | ||
| 1226 | (insert (make-string (- 76 (current-column)) ?-) "\\")))) | ||
| 1208 | ((eq escape ?L) | 1227 | ((eq escape ?L) |
| 1209 | (when (eq state 'hidden) | 1228 | (push (widget-create-child-and-convert |
| 1210 | (widget-insert " ..."))) | 1229 | widget 'visibility |
| 1230 | :action 'custom-toggle-parent | ||
| 1231 | (not (eq state 'hidden))) | ||
| 1232 | buttons)) | ||
| 1211 | ((eq escape ?m) | 1233 | ((eq escape ?m) |
| 1212 | (and (eq (preceding-char) ?\n) | 1234 | (and (eq (preceding-char) ?\n) |
| 1213 | (widget-get widget :indent) | 1235 | (widget-get widget :indent) |
| @@ -1218,27 +1240,28 @@ Change the state of this item." | |||
| 1218 | (push magic buttons) | 1240 | (push magic buttons) |
| 1219 | (widget-put widget :buttons buttons))) | 1241 | (widget-put widget :buttons buttons))) |
| 1220 | ((eq escape ?a) | 1242 | ((eq escape ?a) |
| 1221 | (let* ((symbol (widget-get widget :value)) | 1243 | (unless (eq state 'hidden) |
| 1222 | (links (get symbol 'custom-links)) | 1244 | (let* ((symbol (widget-get widget :value)) |
| 1223 | (many (> (length links) 2))) | 1245 | (links (get symbol 'custom-links)) |
| 1224 | (when links | 1246 | (many (> (length links) 2))) |
| 1225 | (and (eq (preceding-char) ?\n) | 1247 | (when links |
| 1226 | (widget-get widget :indent) | 1248 | (and (eq (preceding-char) ?\n) |
| 1227 | (insert-char ? (widget-get widget :indent))) | 1249 | (widget-get widget :indent) |
| 1228 | (insert "See also ") | 1250 | (insert-char ? (widget-get widget :indent))) |
| 1229 | (while links | 1251 | (insert "See also ") |
| 1230 | (push (widget-create-child-and-convert widget (car links)) | 1252 | (while links |
| 1231 | buttons) | 1253 | (push (widget-create-child-and-convert widget (car links)) |
| 1232 | (setq links (cdr links)) | 1254 | buttons) |
| 1233 | (cond ((null links) | 1255 | (setq links (cdr links)) |
| 1234 | (insert ".\n")) | 1256 | (cond ((null links) |
| 1235 | ((null (cdr links)) | 1257 | (insert ".\n")) |
| 1236 | (if many | 1258 | ((null (cdr links)) |
| 1237 | (insert ", and ") | 1259 | (if many |
| 1238 | (insert " and "))) | 1260 | (insert ", and ") |
| 1239 | (t | 1261 | (insert " and "))) |
| 1240 | (insert ", ")))) | 1262 | (t |
| 1241 | (widget-put widget :buttons buttons)))) | 1263 | (insert ", ")))) |
| 1264 | (widget-put widget :buttons buttons))))) | ||
| 1242 | (t | 1265 | (t |
| 1243 | (widget-default-format-handler widget escape))))) | 1266 | (widget-default-format-handler widget escape))))) |
| 1244 | 1267 | ||
| @@ -1329,9 +1352,14 @@ Change the state of this item." | |||
| 1329 | ((eq state 'hidden) | 1352 | ((eq state 'hidden) |
| 1330 | (widget-put widget :custom-state 'unknown)) | 1353 | (widget-put widget :custom-state 'unknown)) |
| 1331 | (t | 1354 | (t |
| 1355 | (widget-put widget :documentation-shown nil) | ||
| 1332 | (widget-put widget :custom-state 'hidden))) | 1356 | (widget-put widget :custom-state 'hidden))) |
| 1333 | (custom-redraw widget))) | 1357 | (custom-redraw widget))) |
| 1334 | 1358 | ||
| 1359 | (defun custom-toggle-parent (widget &rest ignore) | ||
| 1360 | "Toggle visibility of parent to WIDGET." | ||
| 1361 | (custom-toggle-hide (widget-get widget :parent))) | ||
| 1362 | |||
| 1335 | ;;; The `custom-variable' Widget. | 1363 | ;;; The `custom-variable' Widget. |
| 1336 | 1364 | ||
| 1337 | (defface custom-variable-sample-face '((t (:underline t))) | 1365 | (defface custom-variable-sample-face '((t (:underline t))) |
| @@ -1405,11 +1433,16 @@ Otherwise, look up symbol in `custom-guess-type-alist'." | |||
| 1405 | ;; Indicate hidden value. | 1433 | ;; Indicate hidden value. |
| 1406 | (push (widget-create-child-and-convert | 1434 | (push (widget-create-child-and-convert |
| 1407 | widget 'item | 1435 | widget 'item |
| 1408 | :format "%{%t%}: ..." | 1436 | :format "%{%t%}: " |
| 1409 | :sample-face 'custom-variable-sample-face | 1437 | :sample-face 'custom-variable-sample-face |
| 1410 | :tag tag | 1438 | :tag tag |
| 1411 | :parent widget) | 1439 | :parent widget) |
| 1412 | children)) | 1440 | buttons) |
| 1441 | (push (widget-create-child-and-convert | ||
| 1442 | widget 'visibility | ||
| 1443 | :action 'custom-toggle-parent | ||
| 1444 | nil) | ||
| 1445 | buttons)) | ||
| 1413 | ((eq form 'lisp) | 1446 | ((eq form 'lisp) |
| 1414 | ;; In lisp mode edit the saved value when possible. | 1447 | ;; In lisp mode edit the saved value when possible. |
| 1415 | (let* ((value (cond ((get symbol 'saved-value) | 1448 | (let* ((value (cond ((get symbol 'saved-value) |
| @@ -1420,22 +1453,49 @@ Otherwise, look up symbol in `custom-guess-type-alist'." | |||
| 1420 | (custom-quote (funcall get symbol))) | 1453 | (custom-quote (funcall get symbol))) |
| 1421 | (t | 1454 | (t |
| 1422 | (custom-quote (widget-get conv :value)))))) | 1455 | (custom-quote (widget-get conv :value)))))) |
| 1456 | (insert (symbol-name symbol) ": ") | ||
| 1457 | (push (widget-create-child-and-convert | ||
| 1458 | widget 'visibility | ||
| 1459 | :action 'custom-toggle-parent | ||
| 1460 | t) | ||
| 1461 | buttons) | ||
| 1462 | (insert " ") | ||
| 1423 | (push (widget-create-child-and-convert | 1463 | (push (widget-create-child-and-convert |
| 1424 | widget 'sexp | 1464 | widget 'sexp |
| 1425 | :button-face 'custom-variable-button-face | 1465 | :button-face 'custom-variable-button-face |
| 1466 | :format "%v" | ||
| 1426 | :tag (symbol-name symbol) | 1467 | :tag (symbol-name symbol) |
| 1427 | :parent widget | 1468 | :parent widget |
| 1428 | :value value) | 1469 | :value value) |
| 1429 | children))) | 1470 | children))) |
| 1430 | (t | 1471 | (t |
| 1431 | ;; Edit mode. | 1472 | ;; Edit mode. |
| 1432 | (push (widget-create-child-and-convert | 1473 | (let* ((format (widget-get type :format)) |
| 1433 | widget type | 1474 | tag-format value-format) |
| 1434 | :tag tag | 1475 | (unless (string-match ":" format) |
| 1435 | :button-face 'custom-variable-button-face | 1476 | (error "Bad format.")) |
| 1436 | :sample-face 'custom-variable-sample-face | 1477 | (setq tag-format (substring format 0 (match-end 0))) |
| 1437 | :value value) | 1478 | (setq value-format (substring format (match-end 0))) |
| 1438 | children))) | 1479 | (push (widget-create-child-and-convert |
| 1480 | widget 'item | ||
| 1481 | :format tag-format | ||
| 1482 | :action 'custom-tag-action | ||
| 1483 | :mouse-down-action 'custom-tag-mouse-down-action | ||
| 1484 | :button-face 'custom-variable-button-face | ||
| 1485 | :sample-face 'custom-variable-sample-face | ||
| 1486 | tag) | ||
| 1487 | buttons) | ||
| 1488 | (insert " ") | ||
| 1489 | (push (widget-create-child-and-convert | ||
| 1490 | widget 'visibility | ||
| 1491 | :action 'custom-toggle-parent | ||
| 1492 | t) | ||
| 1493 | buttons) | ||
| 1494 | (push (widget-create-child-and-convert | ||
| 1495 | widget type | ||
| 1496 | :format value-format | ||
| 1497 | :value value) | ||
| 1498 | children)))) | ||
| 1439 | ;; Now update the state. | 1499 | ;; Now update the state. |
| 1440 | (unless (eq (preceding-char) ?\n) | 1500 | (unless (eq (preceding-char) ?\n) |
| 1441 | (widget-insert "\n")) | 1501 | (widget-insert "\n")) |
| @@ -1446,6 +1506,16 @@ Otherwise, look up symbol in `custom-guess-type-alist'." | |||
| 1446 | (widget-put widget :buttons buttons) | 1506 | (widget-put widget :buttons buttons) |
| 1447 | (widget-put widget :children children))) | 1507 | (widget-put widget :children children))) |
| 1448 | 1508 | ||
| 1509 | (defun custom-tag-action (widget &rest args) | ||
| 1510 | "Pass :action to first child of WIDGET's parent." | ||
| 1511 | (apply 'widget-apply (car (widget-get (widget-get widget :parent) :children)) | ||
| 1512 | :action args)) | ||
| 1513 | |||
| 1514 | (defun custom-tag-mouse-down-action (widget &rest args) | ||
| 1515 | "Pass :mouse-down-action to first child of WIDGET's parent." | ||
| 1516 | (apply 'widget-apply (car (widget-get (widget-get widget :parent) :children)) | ||
| 1517 | :mouse-down-action args)) | ||
| 1518 | |||
| 1449 | (defun custom-variable-state-set (widget) | 1519 | (defun custom-variable-state-set (widget) |
| 1450 | "Set the state of WIDGET." | 1520 | "Set the state of WIDGET." |
| 1451 | (let* ((symbol (widget-value widget)) | 1521 | (let* ((symbol (widget-value widget)) |
| @@ -1476,10 +1546,7 @@ Otherwise, look up symbol in `custom-guess-type-alist'." | |||
| 1476 | (widget-put widget :custom-state state))) | 1546 | (widget-put widget :custom-state state))) |
| 1477 | 1547 | ||
| 1478 | (defvar custom-variable-menu | 1548 | (defvar custom-variable-menu |
| 1479 | '(("Hide" custom-toggle-hide | 1549 | '(("Edit" custom-variable-edit |
| 1480 | (lambda (widget) | ||
| 1481 | (not (memq (widget-get widget :custom-state) '(modified invalid))))) | ||
| 1482 | ("Edit" custom-variable-edit | ||
| 1483 | (lambda (widget) | 1550 | (lambda (widget) |
| 1484 | (not (eq (widget-get widget :custom-form) 'edit)))) | 1551 | (not (eq (widget-get widget :custom-form) 'edit)))) |
| 1485 | ("Edit Lisp" custom-variable-edit-lisp | 1552 | ("Edit Lisp" custom-variable-edit-lisp |
| @@ -1712,7 +1779,7 @@ Match frames with dark backgrounds.") | |||
| 1712 | 1779 | ||
| 1713 | (define-widget 'custom-face 'custom | 1780 | (define-widget 'custom-face 'custom |
| 1714 | "Customize face." | 1781 | "Customize face." |
| 1715 | :format "%{%t%}: %s%m%h%a%v" | 1782 | :format "%{%t%}: %s %L\n%m%h%a%v" |
| 1716 | :format-handler 'custom-face-format-handler | 1783 | :format-handler 'custom-face-format-handler |
| 1717 | :sample-face 'custom-face-tag-face | 1784 | :sample-face 'custom-face-tag-face |
| 1718 | :help-echo "Set or reset this face." | 1785 | :help-echo "Set or reset this face." |
| @@ -1739,7 +1806,7 @@ Match frames with dark backgrounds.") | |||
| 1739 | (copy-face 'custom-face-empty symbol)) | 1806 | (copy-face 'custom-face-empty symbol)) |
| 1740 | (setq child (widget-create-child-and-convert | 1807 | (setq child (widget-create-child-and-convert |
| 1741 | widget 'item | 1808 | widget 'item |
| 1742 | :format "(%{%t%})\n" | 1809 | :format "(%{%t%})" |
| 1743 | :sample-face symbol | 1810 | :sample-face symbol |
| 1744 | :tag "sample"))) | 1811 | :tag "sample"))) |
| 1745 | (t | 1812 | (t |
| @@ -1813,10 +1880,7 @@ Match frames with dark backgrounds.") | |||
| 1813 | (message "Creating face editor...done"))) | 1880 | (message "Creating face editor...done"))) |
| 1814 | 1881 | ||
| 1815 | (defvar custom-face-menu | 1882 | (defvar custom-face-menu |
| 1816 | '(("Hide" custom-toggle-hide | 1883 | '(("Edit Selected" custom-face-edit-selected |
| 1817 | (lambda (widget) | ||
| 1818 | (not (memq (widget-get widget :custom-state) '(modified invalid))))) | ||
| 1819 | ("Edit Selected" custom-face-edit-selected | ||
| 1820 | (lambda (widget) | 1884 | (lambda (widget) |
| 1821 | (not (eq (widget-get widget :custom-form) 'selected)))) | 1885 | (not (eq (widget-get widget :custom-form) 'selected)))) |
| 1822 | ("Edit All" custom-face-edit-all | 1886 | ("Edit All" custom-face-edit-all |
| @@ -1955,7 +2019,7 @@ Optional EVENT is the location for the menu." | |||
| 1955 | (let* ((symbol (widget-value widget)) | 2019 | (let* ((symbol (widget-value widget)) |
| 1956 | (child (widget-create-child-and-convert | 2020 | (child (widget-create-child-and-convert |
| 1957 | widget 'custom-face | 2021 | widget 'custom-face |
| 1958 | :format "%t %s%m%h%v" | 2022 | :format "%t %s %L\n%m%h%v" |
| 1959 | :custom-level nil | 2023 | :custom-level nil |
| 1960 | :value symbol))) | 2024 | :value symbol))) |
| 1961 | (custom-magic-reset child) | 2025 | (custom-magic-reset child) |
| @@ -2039,7 +2103,7 @@ and so forth. The remaining group tags are shown with | |||
| 2039 | 2103 | ||
| 2040 | (define-widget 'custom-group 'custom | 2104 | (define-widget 'custom-group 'custom |
| 2041 | "Customize group." | 2105 | "Customize group." |
| 2042 | :format "%l%{%t%}:%L\n%m%h%a%v" | 2106 | :format "%l %{%t%} group: %L %-\n%m%h%a%v%e" |
| 2043 | :sample-face-get 'custom-group-sample-face-get | 2107 | :sample-face-get 'custom-group-sample-face-get |
| 2044 | :documentation-property 'group-documentation | 2108 | :documentation-property 'group-documentation |
| 2045 | :help-echo "Set or reset all members of this group." | 2109 | :help-echo "Set or reset all members of this group." |
| @@ -2096,10 +2160,7 @@ and so forth. The remaining group tags are shown with | |||
| 2096 | (message "Creating group... done"))))) | 2160 | (message "Creating group... done"))))) |
| 2097 | 2161 | ||
| 2098 | (defvar custom-group-menu | 2162 | (defvar custom-group-menu |
| 2099 | '(("Hide" custom-toggle-hide | 2163 | '(("Set" custom-group-set |
| 2100 | (lambda (widget) | ||
| 2101 | (not (memq (widget-get widget :custom-state) '(modified invalid))))) | ||
| 2102 | ("Set" custom-group-set | ||
| 2103 | (lambda (widget) | 2164 | (lambda (widget) |
| 2104 | (eq (widget-get widget :custom-state) 'modified))) | 2165 | (eq (widget-get widget :custom-state) 'modified))) |
| 2105 | ("Save" custom-group-save | 2166 | ("Save" custom-group-save |
diff --git a/lisp/wid-edit.el b/lisp/wid-edit.el index 6de406f4c4c..6749807bb2e 100644 --- a/lisp/wid-edit.el +++ b/lisp/wid-edit.el | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | ;; | 4 | ;; |
| 5 | ;; Author: Per Abrahamsen <abraham@dina.kvl.dk> | 5 | ;; Author: Per Abrahamsen <abraham@dina.kvl.dk> |
| 6 | ;; Keywords: extensions | 6 | ;; Keywords: extensions |
| 7 | ;; Version: 1.9900 | 7 | ;; Version: 1.9901 |
| 8 | ;; X-URL: http://www.dina.kvl.dk/~abraham/custom/ | 8 | ;; X-URL: http://www.dina.kvl.dk/~abraham/custom/ |
| 9 | 9 | ||
| 10 | ;; This file is part of GNU Emacs. | 10 | ;; This file is part of GNU Emacs. |
| @@ -31,6 +31,7 @@ | |||
| 31 | ;;; Code: | 31 | ;;; Code: |
| 32 | 32 | ||
| 33 | (require 'widget) | 33 | (require 'widget) |
| 34 | (eval-when-compile (require 'cl)) | ||
| 34 | 35 | ||
| 35 | ;;; Compatibility. | 36 | ;;; Compatibility. |
| 36 | 37 | ||
| @@ -567,27 +568,23 @@ automatically." | |||
| 567 | (repeat :tag "Suffixes" | 568 | (repeat :tag "Suffixes" |
| 568 | (string :format "%v"))))) | 569 | (string :format "%v"))))) |
| 569 | 570 | ||
| 570 | (defun widget-glyph-insert (widget tag image) | 571 | (defun widget-glyph-find (image tag) |
| 571 | "In WIDGET, insert the text TAG or, if supported, IMAGE. | 572 | "Create a glyph corresponding to IMAGE with string TAG as fallback. |
| 572 | IMAGE should either be a glyph, an image instantiator, or an image file | 573 | IMAGE should either already be a glyph, or be a file name sans |
| 573 | name sans extension (xpm, xbm, gif, jpg, or png) located in | 574 | extension (xpm, xbm, gif, jpg, or png) located in |
| 574 | `widget-glyph-directory'. | 575 | `widget-glyph-directory'." |
| 575 | 576 | (cond ((not (and image | |
| 576 | WARNING: If you call this with a glyph, and you want the user to be | 577 | (string-match "XEmacs" emacs-version) |
| 577 | able to invoke the glyph, make sure it is unique. If you use the | ||
| 578 | same glyph for multiple widgets, invoking any of the glyphs will | ||
| 579 | cause the last created widget to be invoked." | ||
| 580 | (cond ((not (and (string-match "XEmacs" emacs-version) | ||
| 581 | widget-glyph-enable | 578 | widget-glyph-enable |
| 582 | (fboundp 'make-glyph) | 579 | (fboundp 'make-glyph) |
| 583 | (fboundp 'locate-file) | 580 | (fboundp 'locate-file) |
| 584 | image)) | 581 | image)) |
| 585 | ;; We don't want or can't use glyphs. | 582 | ;; We don't want or can't use glyphs. |
| 586 | (insert tag)) | 583 | nil) |
| 587 | ((and (fboundp 'glyphp) | 584 | ((and (fboundp 'glyphp) |
| 588 | (glyphp image)) | 585 | (glyphp image)) |
| 589 | ;; Already a glyph. Insert it. | 586 | ;; Already a glyph. Use it. |
| 590 | (widget-glyph-insert-glyph widget image)) | 587 | image) |
| 591 | ((stringp image) | 588 | ((stringp image) |
| 592 | ;; A string. Look it up in relevant directories. | 589 | ;; A string. Look it up in relevant directories. |
| 593 | (let* ((dirlist (list (or widget-glyph-directory | 590 | (let* ((dirlist (list (or widget-glyph-directory |
| @@ -599,50 +596,65 @@ cause the last created widget to be invoked." | |||
| 599 | (while (and formats (not file)) | 596 | (while (and formats (not file)) |
| 600 | (if (valid-image-instantiator-format-p (car (car formats))) | 597 | (if (valid-image-instantiator-format-p (car (car formats))) |
| 601 | (setq file (locate-file image dirlist | 598 | (setq file (locate-file image dirlist |
| 602 | (mapconcat 'identity (cdr (car formats)) | 599 | (mapconcat 'identity |
| 600 | (cdr (car formats)) | ||
| 603 | ":"))) | 601 | ":"))) |
| 604 | (setq formats (cdr formats)))) | 602 | (setq formats (cdr formats)))) |
| 605 | ;; We create a glyph with the file as the default image | 603 | ;; We create a glyph with the file as the default image |
| 606 | ;; instantiator, and the TAG fallback | 604 | ;; instantiator, and the TAG fallback |
| 607 | (widget-glyph-insert-glyph | 605 | (make-glyph (if file |
| 608 | widget | 606 | (list (vector (car (car formats)) ':file file) |
| 609 | (make-glyph (if file | 607 | (vector 'string ':data tag)) |
| 610 | (list (vector (car (car formats)) ':file file) | 608 | (vector 'string ':data tag))))) |
| 611 | (vector 'string ':data tag)) | ||
| 612 | (vector 'string ':data tag)))))) | ||
| 613 | ((valid-instantiator-p image 'image) | 609 | ((valid-instantiator-p image 'image) |
| 614 | ;; A valid image instantiator (e.g. [gif :file "somefile"] etc.) | 610 | ;; A valid image instantiator (e.g. [gif :file "somefile"] etc.) |
| 615 | (widget-glyph-insert-glyph | 611 | (make-glyph (list image |
| 616 | widget | 612 | (vector 'string ':data tag)))) |
| 617 | (make-glyph (list image | ||
| 618 | (vector 'string ':data tag))))) | ||
| 619 | (t | 613 | (t |
| 620 | ;; Oh well. | 614 | ;; Oh well. |
| 621 | (insert tag)))) | 615 | nil))) |
| 616 | |||
| 617 | (defun widget-glyph-insert (widget tag image &optional down inactive) | ||
| 618 | "In WIDGET, insert the text TAG or, if supported, IMAGE. | ||
| 619 | IMAGE should either be a glyph, an image instantiator, or an image file | ||
| 620 | name sans extension (xpm, xbm, gif, jpg, or png) located in | ||
| 621 | `widget-glyph-directory'. | ||
| 622 | |||
| 623 | Optional arguments DOWN and INACTIVE is used instead of IMAGE when the | ||
| 624 | glyph is pressed or inactive, respectively. | ||
| 625 | |||
| 626 | WARNING: If you call this with a glyph, and you want the user to be | ||
| 627 | able to invoke the glyph, make sure it is unique. If you use the | ||
| 628 | same glyph for multiple widgets, invoking any of the glyphs will | ||
| 629 | cause the last created widget to be invoked." | ||
| 630 | (let ((glyph (widget-glyph-find image tag))) | ||
| 631 | (if glyph | ||
| 632 | (widget-glyph-insert-glyph widget | ||
| 633 | glyph | ||
| 634 | (widget-glyph-find down tag) | ||
| 635 | (widget-glyph-find inactive tag)) | ||
| 636 | (insert tag)))) | ||
| 622 | 637 | ||
| 623 | (defun widget-glyph-insert-glyph (widget glyph &optional down inactive) | 638 | (defun widget-glyph-insert-glyph (widget glyph &optional down inactive) |
| 624 | "In WIDGET, with alternative text TAG, insert GLYPH." | 639 | "In WIDGET, insert GLYPH. |
| 640 | If optional arguments DOWN and INACTIVE are given, they should be | ||
| 641 | glyphs used when the widget is pushed and inactive, respectively." | ||
| 625 | (set-glyph-property glyph 'widget widget) | 642 | (set-glyph-property glyph 'widget widget) |
| 626 | (when down | 643 | (when down |
| 627 | (set-glyph-property down 'widget widget)) | 644 | (set-glyph-property down 'widget widget)) |
| 628 | (when inactive | 645 | (when inactive |
| 629 | (set-glyph-property inactive 'widget widget)) | 646 | (set-glyph-property inactive 'widget widget)) |
| 630 | (insert "*") | 647 | (insert "*") |
| 631 | (add-text-properties (1- (point)) (point) | 648 | (let ((ext (make-extent (point) (1- (point)))) |
| 632 | (list 'invisible t | 649 | (help-echo (widget-get widget :help-echo))) |
| 633 | 'end-glyph glyph)) | 650 | (set-extent-property ext 'invisible t) |
| 651 | (set-extent-end-glyph ext glyph) | ||
| 652 | (when help-echo | ||
| 653 | (set-extent-property ext 'balloon-help help-echo) | ||
| 654 | (set-extent-property ext 'help-echo help-echo))) | ||
| 634 | (widget-put widget :glyph-up glyph) | 655 | (widget-put widget :glyph-up glyph) |
| 635 | (when down (widget-put widget :glyph-down down)) | 656 | (when down (widget-put widget :glyph-down down)) |
| 636 | (when inactive (widget-put widget :glyph-inactive inactive)) | 657 | (when inactive (widget-put widget :glyph-inactive inactive))) |
| 637 | (let ((help-echo (widget-get widget :help-echo))) | ||
| 638 | (when help-echo | ||
| 639 | (let ((extent (extent-at (1- (point)) nil 'end-glyph)) | ||
| 640 | (help-property (if (featurep 'balloon-help) | ||
| 641 | 'balloon-help | ||
| 642 | 'help-echo))) | ||
| 643 | (set-extent-property extent help-property (if (stringp help-echo) | ||
| 644 | help-echo | ||
| 645 | 'widget-mouse-help)))))) | ||
| 646 | 658 | ||
| 647 | ;;; Buttons. | 659 | ;;; Buttons. |
| 648 | 660 | ||
| @@ -653,12 +665,12 @@ cause the last created widget to be invoked." | |||
| 653 | (defcustom widget-button-prefix "" | 665 | (defcustom widget-button-prefix "" |
| 654 | "String used as prefix for buttons." | 666 | "String used as prefix for buttons." |
| 655 | :type 'string | 667 | :type 'string |
| 656 | :group 'widgets) | 668 | :group 'widget-button) |
| 657 | 669 | ||
| 658 | (defcustom widget-button-suffix "" | 670 | (defcustom widget-button-suffix "" |
| 659 | "String used as suffix for buttons." | 671 | "String used as suffix for buttons." |
| 660 | :type 'string | 672 | :type 'string |
| 661 | :group 'widgets) | 673 | :group 'widget-button) |
| 662 | 674 | ||
| 663 | (defun widget-button-insert-indirect (widget key) | 675 | (defun widget-button-insert-indirect (widget key) |
| 664 | "Insert value of WIDGET's KEY property." | 676 | "Insert value of WIDGET's KEY property." |
| @@ -1313,20 +1325,10 @@ Optional EVENT is the event that triggered the action." | |||
| 1313 | ;; Get rid of trailing newlines. | 1325 | ;; Get rid of trailing newlines. |
| 1314 | (when (string-match "\n+\\'" doc-text) | 1326 | (when (string-match "\n+\\'" doc-text) |
| 1315 | (setq doc-text (substring doc-text 0 (match-beginning 0)))) | 1327 | (setq doc-text (substring doc-text 0 (match-beginning 0)))) |
| 1316 | (setq buttons | 1328 | (push (widget-create-child-and-convert |
| 1317 | (cons (if (string-match "\n." doc-text) | 1329 | widget 'documentation-string |
| 1318 | ;; Allow multiline doc to be hiden. | 1330 | doc-text) |
| 1319 | (widget-create-child-and-convert | 1331 | buttons))) |
| 1320 | widget 'widget-help | ||
| 1321 | :doc (progn | ||
| 1322 | (string-match "\\`.*" doc-text) | ||
| 1323 | (match-string 0 doc-text)) | ||
| 1324 | :widget-doc doc-text | ||
| 1325 | "?") | ||
| 1326 | ;; A single line is just inserted. | ||
| 1327 | (widget-create-child-and-convert | ||
| 1328 | widget 'item :format "%d" :doc doc-text nil)) | ||
| 1329 | buttons)))) | ||
| 1330 | (t | 1332 | (t |
| 1331 | (error "Unknown escape `%c'" escape))) | 1333 | (error "Unknown escape `%c'" escape))) |
| 1332 | (widget-put widget :buttons buttons))) | 1334 | (widget-put widget :buttons buttons))) |
| @@ -1495,8 +1497,7 @@ If END is omitted, it defaults to the length of LIST." | |||
| 1495 | (progn | 1497 | (progn |
| 1496 | (unless gui | 1498 | (unless gui |
| 1497 | (setq gui (make-gui-button tag 'widget-gui-action widget)) | 1499 | (setq gui (make-gui-button tag 'widget-gui-action widget)) |
| 1498 | (setq widget-push-button-cache | 1500 | (push (cons tag gui) widget-push-button-cache)) |
| 1499 | (cons (cons tag gui) widget-push-button-cache))) | ||
| 1500 | (widget-glyph-insert-glyph widget | 1501 | (widget-glyph-insert-glyph widget |
| 1501 | (make-glyph | 1502 | (make-glyph |
| 1502 | (list (nth 0 (aref gui 1)) | 1503 | (list (nth 0 (aref gui 1)) |
| @@ -2451,14 +2452,13 @@ when he invoked the menu." | |||
| 2451 | (and (eq (preceding-char) ?\n) | 2452 | (and (eq (preceding-char) ?\n) |
| 2452 | (widget-get widget :indent) | 2453 | (widget-get widget :indent) |
| 2453 | (insert-char ? (widget-get widget :indent))) | 2454 | (insert-char ? (widget-get widget :indent))) |
| 2454 | (setq children | 2455 | (push (cond ((null answer) |
| 2455 | (cons (cond ((null answer) | 2456 | (widget-create-child widget arg)) |
| 2456 | (widget-create-child widget arg)) | 2457 | ((widget-get arg :inline) |
| 2457 | ((widget-get arg :inline) | 2458 | (widget-create-child-value widget arg (car answer))) |
| 2458 | (widget-create-child-value widget arg (car answer))) | 2459 | (t |
| 2459 | (t | 2460 | (widget-create-child-value widget arg (car (car answer))))) |
| 2460 | (widget-create-child-value widget arg (car (car answer))))) | 2461 | children)) |
| 2461 | children))) | ||
| 2462 | (widget-put widget :children (nreverse children)))) | 2462 | (widget-put widget :children (nreverse children)))) |
| 2463 | 2463 | ||
| 2464 | (defun widget-group-match (widget values) | 2464 | (defun widget-group-match (widget values) |
| @@ -2484,20 +2484,74 @@ when he invoked the menu." | |||
| 2484 | (cons found vals) | 2484 | (cons found vals) |
| 2485 | nil))) | 2485 | nil))) |
| 2486 | 2486 | ||
| 2487 | ;;; The `widget-help' Widget. | 2487 | ;;; The `visibility' Widget. |
| 2488 | 2488 | ||
| 2489 | (define-widget 'widget-help 'push-button | 2489 | (define-widget 'visibility 'item |
| 2490 | "The widget documentation button." | 2490 | "An indicator and manipulator for hidden items." |
| 2491 | :format "%[%v%] %d" | 2491 | :format "%[%v%]" |
| 2492 | :help-echo "Toggle display of documentation." | 2492 | :button-prefix "" |
| 2493 | :action 'widget-help-action) | 2493 | :button-suffix "" |
| 2494 | :on "hide" | ||
| 2495 | :off "more" | ||
| 2496 | :value-create 'widget-visibility-value-create | ||
| 2497 | :action 'widget-toggle-action | ||
| 2498 | :match (lambda (widget value) t)) | ||
| 2494 | 2499 | ||
| 2495 | (defun widget-help-action (widget &optional event) | 2500 | (defun widget-visibility-value-create (widget) |
| 2496 | "Toggle documentation for WIDGET." | 2501 | ;; Insert text representing the `on' and `off' states. |
| 2497 | (let ((old (widget-get widget :doc)) | 2502 | (let ((on (widget-get widget :on)) |
| 2498 | (new (widget-get widget :widget-doc))) | 2503 | (off (widget-get widget :off))) |
| 2499 | (widget-put widget :doc new) | 2504 | (if on |
| 2500 | (widget-put widget :widget-doc old)) | 2505 | (setq on (concat widget-push-button-prefix |
| 2506 | on | ||
| 2507 | widget-push-button-suffix)) | ||
| 2508 | (setq on "")) | ||
| 2509 | (if off | ||
| 2510 | (setq off (concat widget-push-button-prefix | ||
| 2511 | off | ||
| 2512 | widget-push-button-suffix)) | ||
| 2513 | (setq off "")) | ||
| 2514 | (if (widget-value widget) | ||
| 2515 | (widget-glyph-insert widget on "down" "down-pushed") | ||
| 2516 | (widget-glyph-insert widget off "right" "right-pushed") | ||
| 2517 | (insert "...")))) | ||
| 2518 | |||
| 2519 | ;;; The `documentation-string' Widget. | ||
| 2520 | |||
| 2521 | (define-widget 'documentation-string 'item | ||
| 2522 | "A documentation string." | ||
| 2523 | :format "%v" | ||
| 2524 | :action 'widget-documentation-string-action | ||
| 2525 | :value-delete 'widget-children-value-delete | ||
| 2526 | :value-create 'widget-documentation-string-value-create) | ||
| 2527 | |||
| 2528 | (defun widget-documentation-string-value-create (widget) | ||
| 2529 | ;; Insert documentation string. | ||
| 2530 | (let ((doc (widget-value widget)) | ||
| 2531 | (shown (widget-get (widget-get widget :parent) :documentation-shown))) | ||
| 2532 | (if (string-match "\n" doc) | ||
| 2533 | (let ((before (substring doc 0 (match-beginning 0))) | ||
| 2534 | (after (substring doc (match-beginning 0))) | ||
| 2535 | buttons) | ||
| 2536 | (insert before " ") | ||
| 2537 | (push (widget-create-child-and-convert | ||
| 2538 | widget 'visibility | ||
| 2539 | :off nil | ||
| 2540 | :action 'widget-parent-action | ||
| 2541 | shown) | ||
| 2542 | buttons) | ||
| 2543 | (when shown | ||
| 2544 | (insert after)) | ||
| 2545 | (widget-put widget :buttons buttons)) | ||
| 2546 | (insert doc))) | ||
| 2547 | (insert "\n")) | ||
| 2548 | |||
| 2549 | (defun widget-documentation-string-action (widget &rest ignore) | ||
| 2550 | ;; Toggle documentation. | ||
| 2551 | (let ((parent (widget-get widget :parent))) | ||
| 2552 | (widget-put parent :documentation-shown | ||
| 2553 | (not (widget-get parent :documentation-shown)))) | ||
| 2554 | ;; Redraw. | ||
| 2501 | (widget-value-set widget (widget-value widget))) | 2555 | (widget-value-set widget (widget-value widget))) |
| 2502 | 2556 | ||
| 2503 | ;;; The Sexp Widgets. | 2557 | ;;; The Sexp Widgets. |
diff --git a/lisp/widget.el b/lisp/widget.el index 1be690a6d36..8a550c15f72 100644 --- a/lisp/widget.el +++ b/lisp/widget.el | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | ;; | 4 | ;; |
| 5 | ;; Author: Per Abrahamsen <abraham@dina.kvl.dk> | 5 | ;; Author: Per Abrahamsen <abraham@dina.kvl.dk> |
| 6 | ;; Keywords: help, extensions, faces, hypermedia | 6 | ;; Keywords: help, extensions, faces, hypermedia |
| 7 | ;; Version: 1.9900 | 7 | ;; Version: 1.9901 |
| 8 | ;; X-URL: http://www.dina.kvl.dk/~abraham/custom/ | 8 | ;; X-URL: http://www.dina.kvl.dk/~abraham/custom/ |
| 9 | 9 | ||
| 10 | ;; This file is part of GNU Emacs. | 10 | ;; This file is part of GNU Emacs. |
| @@ -44,14 +44,14 @@ | |||
| 44 | (set (car keywords) (car keywords))) | 44 | (set (car keywords) (car keywords))) |
| 45 | (setq keywords (cdr keywords))))))) | 45 | (setq keywords (cdr keywords))))))) |
| 46 | 46 | ||
| 47 | (define-widget-keywords :button-prefix :button-suffix | 47 | (define-widget-keywords :documentation-shown :button-prefix |
| 48 | :mouse-down-action :glyph-up :glyph-down :glyph-inactive | 48 | :button-suffix :mouse-down-action :glyph-up :glyph-down :glyph-inactive |
| 49 | :prompt-internal :prompt-history :prompt-match | 49 | :prompt-internal :prompt-history :prompt-match |
| 50 | :prompt-value :deactivate :active | 50 | :prompt-value :deactivate :active |
| 51 | :inactive :activate :sibling-args :delete-button-args | 51 | :inactive :activate :sibling-args :delete-button-args |
| 52 | :insert-button-args :append-button-args :button-args | 52 | :insert-button-args :append-button-args :button-args |
| 53 | :tag-glyph :off-glyph :on-glyph :valid-regexp | 53 | :tag-glyph :off-glyph :on-glyph :valid-regexp |
| 54 | :secret :sample-face :sample-face-get :case-fold :widget-doc | 54 | :secret :sample-face :sample-face-get :case-fold |
| 55 | :create :convert-widget :format :value-create :offset :extra-offset | 55 | :create :convert-widget :format :value-create :offset :extra-offset |
| 56 | :tag :doc :from :to :args :value :value-from :value-to :action | 56 | :tag :doc :from :to :args :value :value-from :value-to :action |
| 57 | :value-set :value-delete :match :parent :delete :menu-tag-get | 57 | :value-set :value-delete :match :parent :delete :menu-tag-get |