Mercurial > hg > xemacs-beta
comparison lisp/custom/wid-edit.el @ 163:0132846995bd r20-3b8
Import from CVS: tag r20-3b8
author | cvs |
---|---|
date | Mon, 13 Aug 2007 09:43:35 +0200 |
parents | 28f395d8dc7a |
children | 5a88923fcbfe |
comparison
equal
deleted
inserted
replaced
162:4de2936b4e77 | 163:0132846995bd |
---|---|
2 ;; | 2 ;; |
3 ;; Copyright (C) 1996, 1997 Free Software Foundation, Inc. | 3 ;; Copyright (C) 1996, 1997 Free Software Foundation, Inc. |
4 ;; | 4 ;; |
5 ;; Author: Per Abrahamsen <abraham@dina.kvl.dk> | 5 ;; Author: Per Abrahamsen <abraham@dina.kvl.dk> |
6 ;; Keywords: extensions | 6 ;; Keywords: extensions |
7 ;; Version: 1.9916 | 7 ;; Version: 1.9931 |
8 ;; X-URL: http://www.dina.kvl.dk/~abraham/custom/ | 8 ;; X-URL: http://www.dina.kvl.dk/~abraham/custom/ |
9 | 9 |
10 ;; This file is part of GNU Emacs. | 10 ;; This file is part of GNU Emacs. |
11 | 11 |
12 ;; GNU Emacs is free software; you can redistribute it and/or modify | 12 ;; GNU Emacs is free software; you can redistribute it and/or modify |
294 (save-excursion | 294 (save-excursion |
295 (goto-char to) | 295 (goto-char to) |
296 (when widget-field-add-space | 296 (when widget-field-add-space |
297 (insert-and-inherit " ")) | 297 (insert-and-inherit " ")) |
298 (setq to (point))) | 298 (setq to (point))) |
299 (add-text-properties (1- to) to ;to (1+ to) | 299 (if widget-field-add-space |
300 '(front-sticky nil start-open t read-only to)) | 300 (add-text-properties (1- to) to |
301 '(front-sticky nil start-open t read-only to)) | |
302 (add-text-properties to (1+ to) | |
303 '(front-sticky nil start-open t read-only to))) | |
301 (add-text-properties (1- from) from | 304 (add-text-properties (1- from) from |
302 '(rear-nonsticky t end-open t read-only from)) | 305 '(rear-nonsticky t end-open t read-only from)) |
303 (let ((map (widget-get widget :keymap)) | 306 (let ((map (widget-get widget :keymap)) |
304 (face (or (widget-get widget :value-face) 'widget-field-face)) | 307 (face (or (widget-get widget :value-face) 'widget-field-face)) |
305 (help-echo (widget-get widget :help-echo)) | 308 (help-echo (widget-get widget :help-echo)) |
357 ;; Execute FORM without inheriting any text properties. | 360 ;; Execute FORM without inheriting any text properties. |
358 (` | 361 (` |
359 (save-restriction | 362 (save-restriction |
360 (let ((inhibit-read-only t) | 363 (let ((inhibit-read-only t) |
361 result | 364 result |
365 before-change-functions | |
362 after-change-functions) | 366 after-change-functions) |
363 (insert "<>") | 367 (insert "<>") |
364 (narrow-to-region (- (point) 2) (point)) | 368 (narrow-to-region (- (point) 2) (point)) |
365 (widget-specify-none (point-min) (point-max)) | 369 (widget-specify-none (point-min) (point-max)) |
366 (goto-char (1+ (point-min))) | 370 (goto-char (1+ (point-min))) |
373 (defface widget-inactive-face '((((class grayscale color) | 377 (defface widget-inactive-face '((((class grayscale color) |
374 (background dark)) | 378 (background dark)) |
375 (:foreground "light gray")) | 379 (:foreground "light gray")) |
376 (((class grayscale color) | 380 (((class grayscale color) |
377 (background light)) | 381 (background light)) |
378 (:foreground "dark gray")) | 382 (:foreground "dim gray")) |
379 (t | 383 (t |
380 (:italic t))) | 384 (:italic t))) |
381 "Face used for inactive widgets." | 385 "Face used for inactive widgets." |
382 :group 'widget-faces) | 386 :group 'widget-faces) |
383 | 387 |
433 (setq widget (get tmp 'widget-type))) | 437 (setq widget (get tmp 'widget-type))) |
434 (t | 438 (t |
435 (setq missing nil)))) | 439 (setq missing nil)))) |
436 value)) | 440 value)) |
437 | 441 |
442 (defun widget-get-indirect (widget property) | |
443 "In WIDGET, get the value of PROPERTY. | |
444 If the value is a symbol, return its binding. | |
445 Otherwise, just return the value." | |
446 (let ((value (widget-get widget property))) | |
447 (if (symbolp value) | |
448 (symbol-value value) | |
449 value))) | |
450 | |
438 (defun widget-member (widget property) | 451 (defun widget-member (widget property) |
439 "Non-nil iff there is a definition in WIDGET for PROPERTY." | 452 "Non-nil iff there is a definition in WIDGET for PROPERTY." |
440 (cond ((widget-plist-member (cdr widget) property) | 453 (cond ((widget-plist-member (cdr widget) property) |
441 t) | 454 t) |
442 ((car widget) | 455 ((car widget) |
469 (cons (list (car vals)) (cdr vals))) | 482 (cons (list (car vals)) (cdr vals))) |
470 (t nil))) | 483 (t nil))) |
471 | 484 |
472 (defun widget-apply-action (widget &optional event) | 485 (defun widget-apply-action (widget &optional event) |
473 "Apply :action in WIDGET in response to EVENT." | 486 "Apply :action in WIDGET in response to EVENT." |
474 (let (after-change-functions) | 487 (if (widget-apply widget :active) |
475 (if (widget-apply widget :active) | 488 (widget-apply widget :action event) |
476 (widget-apply widget :action event) | 489 (error "Attempt to perform action on inactive widget"))) |
477 (error "Attempt to perform action on inactive widget")))) | |
478 | 490 |
479 ;;; Helper functions. | 491 ;;; Helper functions. |
480 ;; | 492 ;; |
481 ;; These are widget specific. | 493 ;; These are widget specific. |
482 | 494 |
627 | 639 |
628 (defun widget-glyph-insert-glyph (widget glyph &optional down inactive) | 640 (defun widget-glyph-insert-glyph (widget glyph &optional down inactive) |
629 "In WIDGET, insert GLYPH. | 641 "In WIDGET, insert GLYPH. |
630 If optional arguments DOWN and INACTIVE are given, they should be | 642 If optional arguments DOWN and INACTIVE are given, they should be |
631 glyphs used when the widget is pushed and inactive, respectively." | 643 glyphs used when the widget is pushed and inactive, respectively." |
632 (set-glyph-property glyph 'widget widget) | 644 (when widget |
633 (when down | 645 (set-glyph-property glyph 'widget widget) |
634 (set-glyph-property down 'widget widget)) | 646 (when down |
635 (when inactive | 647 (set-glyph-property down 'widget widget)) |
636 (set-glyph-property inactive 'widget widget)) | 648 (when inactive |
649 (set-glyph-property inactive 'widget widget))) | |
637 (insert "*") | 650 (insert "*") |
638 (let ((ext (make-extent (point) (1- (point)))) | 651 (let ((ext (make-extent (point) (1- (point)))) |
639 (help-echo (widget-get widget :help-echo))) | 652 (help-echo (and widget (widget-get widget :help-echo)))) |
640 (set-extent-property ext 'invisible t) | 653 (set-extent-property ext 'invisible t) |
654 (set-extent-property ext 'start-open t) | |
655 (set-extent-property ext 'end-open t) | |
641 (set-extent-end-glyph ext glyph) | 656 (set-extent-end-glyph ext glyph) |
642 (when help-echo | 657 (when help-echo |
643 (set-extent-property ext 'balloon-help help-echo) | 658 (set-extent-property ext 'balloon-help help-echo) |
644 (set-extent-property ext 'help-echo help-echo))) | 659 (set-extent-property ext 'help-echo help-echo))) |
645 (widget-put widget :glyph-up glyph) | 660 (when widget |
646 (when down (widget-put widget :glyph-down down)) | 661 (widget-put widget :glyph-up glyph) |
647 (when inactive (widget-put widget :glyph-inactive inactive))) | 662 (when down (widget-put widget :glyph-down down)) |
663 (when inactive (widget-put widget :glyph-inactive inactive)))) | |
648 | 664 |
649 ;;; Buttons. | 665 ;;; Buttons. |
650 | 666 |
651 (defgroup widget-button nil | 667 (defgroup widget-button nil |
652 "The look of various kinds of buttons." | 668 "The look of various kinds of buttons." |
659 | 675 |
660 (defcustom widget-button-suffix "" | 676 (defcustom widget-button-suffix "" |
661 "String used as suffix for buttons." | 677 "String used as suffix for buttons." |
662 :type 'string | 678 :type 'string |
663 :group 'widget-button) | 679 :group 'widget-button) |
664 | |
665 (defun widget-button-insert-indirect (widget key) | |
666 "Insert value of WIDGET's KEY property." | |
667 (let ((val (widget-get widget key))) | |
668 (while (and val (symbolp val)) | |
669 (setq val (symbol-value val))) | |
670 (when val | |
671 (insert val)))) | |
672 | 680 |
673 ;;; Creating Widgets. | 681 ;;; Creating Widgets. |
674 | 682 |
675 ;;;###autoload | 683 ;;;###autoload |
676 (defun widget-create (type &rest args) | 684 (defun widget-create (type &rest args) |
766 widget)) | 774 widget)) |
767 | 775 |
768 (defun widget-insert (&rest args) | 776 (defun widget-insert (&rest args) |
769 "Call `insert' with ARGS and make the text read only." | 777 "Call `insert' with ARGS and make the text read only." |
770 (let ((inhibit-read-only t) | 778 (let ((inhibit-read-only t) |
779 before-change-functions | |
771 after-change-functions | 780 after-change-functions |
772 (from (point))) | 781 (from (point))) |
773 (apply 'insert args) | 782 (apply 'insert args) |
774 (widget-specify-text from (point)))) | 783 (widget-specify-text from (point)))) |
775 | 784 |
809 (button (widget-get widget :button-overlay)) | 818 (button (widget-get widget :button-overlay)) |
810 (field (widget-get widget :field-overlay)) | 819 (field (widget-get widget :field-overlay)) |
811 (children (widget-get widget :children))) | 820 (children (widget-get widget :children))) |
812 (set-marker from nil) | 821 (set-marker from nil) |
813 (set-marker to nil) | 822 (set-marker to nil) |
814 (delete-overlay button) | 823 (when button |
815 (delete-overlay field) | 824 (delete-overlay button)) |
825 (when field | |
826 (delete-overlay field)) | |
816 (mapcar 'widget-leave-text children))) | 827 (mapcar 'widget-leave-text children))) |
817 | 828 |
818 ;;; Keymap and Commands. | 829 ;;; Keymap and Commands. |
819 | 830 |
820 (defvar widget-keymap nil | 831 (defvar widget-keymap nil |
1112 | 1123 |
1113 (defun widget-setup () | 1124 (defun widget-setup () |
1114 "Setup current buffer so editing string widgets works." | 1125 "Setup current buffer so editing string widgets works." |
1115 (let ((inhibit-read-only t) | 1126 (let ((inhibit-read-only t) |
1116 (after-change-functions nil) | 1127 (after-change-functions nil) |
1128 before-change-functions | |
1117 field) | 1129 field) |
1118 (while widget-field-new | 1130 (while widget-field-new |
1119 (setq field (car widget-field-new) | 1131 (setq field (car widget-field-new) |
1120 widget-field-new (cdr widget-field-new) | 1132 widget-field-new (cdr widget-field-new) |
1121 widget-field-list (cons field widget-field-list)) | 1133 widget-field-list (cons field widget-field-list)) |
1126 (set-marker from nil) | 1138 (set-marker from nil) |
1127 (set-marker to nil)))) | 1139 (set-marker to nil)))) |
1128 (widget-clear-undo) | 1140 (widget-clear-undo) |
1129 ;; We need to maintain text properties and size of the editing fields. | 1141 ;; We need to maintain text properties and size of the editing fields. |
1130 (make-local-variable 'after-change-functions) | 1142 (make-local-variable 'after-change-functions) |
1131 (if (and widget-field-list) | 1143 (make-local-variable 'before-change-functions) |
1132 (setq after-change-functions '(widget-after-change)) | 1144 (setq after-change-functions |
1133 (setq after-change-functions nil))) | 1145 (if widget-field-list '(widget-after-change) nil)) |
1146 (setq before-change-functions | |
1147 (if widget-field-list '(widget-before-change) nil))) | |
1134 | 1148 |
1135 (defvar widget-field-last nil) | 1149 (defvar widget-field-last nil) |
1136 ;; Last field containing point. | 1150 ;; Last field containing point. |
1137 (make-variable-buffer-local 'widget-field-last) | 1151 (make-variable-buffer-local 'widget-field-last) |
1138 | 1152 |
1171 (when (and (<= start pos) (<= pos end)) | 1185 (when (and (<= start pos) (<= pos end)) |
1172 (when found | 1186 (when found |
1173 (debug "Overlapping fields")) | 1187 (debug "Overlapping fields")) |
1174 (setq found field)))) | 1188 (setq found field)))) |
1175 found)) | 1189 found)) |
1190 | |
1191 (defun widget-before-change (from &rest ignore) | |
1192 ;; This is how, for example, a variable changes its state to `modified'. | |
1193 ;; when it is being edited. | |
1194 (condition-case nil | |
1195 (let ((field (widget-field-find from))) | |
1196 (widget-apply field :notify field)) | |
1197 (error (debug "Before Change")))) | |
1176 | 1198 |
1177 (defun widget-after-change (from to old) | 1199 (defun widget-after-change (from to old) |
1178 ;; Adjust field size and text properties. | 1200 ;; Adjust field size and text properties. |
1179 (condition-case nil | 1201 (condition-case nil |
1180 (let ((field (widget-field-find from)) | 1202 (let ((field (widget-field-find from)) |
1317 (replace-match "" t t) | 1339 (replace-match "" t t) |
1318 (cond ((eq escape ?%) | 1340 (cond ((eq escape ?%) |
1319 (insert "%")) | 1341 (insert "%")) |
1320 ((eq escape ?\[) | 1342 ((eq escape ?\[) |
1321 (setq button-begin (point)) | 1343 (setq button-begin (point)) |
1322 (widget-button-insert-indirect widget :button-prefix)) | 1344 (insert (widget-get-indirect widget :button-prefix))) |
1323 ((eq escape ?\]) | 1345 ((eq escape ?\]) |
1324 (widget-button-insert-indirect widget :button-suffix) | 1346 (insert (widget-get-indirect widget :button-suffix)) |
1325 (setq button-end (point))) | 1347 (setq button-end (point))) |
1326 ((eq escape ?\{) | 1348 ((eq escape ?\{) |
1327 (setq sample-begin (point))) | 1349 (setq sample-begin (point))) |
1328 ((eq escape ?\}) | 1350 ((eq escape ?\}) |
1329 (setq sample-end (point))) | 1351 (setq sample-end (point))) |
1388 (t | 1410 (t |
1389 (funcall doc-property | 1411 (funcall doc-property |
1390 (widget-get widget :value))))) | 1412 (widget-get widget :value))))) |
1391 (doc-text (and (stringp doc-try) | 1413 (doc-text (and (stringp doc-try) |
1392 (> (length doc-try) 1) | 1414 (> (length doc-try) 1) |
1393 doc-try))) | 1415 doc-try)) |
1416 (doc-indent (widget-get widget :documentation-indent))) | |
1394 (when doc-text | 1417 (when doc-text |
1395 (and (eq (preceding-char) ?\n) | 1418 (and (eq (preceding-char) ?\n) |
1396 (widget-get widget :indent) | 1419 (widget-get widget :indent) |
1397 (insert-char ? (widget-get widget :indent))) | 1420 (insert-char ? (widget-get widget :indent))) |
1398 ;; The `*' in the beginning is redundant. | 1421 ;; The `*' in the beginning is redundant. |
1401 ;; Get rid of trailing newlines. | 1424 ;; Get rid of trailing newlines. |
1402 (when (string-match "\n+\\'" doc-text) | 1425 (when (string-match "\n+\\'" doc-text) |
1403 (setq doc-text (substring doc-text 0 (match-beginning 0)))) | 1426 (setq doc-text (substring doc-text 0 (match-beginning 0)))) |
1404 (push (widget-create-child-and-convert | 1427 (push (widget-create-child-and-convert |
1405 widget 'documentation-string | 1428 widget 'documentation-string |
1429 :indent (cond ((numberp doc-indent ) | |
1430 doc-indent) | |
1431 ((null doc-indent) | |
1432 nil) | |
1433 (t 0)) | |
1406 doc-text) | 1434 doc-text) |
1407 buttons)))) | 1435 buttons)))) |
1408 (t | 1436 (t |
1409 (error "Unknown escape `%c'" escape))) | 1437 (error "Unknown escape `%c'" escape))) |
1410 (widget-put widget :buttons buttons))) | 1438 (widget-put widget :buttons buttons))) |
1421 ;; Remove widget from the buffer. | 1449 ;; Remove widget from the buffer. |
1422 (let ((from (widget-get widget :from)) | 1450 (let ((from (widget-get widget :from)) |
1423 (to (widget-get widget :to)) | 1451 (to (widget-get widget :to)) |
1424 (inactive-overlay (widget-get widget :inactive)) | 1452 (inactive-overlay (widget-get widget :inactive)) |
1425 (button-overlay (widget-get widget :button-overlay)) | 1453 (button-overlay (widget-get widget :button-overlay)) |
1454 before-change-functions | |
1426 after-change-functions | 1455 after-change-functions |
1427 (inhibit-read-only t)) | 1456 (inhibit-read-only t)) |
1428 (widget-apply widget :value-delete) | 1457 (widget-apply widget :value-delete) |
1429 (when inactive-overlay | 1458 (when inactive-overlay |
1430 (delete-overlay inactive-overlay)) | 1459 (delete-overlay inactive-overlay)) |
1564 | 1593 |
1565 (defun widget-push-button-value-create (widget) | 1594 (defun widget-push-button-value-create (widget) |
1566 ;; Insert text representing the `on' and `off' states. | 1595 ;; Insert text representing the `on' and `off' states. |
1567 (let* ((tag (or (widget-get widget :tag) | 1596 (let* ((tag (or (widget-get widget :tag) |
1568 (widget-get widget :value))) | 1597 (widget-get widget :value))) |
1598 (tag-glyph (widget-get widget :tag-glyph)) | |
1569 (text (concat widget-push-button-prefix | 1599 (text (concat widget-push-button-prefix |
1570 tag widget-push-button-suffix)) | 1600 tag widget-push-button-suffix)) |
1571 (gui (cdr (assoc tag widget-push-button-cache)))) | 1601 (gui (cdr (assoc tag widget-push-button-cache)))) |
1572 (if (and (fboundp 'make-gui-button) | 1602 (cond (tag-glyph |
1603 (widget-glyph-insert widget text tag-glyph)) | |
1604 ((and (fboundp 'make-gui-button) | |
1573 (fboundp 'make-glyph) | 1605 (fboundp 'make-glyph) |
1574 widget-push-button-gui | 1606 widget-push-button-gui |
1575 (fboundp 'device-on-window-system-p) | 1607 (fboundp 'device-on-window-system-p) |
1576 (device-on-window-system-p) | 1608 (device-on-window-system-p) |
1577 (string-match "XEmacs" emacs-version)) | 1609 (string-match "XEmacs" emacs-version)) |
1578 (progn | 1610 (unless gui |
1579 (unless gui | 1611 (setq gui (make-gui-button tag 'widget-gui-action widget)) |
1580 (setq gui (make-gui-button tag 'widget-gui-action widget)) | 1612 (push (cons tag gui) widget-push-button-cache)) |
1581 (push (cons tag gui) widget-push-button-cache)) | 1613 (widget-glyph-insert-glyph widget |
1582 (widget-glyph-insert-glyph widget | 1614 (make-glyph |
1583 (make-glyph | 1615 (list (nth 0 (aref gui 1)) |
1584 (list (nth 0 (aref gui 1)) | 1616 (vector 'string ':data text))) |
1585 (vector 'string ':data text))) | 1617 (make-glyph |
1586 (make-glyph | 1618 (list (nth 1 (aref gui 1)) |
1587 (list (nth 1 (aref gui 1)) | 1619 (vector 'string ':data text))) |
1588 (vector 'string ':data text))) | 1620 (make-glyph |
1589 (make-glyph | 1621 (list (nth 2 (aref gui 1)) |
1590 (list (nth 2 (aref gui 1)) | 1622 (vector 'string ':data text))))) |
1591 (vector 'string ':data text))))) | 1623 (t |
1592 (insert text)))) | 1624 (insert text))))) |
1593 | 1625 |
1594 (defun widget-gui-action (widget) | 1626 (defun widget-gui-action (widget) |
1595 "Apply :action for WIDGET." | 1627 "Apply :action for WIDGET." |
1596 (widget-apply-action widget (this-command-keys))) | 1628 (widget-apply-action widget (this-command-keys))) |
1597 | 1629 |
2408 (defun widget-editable-list-insert-before (widget before) | 2440 (defun widget-editable-list-insert-before (widget before) |
2409 ;; Insert a new child in the list of children. | 2441 ;; Insert a new child in the list of children. |
2410 (save-excursion | 2442 (save-excursion |
2411 (let ((children (widget-get widget :children)) | 2443 (let ((children (widget-get widget :children)) |
2412 (inhibit-read-only t) | 2444 (inhibit-read-only t) |
2445 before-change-functions | |
2413 after-change-functions) | 2446 after-change-functions) |
2414 (cond (before | 2447 (cond (before |
2415 (goto-char (widget-get before :entry-from))) | 2448 (goto-char (widget-get before :entry-from))) |
2416 (t | 2449 (t |
2417 (goto-char (widget-get widget :value-pos)))) | 2450 (goto-char (widget-get widget :value-pos)))) |
2434 ;; Delete child from list of children. | 2467 ;; Delete child from list of children. |
2435 (save-excursion | 2468 (save-excursion |
2436 (let ((buttons (copy-sequence (widget-get widget :buttons))) | 2469 (let ((buttons (copy-sequence (widget-get widget :buttons))) |
2437 button | 2470 button |
2438 (inhibit-read-only t) | 2471 (inhibit-read-only t) |
2472 before-change-functions | |
2439 after-change-functions) | 2473 after-change-functions) |
2440 (while buttons | 2474 (while buttons |
2441 (setq button (car buttons) | 2475 (setq button (car buttons) |
2442 buttons (cdr buttons)) | 2476 buttons (cdr buttons)) |
2443 (when (eq (widget-get button :widget) child) | 2477 (when (eq (widget-get button :widget) child) |
2445 :buttons (delq button (widget-get widget :buttons))) | 2479 :buttons (delq button (widget-get widget :buttons))) |
2446 (widget-delete button)))) | 2480 (widget-delete button)))) |
2447 (let ((entry-from (widget-get child :entry-from)) | 2481 (let ((entry-from (widget-get child :entry-from)) |
2448 (entry-to (widget-get child :entry-to)) | 2482 (entry-to (widget-get child :entry-to)) |
2449 (inhibit-read-only t) | 2483 (inhibit-read-only t) |
2484 before-change-functions | |
2450 after-change-functions) | 2485 after-change-functions) |
2451 (widget-delete child) | 2486 (widget-delete child) |
2452 (delete-region entry-from entry-to) | 2487 (delete-region entry-from entry-to) |
2453 (set-marker entry-from nil) | 2488 (set-marker entry-from nil) |
2454 (set-marker entry-to nil)) | 2489 (set-marker entry-to nil)) |
2565 (define-widget 'visibility 'item | 2600 (define-widget 'visibility 'item |
2566 "An indicator and manipulator for hidden items." | 2601 "An indicator and manipulator for hidden items." |
2567 :format "%[%v%]" | 2602 :format "%[%v%]" |
2568 :button-prefix "" | 2603 :button-prefix "" |
2569 :button-suffix "" | 2604 :button-suffix "" |
2570 :on "hide" | 2605 :on "Hide" |
2571 :off "show" | 2606 :off "Show" |
2572 :value-create 'widget-visibility-value-create | 2607 :value-create 'widget-visibility-value-create |
2573 :action 'widget-toggle-action | 2608 :action 'widget-toggle-action |
2574 :match (lambda (widget value) t)) | 2609 :match (lambda (widget value) t)) |
2575 | 2610 |
2576 (defun widget-visibility-value-create (widget) | 2611 (defun widget-visibility-value-create (widget) |
2582 on | 2617 on |
2583 widget-push-button-suffix)) | 2618 widget-push-button-suffix)) |
2584 (setq on "")) | 2619 (setq on "")) |
2585 (if off | 2620 (if off |
2586 (setq off (concat widget-push-button-prefix | 2621 (setq off (concat widget-push-button-prefix |
2587 off | 2622 off |
2588 widget-push-button-suffix)) | 2623 widget-push-button-suffix)) |
2589 (setq off "")) | 2624 (setq off "")) |
2590 (if (widget-value widget) | 2625 (if (widget-value widget) |
2591 (widget-glyph-insert widget on "down" "down-pushed") | 2626 (widget-glyph-insert widget on "down" "down-pushed") |
2592 (widget-glyph-insert widget off "right" "right-pushed") | 2627 (widget-glyph-insert widget off "right" "right-pushed")))) |
2593 (insert "...")))) | |
2594 | 2628 |
2595 ;;; The `documentation-link' Widget. | 2629 ;;; The `documentation-link' Widget. |
2630 ;; | |
2631 ;; This is a helper widget for `documentation-string'. | |
2596 | 2632 |
2597 (define-widget 'documentation-link 'link | 2633 (define-widget 'documentation-link 'link |
2598 "Link type used in documentation strings." | 2634 "Link type used in documentation strings." |
2635 :tab-order -1 | |
2636 :help-echo 'widget-documentation-link-echo-help | |
2599 :action 'widget-documentation-link-action) | 2637 :action 'widget-documentation-link-action) |
2638 | |
2639 (defun widget-documentation-link-echo-help (widget) | |
2640 "Tell what this link will describe." | |
2641 (concat "Describe the `" (widget-get widget :value) "' symbol.")) | |
2600 | 2642 |
2601 (defun widget-documentation-link-action (widget &optional event) | 2643 (defun widget-documentation-link-action (widget &optional event) |
2602 "Run apropos on WIDGET's value. Ignore optional argument EVENT." | 2644 "Run apropos on WIDGET's value. Ignore optional argument EVENT." |
2603 (apropos (concat "\\`" (regexp-quote (widget-get widget :value)) "\\'"))) | 2645 (apropos (concat "\\`" (regexp-quote (widget-get widget :value)) "\\'"))) |
2604 | 2646 |
2633 (let ((regexp widget-documentation-link-regexp) | 2675 (let ((regexp widget-documentation-link-regexp) |
2634 (predicate widget-documentation-link-p) | 2676 (predicate widget-documentation-link-p) |
2635 (type widget-documentation-link-type) | 2677 (type widget-documentation-link-type) |
2636 (buttons (widget-get widget :buttons))) | 2678 (buttons (widget-get widget :buttons))) |
2637 (save-excursion | 2679 (save-excursion |
2638 (goto-char (point-min)) | 2680 (goto-char from) |
2639 (while (re-search-forward regexp to t) | 2681 (while (re-search-forward regexp to t) |
2640 (let ((name (match-string 1)) | 2682 (let ((name (match-string 1)) |
2641 (begin (match-beginning 0)) | 2683 (begin (match-beginning 1)) |
2642 (end (match-end 0))) | 2684 (end (match-end 1))) |
2643 (when (funcall predicate name) | 2685 (when (funcall predicate name) |
2644 (push (widget-convert-button type begin end :value name) | 2686 (push (widget-convert-button type begin end :value name) |
2645 buttons))))) | 2687 buttons))))) |
2646 (widget-put widget :buttons buttons)))) | 2688 (widget-put widget :buttons buttons))) |
2689 (let ((indent (widget-get widget :indent))) | |
2690 (when (and indent (not (zerop indent))) | |
2691 (save-excursion | |
2692 (save-restriction | |
2693 (narrow-to-region from to) | |
2694 (goto-char (point-min)) | |
2695 (while (search-forward "\n" nil t) | |
2696 (insert-char ?\ indent))))))) | |
2647 | 2697 |
2648 ;;; The `documentation-string' Widget. | 2698 ;;; The `documentation-string' Widget. |
2649 | 2699 |
2650 (define-widget 'documentation-string 'item | 2700 (define-widget 'documentation-string 'item |
2651 "A documentation string." | 2701 "A documentation string." |
2655 :value-create 'widget-documentation-string-value-create) | 2705 :value-create 'widget-documentation-string-value-create) |
2656 | 2706 |
2657 (defun widget-documentation-string-value-create (widget) | 2707 (defun widget-documentation-string-value-create (widget) |
2658 ;; Insert documentation string. | 2708 ;; Insert documentation string. |
2659 (let ((doc (widget-value widget)) | 2709 (let ((doc (widget-value widget)) |
2710 (indent (widget-get widget :indent)) | |
2660 (shown (widget-get (widget-get widget :parent) :documentation-shown)) | 2711 (shown (widget-get (widget-get widget :parent) :documentation-shown)) |
2661 (start (point))) | 2712 (start (point))) |
2662 (if (string-match "\n" doc) | 2713 (if (string-match "\n" doc) |
2663 (let ((before (substring doc 0 (match-beginning 0))) | 2714 (let ((before (substring doc 0 (match-beginning 0))) |
2664 (after (substring doc (match-beginning 0))) | 2715 (after (substring doc (match-beginning 0))) |
2665 buttons) | 2716 buttons) |
2666 (insert before " ") | 2717 (insert before " ") |
2667 (widget-documentation-link-add widget start (point)) | 2718 (widget-documentation-link-add widget start (point)) |
2668 (push (widget-create-child-and-convert | 2719 (push (widget-create-child-and-convert |
2669 widget 'visibility | 2720 widget 'visibility |
2670 :off nil | 2721 :help-echo "Show or hide rest of the documentation." |
2722 :off "More" | |
2671 :action 'widget-parent-action | 2723 :action 'widget-parent-action |
2672 shown) | 2724 shown) |
2673 buttons) | 2725 buttons) |
2674 (when shown | 2726 (when shown |
2675 (setq start (point)) | 2727 (setq start (point)) |
2728 (when (and indent (not (zerop indent))) | |
2729 (insert-char ?\ indent)) | |
2676 (insert after) | 2730 (insert after) |
2677 (widget-documentation-link-add widget start (point))) | 2731 (widget-documentation-link-add widget start (point))) |
2678 (widget-put widget :buttons buttons)) | 2732 (widget-put widget :buttons buttons)) |
2679 (insert doc) | 2733 (insert doc) |
2680 (widget-documentation-link-add widget start (point)))) | 2734 (widget-documentation-link-add widget start (point)))) |
3013 (widget-apply widget :value-to-internal value)))) | 3067 (widget-apply widget :value-to-internal value)))) |
3014 | 3068 |
3015 (define-widget 'choice 'menu-choice | 3069 (define-widget 'choice 'menu-choice |
3016 "A union of several sexp types." | 3070 "A union of several sexp types." |
3017 :tag "Choice" | 3071 :tag "Choice" |
3018 :format "%[%t%]: %v" | 3072 :format "%{%t%}: %[Value Menu%] %v" |
3073 :button-prefix 'widget-push-button-prefix | |
3074 :button-suffix 'widget-push-button-suffix | |
3019 :prompt-value 'widget-choice-prompt-value) | 3075 :prompt-value 'widget-choice-prompt-value) |
3020 | 3076 |
3021 (defun widget-choice-prompt-value (widget prompt value unbound) | 3077 (defun widget-choice-prompt-value (widget prompt value unbound) |
3022 "Make a choice." | 3078 "Make a choice." |
3023 (let ((args (widget-get widget :args)) | 3079 (let ((args (widget-get widget :args)) |
3078 | 3134 |
3079 (define-widget 'boolean 'toggle | 3135 (define-widget 'boolean 'toggle |
3080 "To be nil or non-nil, that is the question." | 3136 "To be nil or non-nil, that is the question." |
3081 :tag "Boolean" | 3137 :tag "Boolean" |
3082 :prompt-value 'widget-boolean-prompt-value | 3138 :prompt-value 'widget-boolean-prompt-value |
3083 :format "%[%t%]: %v\n") | 3139 :button-prefix 'widget-push-button-prefix |
3140 :button-suffix 'widget-push-button-suffix | |
3141 :format "%{%t%}: %[Toggle%] %v\n" | |
3142 :on "on (non-nil)" | |
3143 :off "off (nil)") | |
3084 | 3144 |
3085 (defun widget-boolean-prompt-value (widget prompt value unbound) | 3145 (defun widget-boolean-prompt-value (widget prompt value unbound) |
3086 ;; Toggle a boolean. | 3146 ;; Toggle a boolean. |
3087 (y-or-n-p prompt)) | 3147 (y-or-n-p prompt)) |
3088 | 3148 |