comparison lisp/wid-edit.el @ 1173:315720febed1

[xemacs-hg @ 2002-12-26 15:52:41 by stephent] synch GNUisances <87el84sru1.fsf@tleepslib.sk.tsukuba.ac.jp>
author stephent
date Thu, 26 Dec 2002 15:52:43 +0000
parents 79940b592197
children 00abb1091204
comparison
equal deleted inserted replaced
1172:1ea662584c01 1173:315720febed1
56 "Faces used by the widget library." 56 "Faces used by the widget library."
57 :group 'widgets 57 :group 'widgets
58 :group 'faces) 58 :group 'faces)
59 59
60 (defvar widget-documentation-face 'widget-documentation-face 60 (defvar widget-documentation-face 'widget-documentation-face
61 "Face used for documentation strings in widges. 61 "Face used for documentation strings in widgets.
62 This exists as a variable so it can be set locally in certain buffers.") 62 This exists as a variable so it can be set locally in certain buffers.")
63 63
64 (defface widget-documentation-face '((((class color) 64 (defface widget-documentation-face '((((class color)
65 (background dark)) 65 (background dark))
66 (:foreground "lime green")) 66 (:foreground "lime green"))
71 "Face used for documentation text." 71 "Face used for documentation text."
72 :group 'widget-documentation 72 :group 'widget-documentation
73 :group 'widget-faces) 73 :group 'widget-faces)
74 74
75 (defvar widget-button-face 'widget-button-face 75 (defvar widget-button-face 'widget-button-face
76 "Face used for buttons in widges. 76 "Face used for buttons in widgets.
77 This exists as a variable so it can be set locally in certain buffers.") 77 This exists as a variable so it can be set locally in certain buffers.")
78 78
79 (defface widget-button-face '((t (:bold t))) 79 (defface widget-button-face '((t (:bold t)))
80 "Face used for widget buttons." 80 "Face used for widget buttons."
81 :group 'widget-faces) 81 :group 'widget-faces)
185 185
186 (defun widget-choose (title items &optional event) 186 (defun widget-choose (title items &optional event)
187 "Choose an item from a list. 187 "Choose an item from a list.
188 188
189 First argument TITLE is the name of the list. 189 First argument TITLE is the name of the list.
190 Second argument ITEMS is an list whose members are either 190 Second argument ITEMS is a list whose members are either
191 (NAME . VALUE), to indicate selectable items, or just strings to 191 (NAME . VALUE), to indicate selectable items, or just strings to
192 indicate unselectable items. 192 indicate unselectable items.
193 Optional third argument EVENT is an input event. 193 Optional third argument EVENT is an input event.
194 194
195 The user is asked to choose between each NAME from the items alist, 195 The user is asked to choose between each NAME from the items alist,
323 "Specify editable button for WIDGET between FROM and TO." 323 "Specify editable button for WIDGET between FROM and TO."
324 (save-excursion 324 (save-excursion
325 (goto-char to) 325 (goto-char to)
326 (cond ((null (widget-get widget :size)) 326 (cond ((null (widget-get widget :size))
327 (forward-char 1)) 327 (forward-char 1))
328 ;; #### This comment goes outside of the save-excursion in GNU
328 ;; Terminating space is not part of the field, but necessary in 329 ;; Terminating space is not part of the field, but necessary in
329 ;; order for local-map to work. Remove next sexp if local-map works 330 ;; order for local-map to work. Remove next sexp if local-map works
330 ;; at the end of the extent. 331 ;; at the end of the extent.
331 (widget-field-add-space 332 (widget-field-add-space
332 (insert-and-inherit " "))) 333 (insert-and-inherit " ")))
357 (let ((secret (widget-get field :secret)) 358 (let ((secret (widget-get field :secret))
358 (size (widget-get field :size))) 359 (size (widget-get field :size)))
359 (when secret 360 (when secret
360 (let ((begin (widget-field-start field)) 361 (let ((begin (widget-field-start field))
361 (end (widget-field-end field))) 362 (end (widget-field-end field)))
362 (when size 363 (when size
363 (while (and (> end begin) 364 (while (and (> end begin)
364 (eq (char-after (1- end)) ?\ )) 365 (eq (char-after (1- end)) ?\ ))
365 (setq end (1- end)))) 366 (setq end (1- end))))
366 (while (< begin end) 367 (while (< begin end)
367 (let ((old (char-after begin))) 368 (let ((old (char-after begin)))
414 (set-extent-property extent 'widget-doc widget) 415 (set-extent-property extent 'widget-doc widget)
415 (set-extent-property extent 'face widget-documentation-face) 416 (set-extent-property extent 'face widget-documentation-face)
416 (widget-put widget :doc-extent extent))) 417 (widget-put widget :doc-extent extent)))
417 418
418 (defmacro widget-specify-insert (&rest form) 419 (defmacro widget-specify-insert (&rest form)
419 ;; Execute FORM without inheriting any text properties. 420 "Execute FORM without inheriting any text properties."
420 `(save-restriction 421 `(save-restriction
421 (let ((inhibit-read-only t) 422 (let ((inhibit-read-only t)
422 before-change-functions 423 before-change-functions
423 after-change-functions) 424 after-change-functions)
424 (insert "<>") 425 (insert "<>")
425 (narrow-to-region (- (point) 2) (point)) 426 (narrow-to-region (- (point) 2) (point))
426 (goto-char (1+ (point-min))) 427 (goto-char (1+ (point-min)))
427 ;; We use `prog1' instead of a `result' variable, as the latter 428 ;; XEmacs: use `prog1' instead of a `result' variable. The latter
428 ;; confuses the byte-compiler in some cases (a warning). 429 ;; confuses the byte-compiler in some cases (a warning).
429 (prog1 (progn ,@form) 430 (prog1 (progn ,@form)
430 (delete-region (point-min) (1+ (point-min))) 431 (delete-region (point-min) (1+ (point-min)))
431 (delete-region (1- (point-max)) (point-max)) 432 (delete-region (1- (point-max)) (point-max))
432 (goto-char (point-max)))))) 433 (goto-char (point-max))))))
584 (if (symbolp value) 585 (if (symbolp value)
585 (symbol-value value) 586 (symbol-value value)
586 value))) 587 value)))
587 588
588 (defun widget-member (widget property) 589 (defun widget-member (widget property)
589 "Return t if there is a definition in WIDGET for PROPERTY." 590 "Non-nil iff there is a definition in WIDGET for PROPERTY."
590 (cond ((widget-plist-member (cdr widget) property) 591 (cond ((widget-plist-member (cdr widget) property)
591 t) 592 t)
592 ((car widget) 593 ((car widget)
593 (widget-member (get (car widget) 'widget-type) property)) 594 (widget-member (get (car widget) 'widget-type) property))
594 (t nil))) 595 (t nil)))
946 :value (widget-apply widget :value-to-internal value)))) 947 :value (widget-apply widget :value-to-internal value))))
947 ;; Return the newly created widget. 948 ;; Return the newly created widget.
948 widget)) 949 widget))
949 950
950 (defun widget-insert (&rest args) 951 (defun widget-insert (&rest args)
951 "Call `insert' with ARGS and make the text read only." 952 "Call `insert' with ARGS even if surrounding text is read only."
952 (let ((inhibit-read-only t) 953 (let ((inhibit-read-only t)
953 before-change-functions 954 before-change-functions
954 after-change-functions) 955 after-change-functions)
955 (apply 'insert args))) 956 (apply 'insert args)))
956 957
1009 1010
1010 1011
1011 ;;; Keymap and Commands. 1012 ;;; Keymap and Commands.
1012 1013
1013 (defvar widget-keymap nil 1014 (defvar widget-keymap nil
1014 "Keymap containing useful binding for buffers containing widgets. 1015 "Keymap containing useful bindings for buffers containing widgets.
1015 Recommended as a parent keymap for modes using widgets.") 1016 Recommended as a parent keymap for modes using widgets.")
1016 1017
1017 (unless widget-keymap 1018 (unless widget-keymap
1018 (setq widget-keymap (make-sparse-keymap)) 1019 (setq widget-keymap (make-sparse-keymap))
1019 (define-key widget-keymap [tab] 'widget-forward) 1020 (define-key widget-keymap [tab] 'widget-forward)
1020 (define-key widget-keymap [(shift tab)] 'widget-backward) 1021 (define-key widget-keymap [(shift tab)] 'widget-backward)
1021 (define-key widget-keymap [(meta tab)] 'widget-backward) 1022 (define-key widget-keymap [(meta tab)] 'widget-backward)
1022 (define-key widget-keymap [backtab] 'widget-backward)) 1023 (define-key widget-keymap [backtab] 'widget-backward))
1023 1024
1024 (defvar widget-global-map global-map 1025 (defvar widget-global-map global-map
1025 "Keymap used for events the widget does not handle themselves.") 1026 "Keymap used for events a widget does not handle itself.")
1026 (make-variable-buffer-local 'widget-global-map) 1027 (make-variable-buffer-local 'widget-global-map)
1027 1028
1028 (defvar widget-field-keymap nil 1029 (defvar widget-field-keymap nil
1029 "Keymap used inside an editable field.") 1030 "Keymap used inside an editable field.")
1030 1031
1086 "Character position of the mouse event, or nil." 1087 "Character position of the mouse event, or nil."
1087 (and (mouse-event-p event) 1088 (and (mouse-event-p event)
1088 (event-point event))) 1089 (event-point event)))
1089 1090
1090 (defun widget-button-click (event) 1091 (defun widget-button-click (event)
1091 "Invoke button below mouse pointer." 1092 "Invoke button under mouse pointer."
1092 (interactive "e") 1093 (interactive "e")
1093 (with-current-buffer (event-buffer event) 1094 (with-current-buffer (event-buffer event)
1094 (cond ((event-glyph event) 1095 (cond ((event-glyph event)
1095 (widget-glyph-click event)) 1096 (widget-glyph-click event))
1096 ((widget-event-point event) 1097 ((widget-event-point event)
1795 (defun widget-default-sample-face-get (widget) 1796 (defun widget-default-sample-face-get (widget)
1796 ;; Use :sample-face. 1797 ;; Use :sample-face.
1797 (widget-get widget :sample-face)) 1798 (widget-get widget :sample-face))
1798 1799
1799 (defun widget-default-delete (widget) 1800 (defun widget-default-delete (widget)
1800 ;; Remove widget from the buffer. 1801 "Remove widget from the buffer."
1801 (let ((from (widget-get widget :from)) 1802 (let ((from (widget-get widget :from))
1802 (to (widget-get widget :to)) 1803 (to (widget-get widget :to))
1803 (inactive-extent (widget-get widget :inactive)) 1804 (inactive-extent (widget-get widget :inactive))
1804 (button-extent (widget-get widget :button-extent)) 1805 (button-extent (widget-get widget :button-extent))
1805 (sample-extent (widget-get widget :sample-extent)) 1806 (sample-extent (widget-get widget :sample-extent))
1822 (set-marker from nil) 1823 (set-marker from nil)
1823 (set-marker to nil)) 1824 (set-marker to nil))
1824 (widget-clear-undo)) 1825 (widget-clear-undo))
1825 1826
1826 (defun widget-default-value-set (widget value) 1827 (defun widget-default-value-set (widget value)
1827 ;; Recreate widget with new value. 1828 "Recreate widget with new value."
1828 (let* ((old-pos (point)) 1829 (let* ((old-pos (point))
1829 (from (copy-marker (widget-get widget :from))) 1830 (from (copy-marker (widget-get widget :from)))
1830 (to (copy-marker (widget-get widget :to))) 1831 (to (copy-marker (widget-get widget :to)))
1831 (offset (if (and (<= from old-pos) (<= old-pos to)) 1832 (offset (if (and (<= from old-pos) (<= old-pos to))
1832 (if (>= old-pos (1- to)) 1833 (if (>= old-pos (1- to))
1844 (if (< offset 0) 1845 (if (< offset 0)
1845 (goto-char (+ (widget-get widget :to) offset 1)) 1846 (goto-char (+ (widget-get widget :to) offset 1))
1846 (goto-char (min (+ from offset) (1- (widget-get widget :to)))))))) 1847 (goto-char (min (+ from offset) (1- (widget-get widget :to))))))))
1847 1848
1848 (defun widget-default-value-inline (widget) 1849 (defun widget-default-value-inline (widget)
1849 ;; Wrap value in a list unless it is inline. 1850 "Wrap value in a list unless it is inline."
1850 (if (widget-get widget :inline) 1851 (if (widget-get widget :inline)
1851 (widget-value widget) 1852 (widget-value widget)
1852 (list (widget-value widget)))) 1853 (list (widget-value widget))))
1853 1854
1854 (defun widget-default-default-get (widget) 1855 (defun widget-default-default-get (widget)
1855 ;; Get `:value'. 1856 "Get `:value'."
1856 (widget-get widget :value)) 1857 (widget-get widget :value))
1857 1858
1858 (defun widget-default-menu-tag-get (widget) 1859 (defun widget-default-menu-tag-get (widget)
1859 ;; Use tag or value for menus. 1860 "Use tag or value for menus."
1860 (or (widget-get widget :menu-tag) 1861 (or (widget-get widget :menu-tag)
1861 (widget-get widget :tag) 1862 (widget-get widget :tag)
1862 (widget-princ-to-string (widget-get widget :value)))) 1863 (widget-princ-to-string (widget-get widget :value))))
1863 1864
1864 (defun widget-default-active (widget) 1865 (defun widget-default-active (widget)
1873 (widget-specify-inactive widget 1874 (widget-specify-inactive widget
1874 (widget-get widget :from) 1875 (widget-get widget :from)
1875 (widget-get widget :to))) 1876 (widget-get widget :to)))
1876 1877
1877 (defun widget-default-action (widget &optional event) 1878 (defun widget-default-action (widget &optional event)
1878 ;; Notify the parent when a widget change 1879 "Notify the parent when a widget changes."
1879 (let ((parent (widget-get widget :parent))) 1880 (let ((parent (widget-get widget :parent)))
1880 (when parent 1881 (when parent
1881 (widget-apply parent :notify widget event)))) 1882 (widget-apply parent :notify widget event))))
1882 1883
1883 (defun widget-default-notify (widget child &optional event) 1884 (defun widget-default-notify (widget child &optional event)
1884 ;; Pass notification to parent. 1885 "Pass notification to parent."
1885 (widget-default-action widget event)) 1886 (widget-default-action widget event))
1886 1887
1887 (defun widget-default-prompt-value (widget prompt value unbound) 1888 (defun widget-default-prompt-value (widget prompt value unbound)
1888 ;; Read an arbitrary value. Stolen from `set-variable'. 1889 "Read an arbitrary value. Stolen from `set-variable'."
1889 ;; (let ((initial (if unbound 1890 ;; (let ((initial (if unbound
1890 ;; nil 1891 ;; nil
1891 ;; ;; It would be nice if we could do a `(cons val 1)' here. 1892 ;; It would be nice if we could do a `(cons val 1)' here.
1892 ;; (prin1-to-string (custom-quote value)))))) 1893 ;; (prin1-to-string (custom-quote value))))))
1893 (eval-minibuffer prompt )) 1894 (eval-minibuffer prompt))
1894 1895
1895 ;;; The `item' Widget. 1896 ;;; The `item' Widget.
1896 1897
1897 (define-widget 'item 'default 1898 (define-widget 'item 'default
1898 "Constant items for inclusion in other widgets." 1899 "Constant items for inclusion in other widgets."
1904 :match-inline 'widget-item-match-inline 1905 :match-inline 'widget-item-match-inline
1905 :action 'widget-item-action 1906 :action 'widget-item-action
1906 :format "%t\n") 1907 :format "%t\n")
1907 1908
1908 (defun widget-item-value-create (widget) 1909 (defun widget-item-value-create (widget)
1909 ;; Insert the printed representation of the value. 1910 "Insert the printed representation of the value."
1910 (let ((standard-output (current-buffer))) 1911 (let ((standard-output (current-buffer)))
1911 (princ (widget-get widget :value)))) 1912 (princ (widget-get widget :value))))
1912 1913
1913 (defun widget-item-match (widget value) 1914 (defun widget-item-match (widget value)
1914 ;; Match if the value is the same. 1915 ;; Match if the value is the same.
1962 :button-suffix "" 1963 :button-suffix ""
1963 :value-create 'widget-push-button-value-create 1964 :value-create 'widget-push-button-value-create
1964 :format "%[%v%]") 1965 :format "%[%v%]")
1965 1966
1966 (defun widget-push-button-value-create (widget) 1967 (defun widget-push-button-value-create (widget)
1967 ;; Insert text representing the `on' and `off' states. 1968 "Insert text representing the `on' and `off' states."
1968 (let* ((tag (or (widget-get widget :tag) 1969 (let* ((tag (or (widget-get widget :tag)
1969 (widget-get widget :value))) 1970 (widget-get widget :value)))
1970 (tag-glyph (widget-get widget :tag-glyph)) 1971 (tag-glyph (widget-get widget :tag-glyph))
1971 (text (concat widget-push-button-prefix 1972 (text (concat widget-push-button-prefix
1972 tag widget-push-button-suffix)) 1973 tag widget-push-button-suffix))
2003 2004
2004 (define-widget 'link 'item 2005 (define-widget 'link 'item
2005 "An embedded link." 2006 "An embedded link."
2006 :button-prefix 'widget-link-prefix 2007 :button-prefix 'widget-link-prefix
2007 :button-suffix 'widget-link-suffix 2008 :button-suffix 'widget-link-suffix
2008 :help-echo "Follow the link" 2009 :help-echo "Follow the link."
2009 :format "%[%t%]") 2010 :format "%[%t%]")
2010 2011
2011 ;;; The `info-link' Widget. 2012 ;;; The `info-link' Widget.
2012 2013
2013 (define-widget 'info-link 'link 2014 (define-widget 'info-link 'link
2034 2035
2035 (defun widget-url-link-action (widget &optional event) 2036 (defun widget-url-link-action (widget &optional event)
2036 "Open the url specified by WIDGET." 2037 "Open the url specified by WIDGET."
2037 (if-fboundp 'browse-url 2038 (if-fboundp 'browse-url
2038 (browse-url (widget-value widget)) 2039 (browse-url (widget-value widget))
2040 ;; #### Should subclass a 'missing-package error.
2039 (error 'unimplemented "No `browse-url' package; cannot follow URLs in this XEmacs"))) 2041 (error 'unimplemented "No `browse-url' package; cannot follow URLs in this XEmacs")))
2040 2042
2041 ;;; The `function-link' Widget. 2043 ;;; The `function-link' Widget.
2042 2044
2043 (define-widget 'function-link 'link 2045 (define-widget 'function-link 'link
2114 2116
2115 (defvar widget-field-history nil 2117 (defvar widget-field-history nil
2116 "History of field minibuffer edits.") 2118 "History of field minibuffer edits.")
2117 2119
2118 (defun widget-field-prompt-internal (widget prompt initial history) 2120 (defun widget-field-prompt-internal (widget prompt initial history)
2119 ;; Read string for WIDGET prompting with PROMPT. 2121 "Read string for WIDGET prompting with PROMPT.
2120 ;; INITIAL is the initial input and HISTORY is a symbol containing 2122 INITIAL is the initial input and HISTORY is a symbol containing
2121 ;; the earlier input. 2123 the earlier input."
2122 (read-string prompt initial history)) 2124 (read-string prompt initial history))
2123 2125
2124 (defun widget-field-prompt-value (widget prompt value unbound) 2126 (defun widget-field-prompt-value (widget prompt value unbound)
2125 ;; Prompt for a string. 2127 "Prompt for a string."
2126 (let ((initial (if unbound 2128 (let ((initial (if unbound
2127 nil 2129 nil
2128 (cons (widget-apply widget :value-to-internal 2130 (cons (widget-apply widget :value-to-internal
2129 value) 0))) 2131 value) 0)))
2130 (history (widget-get widget :prompt-history))) 2132 (history (widget-get widget :prompt-history)))
2162 ; ;; Move to next field. 2164 ; ;; Move to next field.
2163 ; (widget-forward 1) 2165 ; (widget-forward 1)
2164 ; (run-hook-with-args 'widget-edit-functions widget)) 2166 ; (run-hook-with-args 'widget-edit-functions widget))
2165 2167
2166 (defun widget-field-validate (widget) 2168 (defun widget-field-validate (widget)
2167 ;; Valid if the content matches `:valid-regexp'. 2169 "Valid if the content matches `:valid-regexp'."
2168 (save-excursion 2170 (save-excursion
2169 (let ((value (widget-apply widget :value-get)) 2171 (let ((value (widget-apply widget :value-get))
2170 (regexp (widget-get widget :valid-regexp))) 2172 (regexp (widget-get widget :valid-regexp)))
2171 (if (string-match regexp value) 2173 (if (string-match regexp value)
2172 nil 2174 nil
2173 widget)))) 2175 widget))))
2174 2176
2175 (defun widget-field-value-create (widget) 2177 (defun widget-field-value-create (widget)
2176 ;; Create an editable text field. 2178 "Create an editable text field."
2177 (let ((size (widget-get widget :size)) 2179 (let ((size (widget-get widget :size))
2178 (value (widget-get widget :value)) 2180 (value (widget-get widget :value))
2179 (from (point)) 2181 (from (point))
2180 ;; This is changed to a real extent in `widget-setup'. We 2182 ;; This is changed to a real extent in `widget-setup'. We
2181 ;; need the end points to behave differently until 2183 ;; need the end points to behave differently until
2195 (insert ?\n)) 2197 (insert ?\n))
2196 (move-marker (car extent) from) 2198 (move-marker (car extent) from)
2197 (set-marker-insertion-type (car extent) t))) 2199 (set-marker-insertion-type (car extent) t)))
2198 2200
2199 (defun widget-field-value-delete (widget) 2201 (defun widget-field-value-delete (widget)
2200 ;; Remove the widget from the list of active editing fields. 2202 "Remove the widget from the list of active editing fields."
2201 (setq widget-field-list (delq widget widget-field-list)) 2203 (setq widget-field-list (delq widget widget-field-list))
2202 ;; These are nil if the :format string doesn't contain `%v'. 2204 ;; These are nil if the :format string doesn't contain `%v'.
2203 (let ((extent (widget-get widget :field-extent))) 2205 (let ((extent (widget-get widget :field-extent)))
2204 (when extent 2206 (when extent
2205 (detach-extent extent)))) 2207 (detach-extent extent))))
2206 2208
2207 (defun widget-field-value-get (widget) 2209 (defun widget-field-value-get (widget)
2208 ;; Return current text in editing field. 2210 "Return current text in editing field."
2209 (let ((from (widget-field-start widget)) 2211 (let ((from (widget-field-start widget))
2210 (to (widget-field-end widget)) 2212 (to (widget-field-end widget))
2211 (buffer (widget-field-buffer widget)) 2213 (buffer (widget-field-buffer widget))
2212 (size (widget-get widget :size)) 2214 (size (widget-get widget :size))
2213 (secret (widget-get widget :secret)) 2215 (secret (widget-get widget :secret))
2262 :validate 'widget-choice-validate 2264 :validate 'widget-choice-validate
2263 :match 'widget-choice-match 2265 :match 'widget-choice-match
2264 :match-inline 'widget-choice-match-inline) 2266 :match-inline 'widget-choice-match-inline)
2265 2267
2266 (defun widget-choice-value-create (widget) 2268 (defun widget-choice-value-create (widget)
2267 ;; Insert the first choice that matches the value. 2269 "Insert the first choice that matches the value."
2268 (let ((value (widget-get widget :value)) 2270 (let ((value (widget-get widget :value))
2269 (args (widget-get widget :args)) 2271 (args (widget-get widget :args))
2270 (explicit (widget-get widget :explicit-choice)) 2272 (explicit (widget-get widget :explicit-choice))
2271 current) 2273 current)
2272 (if explicit 2274 (if explicit
2273 (progn 2275 (progn
2276 ;; If the user specified the choice for this value,
2277 ;; respect that choice as long as the value is the same.
2274 (widget-put widget :children (list (widget-create-child-value 2278 (widget-put widget :children (list (widget-create-child-value
2275 widget explicit value))) 2279 widget explicit value)))
2276 (widget-put widget :choice explicit)) 2280 (widget-put widget :choice explicit))
2277 (while args 2281 (while args
2278 (setq current (car args) 2282 (setq current (car args)
2414 :match (lambda (widget value) t) 2418 :match (lambda (widget value) t)
2415 :on "on" 2419 :on "on"
2416 :off "off") 2420 :off "off")
2417 2421
2418 (defun widget-toggle-value-create (widget) 2422 (defun widget-toggle-value-create (widget)
2419 ;; Insert text representing the `on' and `off' states. 2423 "Insert text representing the `on' and `off' states."
2420 (if (widget-value widget) 2424 (if (widget-value widget)
2421 (widget-glyph-insert widget 2425 (widget-glyph-insert widget
2422 (widget-get widget :on) 2426 (widget-get widget :on)
2423 (widget-get widget :on-glyph)) 2427 (widget-get widget :on-glyph))
2424 (widget-glyph-insert widget 2428 (widget-glyph-insert widget
2478 (widget-checklist-add-item widget (car args) (assq (car args) alist)) 2482 (widget-checklist-add-item widget (car args) (assq (car args) alist))
2479 (setq args (cdr args))) 2483 (setq args (cdr args)))
2480 (widget-put widget :children (nreverse (widget-get widget :children))))) 2484 (widget-put widget :children (nreverse (widget-get widget :children)))))
2481 2485
2482 (defun widget-checklist-add-item (widget type chosen) 2486 (defun widget-checklist-add-item (widget type chosen)
2483 ;; Create checklist item in WIDGET of type TYPE. 2487 "Create checklist item in WIDGET of type TYPE.
2484 ;; If the item is checked, CHOSEN is a cons whose cdr is the value. 2488 If the item is checked, CHOSEN is a cons whose cdr is the value."
2485 (and (eq (preceding-char) ?\n) 2489 (and (eq (preceding-char) ?\n)
2486 (widget-get widget :indent) 2490 (widget-get widget :indent)
2487 (insert-char ?\ (widget-get widget :indent))) 2491 (insert-char ?\ (widget-get widget :indent)))
2488 (widget-specify-insert 2492 (widget-specify-insert
2489 (let* ((children (widget-get widget :children)) 2493 (let* ((children (widget-get widget :children))
2548 (setq rest (append rest values) 2552 (setq rest (append rest values)
2549 values nil))))) 2553 values nil)))))
2550 (cons found rest))) 2554 (cons found rest)))
2551 2555
2552 (defun widget-checklist-match-find (widget vals) 2556 (defun widget-checklist-match-find (widget vals)
2553 ;; Find the vals which match a type in the checklist. 2557 "Find the vals which match a type in the checklist.
2554 ;; Return an alist of (TYPE MATCH). 2558 Return an alist of (TYPE MATCH)."
2555 (let ((greedy (widget-get widget :greedy)) 2559 (let ((greedy (widget-get widget :greedy))
2556 (args (copy-sequence (widget-get widget :args))) 2560 (args (copy-sequence (widget-get widget :args)))
2557 found) 2561 found)
2558 (while vals 2562 (while vals
2559 (let ((answer (widget-checklist-match-up args vals))) 2563 (let ((answer (widget-checklist-match-up args vals)))
2567 (t 2571 (t
2568 (setq vals nil))))) 2572 (setq vals nil)))))
2569 found)) 2573 found))
2570 2574
2571 (defun widget-checklist-match-up (args vals) 2575 (defun widget-checklist-match-up (args vals)
2572 ;; Return the first type from ARGS that matches VALS. 2576 "Return the first type from ARGS that matches VALS."
2573 (let (current found) 2577 (let (current found)
2574 (while (and args (null found)) 2578 (while (and args (null found))
2575 (setq current (car args) 2579 (setq current (car args)
2576 args (cdr args) 2580 args (cdr args)
2577 found (widget-match-inline current vals))) 2581 found (widget-match-inline current vals)))
2797 ;;; The `insert-button' Widget. 2801 ;;; The `insert-button' Widget.
2798 2802
2799 (define-widget 'insert-button 'push-button 2803 (define-widget 'insert-button 'push-button
2800 "An insert button for the `editable-list' widget." 2804 "An insert button for the `editable-list' widget."
2801 :tag "INS" 2805 :tag "INS"
2802 :help-echo "Insert a new item into the list at this position" 2806 :help-echo "Insert a new item into the list at this position."
2803 :action 'widget-insert-button-action) 2807 :action 'widget-insert-button-action)
2804 2808
2805 (defun widget-insert-button-action (widget &optional event) 2809 (defun widget-insert-button-action (widget &optional event)
2806 ;; Ask the parent to insert a new item. 2810 ;; Ask the parent to insert a new item.
2807 (widget-apply (widget-get widget :parent) 2811 (widget-apply (widget-get widget :parent)
2810 ;;; The `delete-button' Widget. 2814 ;;; The `delete-button' Widget.
2811 2815
2812 (define-widget 'delete-button 'push-button 2816 (define-widget 'delete-button 'push-button
2813 "A delete button for the `editable-list' widget." 2817 "A delete button for the `editable-list' widget."
2814 :tag "DEL" 2818 :tag "DEL"
2815 :help-echo "Delete this item from the list" 2819 :help-echo "Delete this item from the list."
2816 :action 'widget-delete-button-action) 2820 :action 'widget-delete-button-action)
2817 2821
2818 (defun widget-delete-button-action (widget &optional event) 2822 (defun widget-delete-button-action (widget &optional event)
2819 ;; Ask the parent to insert a new item. 2823 ;; Ask the parent to insert a new item.
2820 (widget-apply (widget-get widget :parent) 2824 (widget-apply (widget-get widget :parent)
3026 (widget-get widget :indent) 3030 (widget-get widget :indent)
3027 (insert-char ?\ (widget-get widget :indent))) 3031 (insert-char ?\ (widget-get widget :indent)))
3028 (push (cond ((null answer) 3032 (push (cond ((null answer)
3029 (widget-create-child widget arg)) 3033 (widget-create-child widget arg))
3030 ((widget-get arg :inline) 3034 ((widget-get arg :inline)
3031 (widget-create-child-value widget arg (car answer))) 3035 (widget-create-child-value widget arg (car answer)))
3032 (t 3036 (t
3033 (widget-create-child-value widget arg (car (car answer))))) 3037 (widget-create-child-value widget arg (car (car answer)))))
3034 children)) 3038 children))
3035 (widget-put widget :children (nreverse children)))) 3039 (widget-put widget :children (nreverse children))))
3036 3040
3037 (defun widget-group-default-get (widget) 3041 (defun widget-group-default-get (widget)
3038 ;; Get the default of the components. 3042 ;; Get the default of the components.
3336 ;;; dir nil must-match file))) 3340 ;;; dir nil must-match file)))
3337 ;;; (widget-value-set widget (abbreviate-file-name answer)) 3341 ;;; (widget-value-set widget (abbreviate-file-name answer))
3338 ;;; (widget-setup) 3342 ;;; (widget-setup)
3339 ;;; (widget-apply widget :notify widget event))) 3343 ;;; (widget-apply widget :notify widget event)))
3340 3344
3345 ;; Fixme: use file-name-as-directory.
3341 (define-widget 'directory 'file 3346 (define-widget 'directory 'file
3342 "A directory widget. 3347 "A directory widget.
3343 It will read a directory name from the minibuffer when invoked." 3348 It will read a directory name from the minibuffer when invoked."
3344 :tag "Directory") 3349 :tag "Directory")
3345 3350
3346 (defvar widget-symbol-prompt-value-history nil 3351 (defvar widget-symbol-prompt-value-history nil
3347 "History of input to `widget-symbol-prompt-value'.") 3352 "History of input to `widget-symbol-prompt-value'.")
3348 3353
3349 (define-widget 'symbol 'editable-field 3354 (define-widget 'symbol 'editable-field
3350 "A lisp symbol." 3355 "A Lisp symbol."
3351 :value nil 3356 :value nil
3352 :tag "Symbol" 3357 :tag "Symbol"
3353 :format "%{%t%}: %v" 3358 :format "%{%t%}: %v"
3354 :match (lambda (widget value) (symbolp value)) 3359 :match (lambda (widget value) (symbolp value))
3355 :complete-function 'lisp-complete-symbol 3360 :complete-function 'lisp-complete-symbol
3377 3382
3378 (defvar widget-function-prompt-value-history nil 3383 (defvar widget-function-prompt-value-history nil
3379 "History of input to `widget-function-prompt-value'.") 3384 "History of input to `widget-function-prompt-value'.")
3380 3385
3381 (define-widget 'function 'sexp 3386 (define-widget 'function 'sexp
3382 "A lisp function." 3387 "A Lisp function."
3383 :complete-function 'lisp-complete-symbol 3388 :complete-function 'lisp-complete-symbol
3384 :prompt-value 'widget-field-prompt-value 3389 :prompt-value 'widget-field-prompt-value
3385 :prompt-internal 'widget-symbol-prompt-internal 3390 :prompt-internal 'widget-symbol-prompt-internal
3386 :prompt-match 'fboundp 3391 :prompt-match 'fboundp
3387 :prompt-history 'widget-function-prompt-value-history 3392 :prompt-history 'widget-function-prompt-value-history
3391 (defvar widget-variable-prompt-value-history nil 3396 (defvar widget-variable-prompt-value-history nil
3392 "History of input to `widget-variable-prompt-value'.") 3397 "History of input to `widget-variable-prompt-value'.")
3393 3398
3394 (define-widget 'variable 'symbol 3399 (define-widget 'variable 'symbol
3395 ;; Should complete on variables. 3400 ;; Should complete on variables.
3396 "A lisp variable." 3401 "A Lisp variable."
3397 :prompt-match 'boundp 3402 :prompt-match 'boundp
3398 :prompt-history 'widget-variable-prompt-value-history 3403 :prompt-history 'widget-variable-prompt-value-history
3399 :tag "Variable") 3404 :tag "Variable")
3400 3405
3401 ;; This part issues a warning when compiling without Mule. Is there a 3406 ;; This part issues a warning when compiling without Mule. Is there a
3433 ; (widget-value-set widget answer) 3438 ; (widget-value-set widget answer)
3434 ; (widget-apply widget :notify widget event) 3439 ; (widget-apply widget :notify widget event)
3435 ; (widget-setup))) 3440 ; (widget-setup)))
3436 3441
3437 (define-widget 'sexp 'editable-field 3442 (define-widget 'sexp 'editable-field
3438 "An arbitrary lisp expression." 3443 "An arbitrary Lisp expression."
3439 :tag "Lisp expression" 3444 :tag "Lisp expression"
3440 :format "%{%t%}: %v" 3445 :format "%{%t%}: %v"
3441 :value nil 3446 :value nil
3442 :validate 'widget-sexp-validate 3447 :validate 'widget-sexp-validate
3443 :match (lambda (widget value) t) 3448 :match (lambda (widget value) t)
3526 :value 0 3531 :value 0
3527 :type-error "This field should contain an integer" 3532 :type-error "This field should contain an integer"
3528 :match-alternatives '(integerp)) 3533 :match-alternatives '(integerp))
3529 3534
3530 (define-widget 'number 'restricted-sexp 3535 (define-widget 'number 'restricted-sexp
3531 "A floating point number." 3536 "A number (floating point or integer)."
3532 :tag "Number" 3537 :tag "Number"
3533 :value 0.0 3538 :value 0.0
3534 :type-error "This field should contain a number" 3539 :type-error "This field should contain a number (floating point or integer)"
3535 :match-alternatives '(numberp)) 3540 :match-alternatives '(numberp))
3536 3541
3537 (define-widget 'character 'editable-field 3542 (define-widget 'character 'editable-field
3538 "A character." 3543 "A character."
3539 :tag "Character" 3544 :tag "Character"
3596 (defun widget-choice-prompt-value (widget prompt value unbound) 3601 (defun widget-choice-prompt-value (widget prompt value unbound)
3597 "Make a choice." 3602 "Make a choice."
3598 (let ((args (widget-get widget :args)) 3603 (let ((args (widget-get widget :args))
3599 (completion-ignore-case (widget-get widget :case-fold)) 3604 (completion-ignore-case (widget-get widget :case-fold))
3600 current choices old) 3605 current choices old)
3601 ;; Find the first arg that match VALUE. 3606 ;; Find the first arg that matches VALUE.
3602 (let ((look args)) 3607 (let ((look args))
3603 (while look 3608 (while look
3604 (if (widget-apply (car look) :match value) 3609 (if (widget-apply (car look) :match value)
3605 (setq old (car look) 3610 (setq old (car look)
3606 look nil) 3611 look nil)
3665 ;; Toggle a boolean. 3670 ;; Toggle a boolean.
3666 (y-or-n-p prompt)) 3671 (y-or-n-p prompt))
3667 3672
3668 ;;; The `color' Widget. 3673 ;;; The `color' Widget.
3669 3674
3675 ;; Fixme: match
3670 (define-widget 'color 'editable-field 3676 (define-widget 'color 'editable-field
3671 "Choose a color name (with sample)." 3677 "Choose a color name (with sample)."
3672 :format "%[%t%]: %v (%{sample%})\n" 3678 :format "%[%t%]: %v (%{sample%})\n"
3673 :size 10 3679 :size 10
3674 :tag "Color" 3680 :tag "Color"
3683 (let* ((prefix (buffer-substring-no-properties (widget-field-start widget) 3689 (let* ((prefix (buffer-substring-no-properties (widget-field-start widget)
3684 (point))) 3690 (point)))
3685 (list (read-color-completion-table)) 3691 (list (read-color-completion-table))
3686 (completion (try-completion prefix list))) 3692 (completion (try-completion prefix list)))
3687 (cond ((eq completion t) 3693 (cond ((eq completion t)
3688 (message "Exact match")) 3694 (message "Exact match."))
3689 ((null completion) 3695 ((null completion)
3690 (error "Can't find completion for \"%s\"" prefix)) 3696 (error "Can't find completion for \"%s\"" prefix))
3691 ((not (string-equal prefix completion)) 3697 ((not (string-equal prefix completion))
3692 (insert (substring completion (length prefix)))) 3698 (insert (substring completion (length prefix))))
3693 (t 3699 (t
3712 3718
3713 (defvar widget-color-history nil 3719 (defvar widget-color-history nil
3714 "History of entered colors.") 3720 "History of entered colors.")
3715 3721
3716 (defun widget-color-action (widget &optional event) 3722 (defun widget-color-action (widget &optional event)
3717 ;; Prompt for a color. 3723 "Prompt for a color."
3718 (let* ((tag (widget-apply widget :menu-tag-get)) 3724 (let* ((tag (widget-apply widget :menu-tag-get))
3719 (answer (read-color (concat tag ": ")))) 3725 (answer (read-color (concat tag ": "))))
3720 (unless (zerop (length answer)) 3726 (unless (zerop (length answer))
3721 (widget-value-set widget answer) 3727 (widget-value-set widget answer)
3722 (widget-setup) 3728 (widget-setup)
3735 (defun widget-at (pos) 3741 (defun widget-at (pos)
3736 "The button or field at POS." 3742 "The button or field at POS."
3737 (or (get-char-property pos 'button) 3743 (or (get-char-property pos 'button)
3738 (get-char-property pos 'field))) 3744 (get-char-property pos 'field)))
3739 3745
3746 ;;; The Help Echo
3747
3740 (defun widget-echo-help (pos) 3748 (defun widget-echo-help (pos)
3741 "Display the help echo for widget at POS." 3749 "Display the help-echo text for widget at POS."
3742 (let* ((widget (widget-at pos)) 3750 (let* ((widget (widget-at pos))
3743 (help-echo (and widget (widget-get widget :help-echo)))) 3751 (help-echo (and widget (widget-get widget :help-echo))))
3744 (and (functionp help-echo) 3752 (and (functionp help-echo)
3745 (setq help-echo (funcall help-echo widget))) 3753 (setq help-echo (funcall help-echo widget)))
3746 (when (stringp help-echo) 3754 (when (stringp help-echo)
3748 3756
3749 ;;; The End: 3757 ;;; The End:
3750 3758
3751 (provide 'wid-edit) 3759 (provide 'wid-edit)
3752 3760
3753 ;; wid-edit.el ends here 3761 ;;; wid-edit.el ends here