Mercurial > hg > xemacs-beta
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 |