comparison lisp/custom/wid-edit.el @ 165:5a88923fcbfe r20-3b9

Import from CVS: tag r20-3b9
author cvs
date Mon, 13 Aug 2007 09:44:42 +0200
parents 0132846995bd
children 85ec50267440
comparison
equal deleted inserted replaced
164:4e0740e5aab2 165:5a88923fcbfe
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.9931 7 ;; Version: 1.9937
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
132 (defgroup widget-faces nil 132 (defgroup widget-faces nil
133 "Faces used by the widget library." 133 "Faces used by the widget library."
134 :group 'widgets 134 :group 'widgets
135 :group 'faces) 135 :group 'faces)
136 136
137 (defvar widget-documentation-face 'widget-documentation-face
138 "Face used for documentation strings in widges.
139 This exists as a variable so it can be set locally in certain buffers.")
140
137 (defface widget-documentation-face '((((class color) 141 (defface widget-documentation-face '((((class color)
138 (background dark)) 142 (background dark))
139 (:foreground "lime green")) 143 (:foreground "lime green"))
140 (((class color) 144 (((class color)
141 (background light)) 145 (background light))
199 (defcustom widget-menu-max-size 40 203 (defcustom widget-menu-max-size 40
200 "Largest number of items allowed in a popup-menu. 204 "Largest number of items allowed in a popup-menu.
201 Larger menus are read through the minibuffer." 205 Larger menus are read through the minibuffer."
202 :group 'widgets 206 :group 'widgets
203 :type 'integer) 207 :type 'integer)
208
209 (defcustom widget-menu-minibuffer-flag nil
210 "*Control how to ask for a choice from the keyboard.
211 Non-nil means use the minibuffer;
212 nil means read a single character."
213 :group 'widgets
214 :type 'boolean)
204 215
205 (defun widget-choose (title items &optional event) 216 (defun widget-choose (title items &optional event)
206 "Choose an item from a list. 217 "Choose an item from a list.
207 218
208 First argument TITLE is the name of the list. 219 First argument TITLE is the name of the list.
236 (setq val (and val 247 (setq val (and val
237 (listp (event-object val)) 248 (listp (event-object val))
238 (stringp (car-safe (event-object val))) 249 (stringp (car-safe (event-object val)))
239 (car (event-object val)))) 250 (car (event-object val))))
240 (cdr (assoc val items)))) 251 (cdr (assoc val items))))
241 (t 252 (widget-menu-minibuffer-flag
253 ;; Read the choice of name from the minibuffer.
242 (setq items (widget-remove-if 'stringp items)) 254 (setq items (widget-remove-if 'stringp items))
243 (let ((val (completing-read (concat title ": ") items nil t))) 255 (let ((val (completing-read (concat title ": ") items nil t)))
244 (if (stringp val) 256 (if (stringp val)
245 (let ((try (try-completion val items))) 257 (let ((try (try-completion val items)))
246 (when (stringp try) 258 (when (stringp try)
247 (setq val try)) 259 (setq val try))
248 (cdr (assoc val items))) 260 (cdr (assoc val items)))
249 nil))))) 261 nil)))
262 (t
263 ;; Construct a menu of the choices
264 ;; and then use it for prompting for a single character.
265 (let* ((overriding-terminal-local-map
266 (make-sparse-keymap))
267 map choice (next-digit ?0)
268 value)
269 ;; Define SPC as a prefix char to get to this menu.
270 (define-key overriding-terminal-local-map " "
271 (setq map (make-sparse-keymap title)))
272 (while items
273 (setq choice (car items) items (cdr items))
274 (if (consp choice)
275 (let* ((name (car choice))
276 (function (cdr choice))
277 (character (aref name 0)))
278 ;; Pick a character for this choice;
279 ;; avoid duplication.
280 (when (lookup-key map (vector character))
281 (setq character (downcase character))
282 (when (lookup-key map (vector character))
283 (setq character next-digit
284 next-digit (1+ next-digit))))
285 (define-key map (vector character)
286 (cons (format "%c = %s" character name) function)))))
287 (define-key map [?\C-g] '("Quit" . keyboard-quit))
288 (define-key map [t] 'keyboard-quit)
289 (setcdr map (nreverse (cdr map)))
290 ;; Unread a SPC to lead to our new menu.
291 (setq unread-command-events (cons ?\ unread-command-events))
292 ;; Read a char with the menu, and return the result
293 ;; that corresponds to it.
294 (setq value
295 (lookup-key overriding-terminal-local-map
296 (read-key-sequence title) t))
297 (when (eq value 'keyboard-quit)
298 (error "Canceled"))
299 value))))
250 300
251 (defun widget-remove-if (predictate list) 301 (defun widget-remove-if (predictate list)
252 (let (result (tail list)) 302 (let (result (tail list))
253 (while tail 303 (while tail
254 (or (funcall predictate (car tail)) 304 (or (funcall predictate (car tail))
280 "Non-nil means add extra space at the end of editable text fields. 330 "Non-nil means add extra space at the end of editable text fields.
281 331
282 This is needed on all versions of Emacs, and on XEmacs before 20.3. 332 This is needed on all versions of Emacs, and on XEmacs before 20.3.
283 If you don't add the space, it will become impossible to edit a zero 333 If you don't add the space, it will become impossible to edit a zero
284 size field." 334 size field."
335 :type 'boolean
336 :group 'widgets)
337
338 (defcustom widget-field-use-before-change
339 (or (> emacs-minor-version 34)
340 (> emacs-major-version 20)
341 (string-match "XEmacs" emacs-version))
342 "Non-nil means use `before-change-functions' to track editable fields.
343 This enables the use of undo, but doesn'f work on Emacs 19.34 and earlier.
344 Using before hooks also means that the :notify function can't know the
345 new value."
285 :type 'boolean 346 :type 'boolean
286 :group 'widgets) 347 :group 'widgets)
287 348
288 (defun widget-specify-field (widget from to) 349 (defun widget-specify-field (widget from to)
289 "Specify editable button for WIDGET between FROM and TO." 350 "Specify editable button for WIDGET between FROM and TO."
352 'end-open t 413 'end-open t
353 'face face))))) 414 'face face)))))
354 (defun widget-specify-doc (widget from to) 415 (defun widget-specify-doc (widget from to)
355 ;; Specify documentation for WIDGET between FROM and TO. 416 ;; Specify documentation for WIDGET between FROM and TO.
356 (add-text-properties from to (list 'widget-doc widget 417 (add-text-properties from to (list 'widget-doc widget
357 'face 'widget-documentation-face))) 418 'face widget-documentation-face)))
358 419
359 (defmacro widget-specify-insert (&rest form) 420 (defmacro widget-specify-insert (&rest form)
360 ;; Execute FORM without inheriting any text properties. 421 ;; Execute FORM without inheriting any text properties.
361 (` 422 (`
362 (save-restriction 423 (save-restriction
929 (when (and pos 990 (when (and pos
930 (eq (get-char-property pos 'button) button)) 991 (eq (get-char-property pos 'button) button))
931 (widget-apply-action button event))) 992 (widget-apply-action button event)))
932 (overlay-put overlay 'face face) 993 (overlay-put overlay 'face face)
933 (overlay-put overlay 'mouse-face mouse-face))) 994 (overlay-put overlay 'mouse-face mouse-face)))
934 (let (command up) 995 (let ((up t)
996 command)
935 ;; Find the global command to run, and check whether it 997 ;; Find the global command to run, and check whether it
936 ;; is bound to an up event. 998 ;; is bound to an up event.
937 (cond ((setq command ;down event 999 (cond ((setq command ;down event
938 (lookup-key widget-global-map [ button2 ]))) 1000 (lookup-key widget-global-map [ button2 ]))
1001 (setq up nil))
939 ((setq command ;down event 1002 ((setq command ;down event
940 (lookup-key widget-global-map [ down-mouse-2 ]))) 1003 (lookup-key widget-global-map [ down-mouse-2 ]))
1004 (setq up nil))
941 ((setq command ;up event 1005 ((setq command ;up event
942 (lookup-key widget-global-map [ button2up ])) 1006 (lookup-key widget-global-map [ button2up ])))
943 (setq up t))
944 ((setq command ;up event 1007 ((setq command ;up event
945 (lookup-key widget-global-map [ mouse-2])) 1008 (lookup-key widget-global-map [ mouse-2]))))
946 (setq up t))) 1009 (when up
1010 ;; Don't execute up events twice.
1011 (while (not (button-release-event-p event))
1012 (setq event (widget-read-event))))
947 (when command 1013 (when command
948 ;; Don't execute up events twice.
949 (when up
950 (while (not (button-release-event-p event))
951 (setq event (widget-read-event))))
952 (call-interactively command)))))) 1014 (call-interactively command))))))
953 (t 1015 (t
954 (message "You clicked somewhere weird.")))) 1016 (message "You clicked somewhere weird."))))
955 1017
956 (defun widget-button1-click (event) 1018 (defun widget-button1-click (event)
1138 (set-marker from nil) 1200 (set-marker from nil)
1139 (set-marker to nil)))) 1201 (set-marker to nil))))
1140 (widget-clear-undo) 1202 (widget-clear-undo)
1141 ;; We need to maintain text properties and size of the editing fields. 1203 ;; We need to maintain text properties and size of the editing fields.
1142 (make-local-variable 'after-change-functions) 1204 (make-local-variable 'after-change-functions)
1143 (make-local-variable 'before-change-functions)
1144 (setq after-change-functions 1205 (setq after-change-functions
1145 (if widget-field-list '(widget-after-change) nil)) 1206 (if widget-field-list '(widget-after-change) nil))
1146 (setq before-change-functions 1207 (when widget-field-use-before-change
1147 (if widget-field-list '(widget-before-change) nil))) 1208 (make-local-variable 'before-change-functions)
1209 (setq before-change-functions
1210 (if widget-field-list '(widget-before-change) nil))))
1148 1211
1149 (defvar widget-field-last nil) 1212 (defvar widget-field-last nil)
1150 ;; Last field containing point. 1213 ;; Last field containing point.
1151 (make-variable-buffer-local 'widget-field-last) 1214 (make-variable-buffer-local 'widget-field-last)
1152 1215
1435 buttons)))) 1498 buttons))))
1436 (t 1499 (t
1437 (error "Unknown escape `%c'" escape))) 1500 (error "Unknown escape `%c'" escape)))
1438 (widget-put widget :buttons buttons))) 1501 (widget-put widget :buttons buttons)))
1439 1502
1503 (defvar widget-button-face nil
1504 "Face to use for buttons.
1505 This is a variable so that it can be buffer-local.")
1506
1440 (defun widget-default-button-face-get (widget) 1507 (defun widget-default-button-face-get (widget)
1441 ;; Use :button-face or widget-button-face 1508 ;; Use :button-face or widget-button-face
1442 (or (widget-get widget :button-face) 'widget-button-face)) 1509 (or (widget-get widget :button-face)
1510 (let ((parent (widget-get widget :parent)))
1511 (if parent
1512 (widget-apply parent :button-face-get)
1513 'widget-button-face))))
1443 1514
1444 (defun widget-default-sample-face-get (widget) 1515 (defun widget-default-sample-face-get (widget)
1445 ;; Use :sample-face. 1516 ;; Use :sample-face.
1446 (widget-get widget :sample-face)) 1517 (widget-get widget :sample-face))
1447 1518
1466 (set-marker to nil)) 1537 (set-marker to nil))
1467 (widget-clear-undo)) 1538 (widget-clear-undo))
1468 1539
1469 (defun widget-default-value-set (widget value) 1540 (defun widget-default-value-set (widget value)
1470 ;; Recreate widget with new value. 1541 ;; Recreate widget with new value.
1471 (save-excursion 1542 (let* ((old-pos (point))
1472 (goto-char (widget-get widget :from)) 1543 (from (copy-marker (widget-get widget :from)))
1473 (widget-apply widget :delete) 1544 (to (copy-marker (widget-get widget :to)))
1474 (widget-put widget :value value) 1545 (offset (if (and (<= from old-pos) (<= old-pos to))
1475 (widget-apply widget :create))) 1546 (if (>= old-pos (1- to))
1547 (- old-pos to 1)
1548 (- old-pos from)))))
1549 ;;??? Bug: this ought to insert the new value before deleting the old one,
1550 ;; so that markers on either side of the value automatically
1551 ;; stay on the same side. -- rms.
1552 (save-excursion
1553 (goto-char (widget-get widget :from))
1554 (widget-apply widget :delete)
1555 (widget-put widget :value value)
1556 (widget-apply widget :create))
1557 (if offset
1558 (if (< offset 0)
1559 (goto-char (+ (widget-get widget :to) offset 1))
1560 (goto-char (min (+ from offset) (1- (widget-get widget :to))))))))
1476 1561
1477 (defun widget-default-value-inline (widget) 1562 (defun widget-default-value-inline (widget)
1478 ;; Wrap value in a list unless it is inline. 1563 ;; Wrap value in a list unless it is inline.
1479 (if (widget-get widget :inline) 1564 (if (widget-get widget :inline)
1480 (widget-value widget) 1565 (widget-value widget)
1705 (history (widget-get widget :prompt-history))) 1790 (history (widget-get widget :prompt-history)))
1706 (let ((answer (widget-apply widget 1791 (let ((answer (widget-apply widget
1707 :prompt-internal prompt initial history))) 1792 :prompt-internal prompt initial history)))
1708 (widget-apply widget :value-to-external answer)))) 1793 (widget-apply widget :value-to-external answer))))
1709 1794
1795 (defvar widget-edit-functions nil)
1796
1710 (defun widget-field-action (widget &optional event) 1797 (defun widget-field-action (widget &optional event)
1711 ;; Edit the value in the minibuffer. 1798 ;; Move to next field.
1712 (let ((invalid (widget-apply widget :validate))) 1799 (widget-forward 1)
1713 (let ((prompt (concat (widget-apply widget :menu-tag-get) ": ")) 1800 (run-hook-with-args 'widget-edit-functions widget))
1714 (value (unless invalid
1715 (widget-value widget))))
1716 (let ((answer (widget-apply widget :prompt-value prompt value invalid) ))
1717 (widget-value-set widget answer)))
1718 (widget-setup)
1719 (widget-apply widget :notify widget event)))
1720 1801
1721 (defun widget-field-validate (widget) 1802 (defun widget-field-validate (widget)
1722 ;; Valid if the content matches `:valid-regexp'. 1803 ;; Valid if the content matches `:valid-regexp'.
1723 (save-excursion 1804 (save-excursion
1724 (let ((value (widget-apply widget :value-get)) 1805 (let ((value (widget-apply widget :value-get))
1909 (when current 1990 (when current
1910 (widget-value-set widget 1991 (widget-value-set widget
1911 (widget-apply current :value-to-external 1992 (widget-apply current :value-to-external
1912 (widget-get current :value))) 1993 (widget-get current :value)))
1913 (widget-setup) 1994 (widget-setup)
1914 (widget-apply widget :notify widget event)))) 1995 (widget-apply widget :notify widget event)))
1996 (run-hooks 'widget-edit-hook))
1915 1997
1916 (defun widget-choice-validate (widget) 1998 (defun widget-choice-validate (widget)
1917 ;; Valid if we have made a valid choice. 1999 ;; Valid if we have made a valid choice.
1918 (let ((void (widget-get widget :void)) 2000 (let ((void (widget-get widget :void))
1919 (choice (widget-get widget :choice)) 2001 (choice (widget-get widget :choice))
1964 (widget-get widget :off-glyph)))) 2046 (widget-get widget :off-glyph))))
1965 2047
1966 (defun widget-toggle-action (widget &optional event) 2048 (defun widget-toggle-action (widget &optional event)
1967 ;; Toggle value. 2049 ;; Toggle value.
1968 (widget-value-set widget (not (widget-value widget))) 2050 (widget-value-set widget (not (widget-value widget)))
1969 (widget-apply widget :notify widget event)) 2051 (widget-apply widget :notify widget event)
2052 (run-hooks 'widget-edit-hook))
1970 2053
1971 ;;; The `checkbox' Widget. 2054 ;;; The `checkbox' Widget.
1972 2055
1973 (define-widget 'checkbox 'toggle 2056 (define-widget 'checkbox 'toggle
1974 "A checkbox toggle." 2057 "A checkbox toggle."
2639 (defun widget-documentation-link-echo-help (widget) 2722 (defun widget-documentation-link-echo-help (widget)
2640 "Tell what this link will describe." 2723 "Tell what this link will describe."
2641 (concat "Describe the `" (widget-get widget :value) "' symbol.")) 2724 (concat "Describe the `" (widget-get widget :value) "' symbol."))
2642 2725
2643 (defun widget-documentation-link-action (widget &optional event) 2726 (defun widget-documentation-link-action (widget &optional event)
2644 "Run apropos on WIDGET's value. Ignore optional argument EVENT." 2727 "Display documentation for WIDGET's value. Ignore optional argument EVENT."
2645 (apropos (concat "\\`" (regexp-quote (widget-get widget :value)) "\\'"))) 2728 (let* ((string (widget-get widget :value))
2729 (symbol (intern string)))
2730 (if (and (fboundp symbol) (boundp symbol))
2731 ;; If there are two doc strings, give the user a way to pick one.
2732 (apropos (concat "\\`" (regexp-quote string) "\\'"))
2733 (if (fboundp symbol)
2734 (describe-function symbol)
2735 (describe-variable symbol)))))
2646 2736
2647 (defcustom widget-documentation-links t 2737 (defcustom widget-documentation-links t
2648 "Add hyperlinks to documentation strings when non-nil." 2738 "Add hyperlinks to documentation strings when non-nil."
2649 :type 'boolean 2739 :type 'boolean
2650 :group 'widget-documentation) 2740 :group 'widget-documentation)
2800 widget)))) 2890 widget))))
2801 2891
2802 (define-widget 'file 'string 2892 (define-widget 'file 'string
2803 "A file widget. 2893 "A file widget.
2804 It will read a file name from the minibuffer when invoked." 2894 It will read a file name from the minibuffer when invoked."
2895 :complete-function 'widget-file-complete
2805 :prompt-value 'widget-file-prompt-value 2896 :prompt-value 'widget-file-prompt-value
2806 :format "%{%t%}: %v" 2897 :format "%{%t%}: %v"
2807 :tag "File" 2898 :tag "File")
2808 :action 'widget-file-action) 2899
2900 (defun widget-file-complete ()
2901 "Perform completion on file name preceding point."
2902 (interactive)
2903 (let* ((end (point))
2904 (beg (save-excursion
2905 (skip-chars-backward "^ ")
2906 (point)))
2907 (pattern (buffer-substring beg end))
2908 (name-part (file-name-nondirectory pattern))
2909 (directory (file-name-directory pattern))
2910 (completion (file-name-completion name-part directory)))
2911 (cond ((eq completion t))
2912 ((null completion)
2913 (message "Can't find completion for \"%s\"" pattern)
2914 (ding))
2915 ((not (string= name-part completion))
2916 (delete-region beg end)
2917 (insert (expand-file-name completion directory)))
2918 (t
2919 (message "Making completion list...")
2920 (let ((list (file-name-all-completions name-part directory)))
2921 (setq list (sort list 'string<))
2922 (with-output-to-temp-buffer "*Completions*"
2923 (display-completion-list list)))
2924 (message "Making completion list...%s" "done")))))
2809 2925
2810 (defun widget-file-prompt-value (widget prompt value unbound) 2926 (defun widget-file-prompt-value (widget prompt value unbound)
2811 ;; Read file from minibuffer. 2927 ;; Read file from minibuffer.
2812 (abbreviate-file-name 2928 (abbreviate-file-name
2813 (if unbound 2929 (if unbound
2816 (dir (file-name-directory value)) 2932 (dir (file-name-directory value))
2817 (file (file-name-nondirectory value)) 2933 (file (file-name-nondirectory value))
2818 (must-match (widget-get widget :must-match))) 2934 (must-match (widget-get widget :must-match)))
2819 (read-file-name prompt2 dir nil must-match file))))) 2935 (read-file-name prompt2 dir nil must-match file)))))
2820 2936
2821 (defun widget-file-action (widget &optional event) 2937 ;;;(defun widget-file-action (widget &optional event)
2822 ;; Read a file name from the minibuffer. 2938 ;;; ;; Read a file name from the minibuffer.
2823 (let* ((value (widget-value widget)) 2939 ;;; (let* ((value (widget-value widget))
2824 (dir (file-name-directory value)) 2940 ;;; (dir (file-name-directory value))
2825 (file (file-name-nondirectory value)) 2941 ;;; (file (file-name-nondirectory value))
2826 (menu-tag (widget-apply widget :menu-tag-get)) 2942 ;;; (menu-tag (widget-apply widget :menu-tag-get))
2827 (must-match (widget-get widget :must-match)) 2943 ;;; (must-match (widget-get widget :must-match))
2828 (answer (read-file-name (concat menu-tag ": (default `" value "') ") 2944 ;;; (answer (read-file-name (concat menu-tag ": (default `" value "') ")
2829 dir nil must-match file))) 2945 ;;; dir nil must-match file)))
2830 (widget-value-set widget (abbreviate-file-name answer)) 2946 ;;; (widget-value-set widget (abbreviate-file-name answer))
2831 (widget-setup) 2947 ;;; (widget-setup)
2832 (widget-apply widget :notify widget event))) 2948 ;;; (widget-apply widget :notify widget event)))
2833 2949
2834 (define-widget 'directory 'file 2950 (define-widget 'directory 'file
2835 "A directory widget. 2951 "A directory widget.
2836 It will read a directory name from the minibuffer when invoked." 2952 It will read a directory name from the minibuffer when invoked."
2837 :tag "Directory") 2953 :tag "Directory")
2843 "A lisp symbol." 2959 "A lisp symbol."
2844 :value nil 2960 :value nil
2845 :tag "Symbol" 2961 :tag "Symbol"
2846 :format "%{%t%}: %v" 2962 :format "%{%t%}: %v"
2847 :match (lambda (widget value) (symbolp value)) 2963 :match (lambda (widget value) (symbolp value))
2964 :complete-function 'lisp-complete-symbol
2848 :prompt-internal 'widget-symbol-prompt-internal 2965 :prompt-internal 'widget-symbol-prompt-internal
2849 :prompt-match 'symbolp 2966 :prompt-match 'symbolp
2850 :prompt-history 'widget-symbol-prompt-value-history 2967 :prompt-history 'widget-symbol-prompt-value-history
2851 :value-to-internal (lambda (widget value) 2968 :value-to-internal (lambda (widget value)
2852 (if (symbolp value) 2969 (if (symbolp value)
2988 (unless (eobp) 3105 (unless (eobp)
2989 (error "Junk at end of expression: %s" 3106 (error "Junk at end of expression: %s"
2990 (buffer-substring (point) (point-max)))) 3107 (buffer-substring (point) (point-max))))
2991 answer))))) 3108 answer)))))
2992 3109
2993 (define-widget 'integer 'sexp 3110 (define-widget 'restricted-sexp 'sexp
3111 "A Lisp expression restricted to values that match.
3112 To use this type, you must define :match or :match-alternatives."
3113 :type-error "The specified value is not valid"
3114 :match 'widget-restricted-sexp-match
3115 :value-to-internal (lambda (widget value)
3116 (if (widget-apply widget :match value)
3117 (prin1-to-string value)
3118 value)))
3119
3120 (defun widget-restricted-sexp-match (widget value)
3121 (let ((alternatives (widget-get widget :match-alternatives))
3122 matched)
3123 (while (and alternatives (not matched))
3124 (if (cond ((functionp (car alternatives))
3125 (funcall (car alternatives) value))
3126 ((and (consp (car alternatives))
3127 (eq (car (car alternatives)) 'quote))
3128 (eq value (nth 1 (car alternatives)))))
3129 (setq matched t))
3130 (setq alternatives (cdr alternatives)))
3131 matched))
3132
3133 (define-widget 'integer 'restricted-sexp
2994 "An integer." 3134 "An integer."
2995 :tag "Integer" 3135 :tag "Integer"
2996 :value 0 3136 :value 0
2997 :type-error "This field should contain an integer" 3137 :type-error "This field should contain an integer"
2998 :value-to-internal (lambda (widget value) 3138 :match-alternatives '(integerp))
2999 (if (integerp value) 3139
3000 (prin1-to-string value) 3140 (define-widget 'number 'restricted-sexp
3001 value)) 3141 "A floating point number."
3002 :match (lambda (widget value) (integerp value))) 3142 :tag "Number"
3143 :value 0.0
3144 :type-error "This field should contain a number"
3145 :match-alternatives '(numberp))
3003 3146
3004 (define-widget 'character 'editable-field 3147 (define-widget 'character 'editable-field
3005 "An character." 3148 "A character."
3006 :tag "Character" 3149 :tag "Character"
3007 :value 0 3150 :value 0
3008 :size 1 3151 :size 1
3009 :format "%{%t%}: %v\n" 3152 :format "%{%t%}: %v\n"
3010 :valid-regexp "\\`.\\'" 3153 :valid-regexp "\\`.\\'"
3019 value)) 3162 value))
3020 :match (lambda (widget value) 3163 :match (lambda (widget value)
3021 (if (fboundp 'characterp) 3164 (if (fboundp 'characterp)
3022 (characterp value) 3165 (characterp value)
3023 (integerp value)))) 3166 (integerp value))))
3024
3025 (define-widget 'number 'sexp
3026 "A floating point number."
3027 :tag "Number"
3028 :value 0.0
3029 :type-error "This field should contain a number"
3030 :value-to-internal (lambda (widget value)
3031 (if (numberp value)
3032 (prin1-to-string value)
3033 value))
3034 :match (lambda (widget value) (numberp value)))
3035 3167
3036 (define-widget 'list 'group 3168 (define-widget 'list 'group
3037 "A lisp list." 3169 "A lisp list."
3038 :tag "List" 3170 :tag "List"
3039 :format "%{%t%}:\n%v") 3171 :format "%{%t%}:\n%v")