Mercurial > emacs
changeset 29402:3bb8d5adf524
byte-compile-dynamic since we typically don't use
all the widgets. Don't require cl or widget. Remove
eval-and-compile. Don't autoload finder-commentary. Doc fixes.
(widget-read-event): Removed. Callers changed to use read-event.
(widget-button-release-event-p): Renamed from
button-release-event-p.
(widget-field-add-space, widget-field-use-before-change):
Uncustomize.
(widget-specify-field): Use keymap property, not local-map.
(widget-specify-button): Obey :suppress-face.
(widget-specify-insert): Use modern backquote syntax.
(widget-image-directory): Renamed from widget-glyph-directory.
(widget-image-enable): Renamed from widget-glyph-enable.
(widget-image-find): Replaces widget-glyph-find.
(widget-button-pressed-face): Move defvar.
(widget-image-insert): Replaces widget-glyph-insert.
(widget-convert): Use keywordp.
(widget-leave-text, widget-children-value-delete): Use mapc.
(widget-keymap): Remove XEmacs stuff.
(widget-field-keymap, widget-text-keymap): Define all inside
defvar.
(widget-button-click): Don't set point at the click, but re-centre
if we scroll out of window. Rewritten for images v. glyphs &c.
(widget-tabable-at): Use POS arg, not point.
(widget-beginning-of-line, widget-end-of-line)
(widget-item-value-create, widget-sublist, widget-princ-to-string)
(widget-sexp-prompt-value, widget-echo-help): Simplify.
(widget-default-create): Use widget-image-insert; some rewriting.
(widget-visibility-value-create)
(widget-push-button-value-create, widget-toggle-value-create): Use
widget-image-insert.
(checkbox): Create on and off images dynamically.
(documentation-link): Change :help-echo.
(widget-documentation-link-echo-help): Remove.
author | Dave Love <fx@gnu.org> |
---|---|
date | Sat, 03 Jun 2000 16:42:14 +0000 |
parents | 8cecaaeeeaa4 |
children | efa6bac91b58 |
files | lisp/wid-edit.el |
diffstat | 1 files changed, 340 insertions(+), 493 deletions(-) [+] |
line wrap: on
line diff
--- a/lisp/wid-edit.el Sat Jun 03 13:14:12 2000 +0000 +++ b/lisp/wid-edit.el Sat Jun 03 16:42:14 2000 +0000 @@ -1,4 +1,4 @@ -;;; wid-edit.el --- Functions for creating and using widgets. +;;; wid-edit.el --- Functions for creating and using widgets -*-byte-compile-dynamic: t;-*- ;; ;; Copyright (C) 1996, 1997, 1999, 2000 Free Software Foundation, Inc. ;; @@ -29,30 +29,21 @@ ;;; Code: -(require 'widget) -(eval-when-compile (require 'cl)) - ;;; Compatibility. - + (defun widget-event-point (event) "Character position of the end of event if that exists, or nil." (posn-point (event-end event))) -(defalias 'widget-read-event 'read-event) - -(eval-and-compile - (autoload 'pp-to-string "pp") - (autoload 'Info-goto-node "info") - (autoload 'finder-commentary "finder" nil t) - - (unless (fboundp 'button-release-event-p) - ;; XEmacs function missing from Emacs. - (defun button-release-event-p (event) - "Non-nil if EVENT is a mouse-button-release event object." - (and (eventp event) - (memq (event-basic-type event) '(mouse-1 mouse-2 mouse-3)) - (or (memq 'click (event-modifiers event)) - (memq 'drag (event-modifiers event))))))) +(autoload 'pp-to-string "pp") +(autoload 'Info-goto-node "info") + +(defun widget-button-release-event-p (event) + "Non-nil if EVENT is a mouse-button-release event object." + (and (eventp event) + (memq (event-basic-type event) '(mouse-1 mouse-2 mouse-3)) + (or (memq 'click (event-modifiers event)) + (memq 'drag (event-modifiers event))))) ;;; Customization. @@ -107,7 +98,7 @@ (((class grayscale color) (background dark)) (:background "dim gray")) - (t + (t (:italic t))) "Face used for editable fields." :group 'widget-faces) @@ -118,7 +109,7 @@ (((class grayscale color) (background dark)) (:background "dim gray")) - (t + (t (:italic t))) "Face used for editable fields spanning only a single line." :group 'widget-faces) @@ -140,15 +131,11 @@ ;; These are not really widget specific. (defun widget-princ-to-string (object) - ;; Return string representation of OBJECT, any Lisp object. - ;; No quoting characters are used; no delimiters are printed around - ;; the contents of strings. - (save-excursion - (set-buffer (get-buffer-create " *widget-tmp*")) - (erase-buffer) - (let ((standard-output (current-buffer))) - (princ object)) - (buffer-string))) + "Return string representation of OBJECT, any Lisp object. +No quoting characters are used; no delimiters are printed around +the contents of strings." + (with-output-to-string + (princ object))) (defun widget-clear-undo () "Clear all undo information." @@ -202,8 +189,7 @@ (let ((try (try-completion val items))) (when (stringp try) (setq val try)) - (cdr (assoc val items))) - nil))) + (cdr (assoc val items)))))) (t ;; Construct a menu of the choices ;; and then use it for prompting for a single character. @@ -252,12 +238,15 @@ ;; Unread a SPC to lead to our new menu. (setq unread-command-events (cons ?\ unread-command-events)) (setq keys (read-key-sequence title)) - (setq value (lookup-key overriding-terminal-local-map keys t) + (setq value + (lookup-key overriding-terminal-local-map keys t) char (string-to-char (substring keys 1))) (cond ((eq value 'scroll-other-window) - (let ((minibuffer-scroll-window (get-buffer-window buf))) + (let ((minibuffer-scroll-window + (get-buffer-window buf))) (if (> 0 arg) - (scroll-other-window-down (window-height minibuffer-scroll-window)) + (scroll-other-window-down + (window-height minibuffer-scroll-window)) (scroll-other-window)) (setq arg 1))) ((eq value 'negative-argument) @@ -278,31 +267,18 @@ ;;; Widget text specifications. ;; -;; These functions are for specifying text properties. - -(defcustom widget-field-add-space - (or (< emacs-major-version 20) - (and (eq emacs-major-version 20) - (< emacs-minor-version 3)) - (not (string-match "XEmacs" emacs-version))) +;; These functions are for specifying text properties. + +(defvar widget-field-add-space t "Non-nil means add extra space at the end of editable text fields. - -This is needed on all versions of Emacs, and on XEmacs before 20.3. If you don't add the space, it will become impossible to edit a zero -size field." - :type 'boolean - :group 'widgets) - -(defcustom widget-field-use-before-change - (and (or (> emacs-minor-version 34) - (> emacs-major-version 19)) - (not (string-match "XEmacs" emacs-version))) +size field.") + +(defvar widget-field-use-before-change t "Non-nil means use `before-change-functions' to track editable fields. -This enables the use of undo, but doesn't work on Emacs 19.34 and earlier. +This enables the use of undo, but doesn't work on Emacs 19.34 and earlier. Using before hooks also means that the :notify function can't know the -new value." - :type 'boolean - :group 'widgets) +new value.") (defun widget-specify-field (widget from to) "Specify editable button for WIDGET between FROM and TO." @@ -319,14 +295,13 @@ (let ((map (widget-get widget :keymap)) (face (or (widget-get widget :value-face) 'widget-field-face)) (help-echo (widget-get widget :help-echo)) - (overlay (make-overlay from to nil + (overlay (make-overlay from to nil nil (or (not widget-field-add-space) - (widget-get widget :size))))) + (widget-get widget :size))))) (widget-put widget :field-overlay overlay) ;;(overlay-put overlay 'detachable nil) (overlay-put overlay 'field widget) - (overlay-put overlay 'local-map map) - ;;(overlay-put overlay 'keymap map) + (overlay-put overlay 'keymap map) (overlay-put overlay 'face face) ;;(overlay-put overlay 'balloon-help help-echo) (if (stringp help-echo) @@ -340,7 +315,7 @@ (when secret (let ((begin (widget-field-start field)) (end (widget-field-end field))) - (when size + (when size (while (and (> end begin) (eq (char-after (1- end)) ?\ )) (setq end (1- end)))) @@ -358,42 +333,44 @@ (overlay (make-overlay from to nil t nil))) (widget-put widget :button-overlay overlay) (overlay-put overlay 'button widget) - (overlay-put overlay 'mouse-face widget-mouse-face) + ;; We want to avoid the face with image buttons. + (unless (widget-get widget :suppress-face) + (overlay-put overlay 'face face) + (overlay-put overlay 'mouse-face widget-mouse-face)) ;;(overlay-put overlay 'balloon-help help-echo) (if (stringp help-echo) (overlay-put overlay 'help-echo help-echo)) (overlay-put overlay 'face face))) (defun widget-specify-sample (widget from to) - ;; Specify sample for WIDGET between FROM and TO. + "Specify sample for WIDGET between FROM and TO." (let ((face (widget-apply widget :sample-face-get)) (overlay (make-overlay from to nil t nil))) (overlay-put overlay 'face face) (widget-put widget :sample-overlay overlay))) (defun widget-specify-doc (widget from to) - ;; Specify documentation for WIDGET between FROM and TO. + "Specify documentation for WIDGET between FROM and TO." (let ((overlay (make-overlay from to nil t nil))) (overlay-put overlay 'widget-doc widget) (overlay-put overlay 'face widget-documentation-face) (widget-put widget :doc-overlay overlay))) (defmacro widget-specify-insert (&rest form) - ;; Execute FORM without inheriting any text properties. - (` - (save-restriction - (let ((inhibit-read-only t) - result - before-change-functions - after-change-functions) - (insert "<>") - (narrow-to-region (- (point) 2) (point)) - (goto-char (1+ (point-min))) - (setq result (progn (,@ form))) - (delete-region (point-min) (1+ (point-min))) - (delete-region (1- (point-max)) (point-max)) - (goto-char (point-max)) - result)))) + "Execute FORM without inheriting any text properties." + `(save-restriction + (let ((inhibit-read-only t) + result + before-change-functions + after-change-functions) + (insert "<>") + (narrow-to-region (- (point) 2) (point)) + (goto-char (1+ (point-min))) + (setq result (progn ,@form)) + (delete-region (point-min) (1+ (point-min))) + (delete-region (1- (point-max)) (point-max)) + (goto-char (point-max)) + result))) (defface widget-inactive-face '((((class grayscale color) (background dark)) @@ -401,7 +378,7 @@ (((class grayscale color) (background light)) (:foreground "dim gray")) - (t + (t (:italic t))) "Face used for inactive widgets." :group 'widget-faces) @@ -439,7 +416,7 @@ (defun widget-get-indirect (widget property) "In WIDGET, get the value of PROPERTY. -If the value is a symbol, return its binding. +If the value is a symbol, return its binding. Otherwise, just return the value." (let ((value (widget-get widget property))) (if (symbolp value) @@ -499,7 +476,7 @@ (setq widget (widget-convert widget)) (let ((answer (widget-apply widget :prompt-value prompt value unbound))) (unless (widget-apply widget :match answer) - (error "Value does not match %S type." (car widget))) + (error "Value does not match %S type" (car widget))) answer)) (defun widget-get-sibling (widget) @@ -536,17 +513,19 @@ (if (and widget (funcall function widget maparg)) (setq overlays nil))))) -;;; Glyphs. - -(defcustom widget-glyph-directory (concat data-directory "custom/") - "Where widget glyphs are located. +;;; Images. + +(defcustom widget-image-directory (file-name-as-directory + (expand-file-name "custom" data-directory)) + "Where widget button images are located. If this variable is nil, widget will try to locate the directory automatically." :group 'widgets :type 'directory) -(defcustom widget-glyph-enable t - "If non nil, use glyphs in images when available." +(defcustom widget-image-enable t + "If non nil, use image buttons in widgets when available." + :version "21.1" :group 'widgets :type 'boolean) @@ -560,104 +539,51 @@ (repeat :tag "Suffixes" (string :format "%v"))))) -(defun widget-glyph-find (image tag) - "Create a glyph corresponding to IMAGE with string TAG as fallback. -IMAGE should either already be a glyph, or be a file name sans +(defun widget-image-find (image) + "Create a graphical button from IMAGE. +IMAGE should either already be an image, or be a file name sans extension (xpm, xbm, gif, jpg, or png) located in -`widget-glyph-directory'." - (cond ((not (and image - (string-match "XEmacs" emacs-version) - widget-glyph-enable - (fboundp 'make-glyph) - (fboundp 'locate-file) - image)) - ;; We don't want or can't use glyphs. +`widget-image-directory' or otherwise where `find-image' will find it." + (cond ((not (and image widget-image-enable (display-graphic-p))) + ;; We don't want or can't use images. nil) - ((and (fboundp 'glyphp) - (glyphp image)) - ;; Already a glyph. Use it. + ((and (consp image) + (eq 'image (car image))) + ;; Already an image spec. Use it. image) ((stringp image) ;; A string. Look it up in relevant directories. - (let* ((dirlist (list (or widget-glyph-directory - (concat data-directory - "custom/")) - data-directory)) + (let* ((load-path (cons widget-image-directory load-path)) (formats widget-image-conversion) - file) - (while (and formats (not file)) - (when (valid-image-instantiator-format-p (car (car formats))) - (setq file (locate-file image dirlist - (mapconcat 'identity - (cdr (car formats)) - ":")))) - (unless file - (setq formats (cdr formats)))) - (and file - ;; We create a glyph with the file as the default image - ;; instantiator, and the TAG fallback - (make-glyph (list (vector (car (car formats)) ':file file) - (vector 'string ':data tag)))))) - ((valid-instantiator-p image 'image) - ;; A valid image instantiator (e.g. [gif :file "somefile"] etc.) - (make-glyph (list image - (vector 'string ':data tag)))) - ((consp image) - ;; This could be virtually anything. Let `make-glyph' sort it out. - (make-glyph image)) + specs) + (dolist (elt widget-image-conversion) + (dolist (ext (cdr elt)) + (push (list :type (car elt) :file (concat image ext)) specs))) + (setq specs (nreverse specs)) + (find-image specs))) (t ;; Oh well. nil))) -(defun widget-glyph-insert (widget tag image &optional down inactive) +(defvar widget-button-pressed-face 'widget-button-pressed-face + "Face used for pressed buttons in widgets. +This exists as a variable so it can be set locally in certain +buffers.") + +(defun widget-image-insert (widget tag image &optional down inactive) "In WIDGET, insert the text TAG or, if supported, IMAGE. -IMAGE should either be a glyph, an image instantiator, or an image file -name sans extension (xpm, xbm, gif, jpg, or png) located in -`widget-glyph-directory'. - -Optional arguments DOWN and INACTIVE is used instead of IMAGE when the -glyph is pressed or inactive, respectively. - -WARNING: If you call this with a glyph, and you want the user to be -able to invoke the glyph, make sure it is unique. If you use the -same glyph for multiple widgets, invoking any of the glyphs will -cause the last created widget to be invoked. - -Instead of an instantiator, you can also use a list of instantiators, -or whatever `make-glyph' will accept. However, in that case you must -provide the fallback TAG as a part of the instantiator yourself." - (let ((glyph (widget-glyph-find image tag))) - (if glyph - (widget-glyph-insert-glyph widget - glyph - (widget-glyph-find down tag) - (widget-glyph-find inactive tag)) - (insert tag)))) - -(defun widget-glyph-insert-glyph (widget glyph &optional down inactive) - "In WIDGET, insert GLYPH. -If optional arguments DOWN and INACTIVE are given, they should be -glyphs used when the widget is pushed and inactive, respectively." - (when widget - (set-glyph-property glyph 'widget widget) - (when down - (set-glyph-property down 'widget widget)) - (when inactive - (set-glyph-property inactive 'widget widget))) - (insert "*") - (let ((ext (make-extent (point) (1- (point)))) - (help-echo (and widget (widget-get widget :help-echo)))) - (set-extent-property ext 'invisible t) - (set-extent-property ext 'start-open t) - (set-extent-property ext 'end-open t) - (set-extent-end-glyph ext glyph) - (when help-echo - (set-extent-property ext 'balloon-help help-echo) - (set-extent-property ext 'help-echo help-echo))) - (when widget - (widget-put widget :glyph-up glyph) - (when down (widget-put widget :glyph-down down)) - (when inactive (widget-put widget :glyph-inactive inactive)))) +IMAGE should either be an image or an image file name sans extension +\(xpm, xbm, gif, jpg, or png) located in `widget-image-directory'. + +Optional arguments DOWN and INACTIVE are used instead of IMAGE when the +button is pressed or inactive, respectively. These are currently ignored." + (if (and (display-graphic-p) + (setq image (widget-image-find image))) + (progn (widget-put widget :suppress-face t) + (insert-image image + (propertize + tag 'mouse-face widget-button-pressed-face))) + (insert tag))) ;;; Buttons. @@ -679,7 +605,7 @@ ;;;###autoload (defun widget-create (type &rest args) - "Create widget of TYPE. + "Create widget of TYPE. The optional ARGS are additional keyword arguments." (let ((widget (apply 'widget-convert type args))) (widget-apply widget :create) @@ -726,10 +652,10 @@ (widget-apply widget :delete)) (defun widget-convert (type &rest args) - "Convert TYPE to a widget without inserting it in the buffer. + "Convert TYPE to a widget without inserting it in the buffer. The optional ARGS are additional keyword arguments." ;; Don't touch the type. - (let* ((widget (if (symbolp type) + (let* ((widget (if (symbolp type) (list type) (copy-sequence type))) (current widget) @@ -737,13 +663,13 @@ ;; First set the :args keyword. (while (cdr current) ;Look in the type. (let ((next (car (cdr current)))) - (if (and (symbolp next) (eq (aref (symbol-name next) 0) ?:)) + (if (keywordp next) (setq current (cdr (cdr current))) (setcdr current (list :args (cdr current))) (setq current nil)))) (while args ;Look in the args. (let ((next (nth 0 args))) - (if (and (symbolp next) (eq (aref (symbol-name next) 0) ?:)) + (if (keywordp next) (setq args (nthcdr 2 args)) (widget-put widget :args args) (setq args nil)))) @@ -755,10 +681,10 @@ (setq widget (funcall convert-widget widget)))) (setq type (get (car type) 'widget-type))) ;; Finally set the keyword args. - (while keys + (while keys (let ((next (nth 0 keys))) - (if (and (symbolp next) (eq (aref (symbol-name next) 0) ?:)) - (progn + (if (keywordp next) + (progn (widget-put widget next (nth 1 keys)) (setq keys (nthcdr 2 keys))) (setq keys nil)))) @@ -825,54 +751,46 @@ (delete-overlay doc)) (when field (delete-overlay field)) - (mapcar 'widget-leave-text children))) + (mapc 'widget-leave-text children))) ;;; Keymap and Commands. -(defvar widget-keymap nil +(defvar widget-keymap + (let ((map (make-sparse-keymap))) + (define-key map "\t" 'widget-forward) + (define-key map [(shift tab)] 'widget-backward) + (define-key map [backtab] 'widget-backward) + (define-key map [down-mouse-2] 'widget-button-click) + (define-key map "\C-m" 'widget-button-press) + map) "Keymap containing useful binding for buffers containing widgets. Recommended as a parent keymap for modes using widgets.") -(unless widget-keymap - (setq widget-keymap (make-sparse-keymap)) - (define-key widget-keymap "\t" 'widget-forward) - (define-key widget-keymap [(shift tab)] 'widget-backward) - (define-key widget-keymap [backtab] 'widget-backward) - (if (string-match "XEmacs" emacs-version) - (progn - ;;Glyph support. - (define-key widget-keymap [button1] 'widget-button1-click) - (define-key widget-keymap [button2] 'widget-button-click)) - (define-key widget-keymap [down-mouse-2] 'widget-button-click)) - (define-key widget-keymap "\C-m" 'widget-button-press)) - (defvar widget-global-map global-map "Keymap used for events the widget does not handle themselves.") (make-variable-buffer-local 'widget-global-map) -(defvar widget-field-keymap nil +(defvar widget-field-keymap + (let ((map (copy-keymap widget-keymap))) + (define-key map [menu-bar] nil) + (define-key map "\C-k" 'widget-kill-line) + (define-key map "\M-\t" 'widget-complete) + (define-key map "\C-m" 'widget-field-activate) + (define-key map "\C-a" 'widget-beginning-of-line) + (define-key map "\C-e" 'widget-end-of-line) + (set-keymap-parent map global-map) + map) "Keymap used inside an editable field.") -(unless widget-field-keymap - (setq widget-field-keymap (copy-keymap widget-keymap)) - (define-key widget-field-keymap [menu-bar] 'nil) - (define-key widget-field-keymap "\C-k" 'widget-kill-line) - (define-key widget-field-keymap "\M-\t" 'widget-complete) - (define-key widget-field-keymap "\C-m" 'widget-field-activate) - (define-key widget-field-keymap "\C-a" 'widget-beginning-of-line) - (define-key widget-field-keymap "\C-e" 'widget-end-of-line) - (set-keymap-parent widget-field-keymap global-map)) - -(defvar widget-text-keymap nil +(defvar widget-text-keymap + (let ((map (copy-keymap widget-keymap))) + (define-key map [menu-bar] 'nil) + (define-key map "\C-a" 'widget-beginning-of-line) + (define-key map "\C-e" 'widget-end-of-line) + (set-keymap-parent map global-map) + map) "Keymap used inside a text field.") -(unless widget-text-keymap - (setq widget-text-keymap (copy-keymap widget-keymap)) - (define-key widget-text-keymap [menu-bar] 'nil) - (define-key widget-text-keymap "\C-a" 'widget-beginning-of-line) - (define-key widget-text-keymap "\C-e" 'widget-end-of-line) - (set-keymap-parent widget-text-keymap global-map)) - (defun widget-field-activate (pos &optional event) "Invoke the ediable field at point." (interactive "@d") @@ -882,11 +800,7 @@ (call-interactively (lookup-key widget-global-map (this-command-keys)))))) -(defvar widget-button-pressed-face 'widget-button-pressed-face - "Face used for pressed buttons in widgets. -This exists as a variable so it can be set locally in certain buffers.") - -(defface widget-button-pressed-face +(defface widget-button-pressed-face '((((class color)) (:foreground "red")) (t @@ -895,104 +809,72 @@ :group 'widget-faces) (defun widget-button-click (event) - "Invoke the button that the mouse is pointing at, and move there." + "Invoke the button that the mouse is pointing at." (interactive "@e") - (mouse-set-point event) - (cond ((and (fboundp 'event-glyph) - (event-glyph event)) - (widget-glyph-click event)) - ((widget-event-point event) - (let* ((pos (widget-event-point event)) - (button (get-char-property pos 'button))) - (if button - (let* ((overlay (widget-get button :button-overlay)) - (face (overlay-get overlay 'face)) - (mouse-face (overlay-get overlay 'mouse-face))) - (unwind-protect - (let ((track-mouse t)) - (save-excursion - (overlay-put overlay - 'face widget-button-pressed-face) - (overlay-put overlay - 'mouse-face widget-button-pressed-face) - (unless (widget-apply button :mouse-down-action event) - (while (not (button-release-event-p event)) - (setq event (widget-read-event) - pos (widget-event-point event)) - (if (and pos - (eq (get-char-property pos 'button) - button)) - (progn - (overlay-put overlay - 'face - widget-button-pressed-face) - (overlay-put overlay - 'mouse-face - widget-button-pressed-face)) - (overlay-put overlay 'face face) - (overlay-put overlay 'mouse-face mouse-face)))) - (when (and pos - (eq (get-char-property pos 'button) button)) - (widget-apply-action button event)))) - (overlay-put overlay 'face face) - (overlay-put overlay 'mouse-face mouse-face))) - (let ((up t) - command) - ;; Find the global command to run, and check whether it - ;; is bound to an up event. - (cond ((setq command ;down event - (lookup-key widget-global-map [ button2 ])) - (setq up nil)) - ((setq command ;down event - (lookup-key widget-global-map [ down-mouse-2 ])) - (setq up nil)) - ((setq command ;up event - (lookup-key widget-global-map [ button2up ]))) - ((setq command ;up event - (lookup-key widget-global-map [ mouse-2])))) - (when up - ;; Don't execute up events twice. - (while (not (button-release-event-p event)) - (setq event (widget-read-event)))) - (when command - (call-interactively command)))))) - (t - (message "You clicked somewhere weird.")))) - -(defun widget-button1-click (event) - "Invoke glyph below mouse pointer." - (interactive "@e") - (if (and (fboundp 'event-glyph) - (event-glyph event)) - (widget-glyph-click event) - (call-interactively (lookup-key widget-global-map (this-command-keys))))) - -(defun widget-glyph-click (event) - "Handle click on a glyph." - (let* ((glyph (event-glyph event)) - (widget (glyph-property glyph 'widget)) - (extent (event-glyph-extent event)) - (down-glyph (or (and widget (widget-get widget :glyph-down)) glyph)) - (up-glyph (or (and widget (widget-get widget :glyph-up)) glyph)) - (last event)) - ;; Wait for the release. - (while (not (button-release-event-p last)) - (if (eq extent (event-glyph-extent last)) - (set-extent-property extent 'end-glyph down-glyph) - (set-extent-property extent 'end-glyph up-glyph)) - (setq last (read-event event))) - ;; Release glyph. - (when down-glyph - (set-extent-property extent 'end-glyph up-glyph)) - ;; Apply widget action. - (when (eq extent (event-glyph-extent last)) - (let ((widget (glyph-property (event-glyph event) 'widget))) - (cond ((null widget) - (message "You clicked on a glyph.")) - ((not (widget-apply widget :active)) - (message "This glyph is inactive.")) - (t - (widget-apply-action widget event))))))) + (if (widget-event-point event) + (save-excursion + (mouse-set-point event) + (let* ((pos (widget-event-point event)) + (button (get-char-property pos 'button))) + (if button + (let* ((overlay (widget-get button :button-overlay)) + (face (overlay-get overlay 'face)) + (mouse-face (overlay-get overlay 'mouse-face))) + (unwind-protect + (let ((track-mouse t)) + (save-excursion + (when face ; avoid changing around image + (overlay-put overlay + 'face widget-button-pressed-face) + (overlay-put overlay + 'mouse-face widget-button-pressed-face)) + (unless (widget-apply button :mouse-down-action event) + (while (not (widget-button-release-event-p event)) + (setq event (read-event) + pos (widget-event-point event)) + (if (and pos + (eq (get-char-property pos 'button) + button)) + (when face + (overlay-put overlay + 'face + widget-button-pressed-face) + (overlay-put overlay + 'mouse-face + widget-button-pressed-face)) + (overlay-put overlay 'face face) + (overlay-put overlay 'mouse-face mouse-face)))) + (when (and pos + (eq (get-char-property pos 'button) button)) + (widget-apply-action button event)))) + (overlay-put overlay 'face face) + (overlay-put overlay 'mouse-face mouse-face))) + (let ((up t) + command) + ;; Find the global command to run, and check whether it + ;; is bound to an up event. + (if (memq (event-basic-type event) '(mouse-1 down-mouse-1)) + (cond ((setq command ;down event + (lookup-key widget-global-map [down-mouse-1])) + (setq up nil)) + ((setq command ;up event + (lookup-key widget-global-map [mouse-1])))) + (cond ((setq command ;down event + (lookup-key widget-global-map [down-mouse-2])) + (setq up nil)) + ((setq command ;up event + (lookup-key widget-global-map [mouse-2]))))) + (when up + ;; Don't execute up events twice. + (while (not (widget-button-release-event-p event)) + (setq event (read-event)))) + (when command + (call-interactively command))))) + (unless (pos-visible-in-window-p (widget-event-point event)) + (mouse-set-point event) + (beginning-of-line) + (recenter))) + (message "You clicked somewhere weird."))) (defun widget-button-press (pos &optional event) "Invoke button at POS." @@ -1009,16 +891,14 @@ POS defaults to the value of (point)." (unless pos (setq pos (point))) - (let ((widget (or (get-char-property (point) 'button) - (get-char-property (point) 'field)))) + (let ((widget (or (get-char-property pos 'button) + (get-char-property pos 'field)))) (if widget (let ((order (widget-get widget :tab-order))) (if order (if (>= order 0) - widget - nil) - widget)) - nil))) + widget) + widget))))) (defvar widget-use-overlay-change t "If non-nil, use overlay change functions to tab around in the buffer. @@ -1089,9 +969,7 @@ (interactive) (let* ((field (widget-field-find (point))) (start (and field (widget-field-start field))) - (bol (save-excursion - (beginning-of-line) - (point)))) + (bol (line-beginning-position))) (goto-char (if start (max start bol) bol)))) @@ -1101,9 +979,7 @@ (interactive) (let* ((field (widget-field-find (point))) (end (and field (widget-field-end field))) - (eol (save-excursion - (end-of-line) - (point)))) + (eol (line-end-position))) (goto-char (if end (min end eol) eol)))) @@ -1155,7 +1031,7 @@ widget-field-list (cons field widget-field-list)) (let ((from (car (widget-get field :field-overlay))) (to (cdr (widget-get field :field-overlay)))) - (widget-specify-field field + (widget-specify-field field (marker-position from) (marker-position to)) (set-marker from nil) (set-marker to nil)))) @@ -1233,7 +1109,7 @@ (add-hook 'after-change-functions 'widget-after-change nil t)) (defun widget-after-change (from to old) - ;; Adjust field size and text properties. + "Adjust field size and text properties." (condition-case nil (let ((field (widget-field-find from)) (other (widget-field-find to))) @@ -1241,7 +1117,7 @@ (unless (eq field other) (debug "Change in different fields")) (let ((size (widget-get field :size))) - (when size + (when size (let ((begin (widget-field-start field)) (end (widget-field-end field))) (cond ((< (- end begin) size) @@ -1268,7 +1144,7 @@ ;;; Widget Functions ;; -;; These functions are used in the definition of multiple widgets. +;; These functions are used in the definition of multiple widgets. (defun widget-parent-action (widget &optional event) "Tell :parent of WIDGET to handle the :action. @@ -1277,9 +1153,9 @@ (defun widget-children-value-delete (widget) "Delete all :children and :buttons in WIDGET." - (mapcar 'widget-delete (widget-get widget :children)) + (mapc 'widget-delete (widget-get widget :children)) (widget-put widget :children nil) - (mapcar 'widget-delete (widget-get widget :buttons)) + (mapc 'widget-delete (widget-get widget :buttons)) (widget-put widget :buttons nil)) (defun widget-children-validate (widget) @@ -1300,7 +1176,7 @@ (defun widget-value-convert-widget (widget) "Initialize :value from :args in WIDGET." (let ((args (widget-get widget :args))) - (when args + (when args (widget-put widget :value (car args)) ;; Don't convert :value here, as this is done in `widget-convert'. ;; (widget-put widget :value (widget-apply widget @@ -1320,7 +1196,7 @@ :value-to-external (lambda (widget value) value) :button-prefix 'widget-button-prefix :button-suffix 'widget-button-suffix - :complete 'widget-default-complete + :complete 'widget-default-complete :create 'widget-default-create :indent nil :offset 0 @@ -1362,7 +1238,7 @@ (let ((escape (aref (match-string 1) 0))) (replace-match "" t t) (cond ((eq escape ?%) - (insert "%")) + (insert ?%)) ((eq escape ?\[) (setq button-begin (point)) (insert (widget-get-indirect widget :button-prefix))) @@ -1375,18 +1251,18 @@ (setq sample-end (point))) ((eq escape ?n) (when (widget-get widget :indent) - (insert "\n") + (insert ?\n) (insert-char ? (widget-get widget :indent)))) ((eq escape ?t) - (let ((glyph (widget-get widget :tag-glyph)) + (let ((image (widget-get widget :tag-glyph)) (tag (widget-get widget :tag))) - (cond (glyph - (widget-glyph-insert widget (or tag "image") glyph)) + (cond (image + (widget-image-insert widget (or tag "image") image)) (tag (insert tag)) (t - (let ((standard-output (current-buffer))) - (princ (widget-get widget :value))))))) + (princ (widget-get widget :value) + (current-buffer)))))) ((eq escape ?d) (let ((doc (widget-get widget :doc))) (when doc @@ -1394,13 +1270,13 @@ (insert doc) (while (eq (preceding-char) ?\n) (delete-backward-char 1)) - (insert "\n") + (insert ?\n) (setq doc-end (point))))) ((eq escape ?v) (if (and button-begin (not button-end)) (widget-apply widget :value-create) (setq value-pos (point)))) - (t + (t (widget-apply widget :format-handler escape))))) ;; Specify button, sample, and doc, and insert value. (and button-begin button-end @@ -1427,7 +1303,7 @@ (let* ((doc-property (widget-get widget :documentation-property)) (doc-try (cond ((widget-get widget :doc)) ((symbolp doc-property) - (documentation-property + (documentation-property (widget-get widget :value) doc-property)) (t @@ -1456,7 +1332,7 @@ (t 0)) doc-text) buttons)))) - (t + (t (error "Unknown escape `%c'" escape))) (widget-put widget :buttons buttons))) @@ -1473,7 +1349,7 @@ (widget-get widget :sample-face)) (defun widget-default-delete (widget) - ;; Remove widget from the buffer. + "Remove widget from the buffer." (let ((from (widget-get widget :from)) (to (widget-get widget :to)) (inactive-overlay (widget-get widget :inactive)) @@ -1500,7 +1376,7 @@ (widget-clear-undo)) (defun widget-default-value-set (widget value) - ;; Recreate widget with new value. + "Recreate widget with new value." (let* ((old-pos (point)) (from (copy-marker (widget-get widget :from))) (to (copy-marker (widget-get widget :to))) @@ -1509,7 +1385,7 @@ (- old-pos to 1) (- old-pos from))))) ;;??? Bug: this ought to insert the new value before deleting the old one, - ;; so that markers on either side of the value automatically + ;; so that markers on either side of the value automatically ;; stay on the same side. -- rms. (save-excursion (goto-char (widget-get widget :from)) @@ -1522,17 +1398,17 @@ (goto-char (min (+ from offset) (1- (widget-get widget :to)))))))) (defun widget-default-value-inline (widget) - ;; Wrap value in a list unless it is inline. + "Wrap value in a list unless it is inline." (if (widget-get widget :inline) (widget-value widget) (list (widget-value widget)))) (defun widget-default-default-get (widget) - ;; Get `:value'. + "Get `:value'." (widget-get widget :value)) (defun widget-default-menu-tag-get (widget) - ;; Use tag or value for menus. + "Use tag or value for menus." (or (widget-get widget :menu-tag) (widget-get widget :tag) (widget-princ-to-string (widget-get widget :value)))) @@ -1552,21 +1428,21 @@ (widget-get widget :to))) (defun widget-default-action (widget &optional event) - ;; Notify the parent when a widget change + "Notify the parent when a widget changes." (let ((parent (widget-get widget :parent))) (when parent (widget-apply parent :notify widget event)))) (defun widget-default-notify (widget child &optional event) - ;; Pass notification to parent. + "Pass notification to parent." (widget-default-action widget event)) (defun widget-default-prompt-value (widget prompt value unbound) - ;; Read an arbitrary value. Stolen from `set-variable'. -;; (let ((initial (if unbound -;; nil -;; ;; It would be nice if we could do a `(cons val 1)' here. -;; (prin1-to-string (custom-quote value)))))) + "Read an arbitrary value. Stolen from `set-variable'." +;; (let ((initial (if unbound +nil +;; It would be nice if we could do a `(cons val 1)' here. +;; (prin1-to-string (custom-quote value)))))) (eval-minibuffer prompt )) ;;; The `item' Widget. @@ -1583,9 +1459,8 @@ :format "%t\n") (defun widget-item-value-create (widget) - ;; Insert the printed representation of the value. - (let ((standard-output (current-buffer))) - (princ (widget-get widget :value)))) + "Insert the printed representation of the value." + (princ (widget-get widget :value) (current-buffer))) (defun widget-item-match (widget value) ;; Match if the value is the same. @@ -1605,8 +1480,7 @@ If END is omitted, it defaults to the length of LIST." (if (> start 0) (setq list (nthcdr start list))) (if end - (if (<= end start) - nil + (unless (<= end start) (setq list (copy-sequence list)) (setcdr (nthcdr (- end start 1) list) nil) list) @@ -1644,7 +1518,7 @@ :format "%[%v%]") (defun widget-push-button-value-create (widget) - ;; Insert text representing the `on' and `off' states. + "Insert text representing the `on' and `off' states." (let* ((tag (or (widget-get widget :tag) (widget-get widget :value))) (tag-glyph (widget-get widget :tag-glyph)) @@ -1652,26 +1526,7 @@ tag widget-push-button-suffix)) (gui (cdr (assoc tag widget-push-button-cache)))) (cond (tag-glyph - (widget-glyph-insert widget text tag-glyph)) - ((and (fboundp 'make-gui-button) - (fboundp 'make-glyph) - widget-push-button-gui - (fboundp 'device-on-window-system-p) - (device-on-window-system-p) - (string-match "XEmacs" emacs-version)) - (unless gui - (setq gui (make-gui-button tag 'widget-gui-action widget)) - (push (cons tag gui) widget-push-button-cache)) - (widget-glyph-insert-glyph widget - (make-glyph - (list (nth 0 (aref gui 1)) - (vector 'string ':data text))) - (make-glyph - (list (nth 1 (aref gui 1)) - (vector 'string ':data text))) - (make-glyph - (list (nth 2 (aref gui 1)) - (vector 'string ':data text))))) + (widget-image-insert widget text tag-glyph)) (t (insert text))))) @@ -1792,13 +1647,13 @@ "History of field minibuffer edits.") (defun widget-field-prompt-internal (widget prompt initial history) - ;; Read string for WIDGET promptinhg with PROMPT. - ;; INITIAL is the initial input and HISTORY is a symbol containing - ;; the earlier input. + "Read string for WIDGET promptinhg with PROMPT. +INITIAL is the initial input and HISTORY is a symbol containing +the earlier input." (read-string prompt initial history)) (defun widget-field-prompt-value (widget prompt value unbound) - ;; Prompt for a string. + "Prompt for a string." (let ((initial (if unbound nil (cons (widget-apply widget :value-to-internal @@ -1811,12 +1666,12 @@ (defvar widget-edit-functions nil) (defun widget-field-action (widget &optional event) - ;; Move to next field. + "Move to next field." (widget-forward 1) (run-hook-with-args 'widget-edit-functions widget)) (defun widget-field-validate (widget) - ;; Valid if the content matches `:valid-regexp'. + "Valid if the content matches `:valid-regexp'." (save-excursion (let ((value (widget-apply widget :value-get)) (regexp (widget-get widget :valid-regexp))) @@ -1825,13 +1680,13 @@ widget)))) (defun widget-field-value-create (widget) - ;; Create an editable text field. + "Create an editable text field." (let ((size (widget-get widget :size)) (value (widget-get widget :value)) (from (point)) ;; This is changed to a real overlay in `widget-setup'. We ;; need the end points to behave differently until - ;; `widget-setup' is called. + ;; `widget-setup' is called. (overlay (cons (make-marker) (make-marker)))) (widget-put widget :field-overlay overlay) (insert value) @@ -1848,7 +1703,7 @@ (set-marker-insertion-type (car overlay) t))) (defun widget-field-value-delete (widget) - ;; Remove the widget from the list of active editing fields. + "Remove the widget from the list of active editing fields." (setq widget-field-list (delq widget widget-field-list)) ;; These are nil if the :format string doesn't contain `%v'. (let ((overlay (widget-get widget :field-overlay))) @@ -1856,7 +1711,7 @@ (delete-overlay overlay)))) (defun widget-field-value-get (widget) - ;; Return current text in editing field. + "Return current text in editing field." (let ((from (widget-field-start widget)) (to (widget-field-end widget)) (buffer (widget-field-buffer widget)) @@ -1864,7 +1719,7 @@ (secret (widget-get widget :secret)) (old (current-buffer))) (if (and from to) - (progn + (progn (set-buffer buffer) (while (and size (not (zerop size)) @@ -1914,7 +1769,7 @@ :match-inline 'widget-choice-match-inline) (defun widget-choice-value-create (widget) - ;; Insert the first choice that matches the value. + "Insert the first choice that matches the value." (let ((value (widget-get widget :value)) (args (widget-get widget :args)) (explicit (widget-get widget :explicit-choice)) @@ -2031,7 +1886,7 @@ (widget-put widget :explicit-choice current) (widget-put widget :explicit-choice-value (widget-get widget :value))) (let ((value (widget-default-get current))) - (widget-value-set widget + (widget-value-set widget (widget-apply current :value-to-external value))) (widget-setup) (widget-apply widget :notify widget event))) @@ -2078,12 +1933,12 @@ :off "off") (defun widget-toggle-value-create (widget) - ;; Insert text representing the `on' and `off' states. + "Insert text representing the `on' and `off' states." (if (widget-value widget) - (widget-glyph-insert widget - (widget-get widget :on) + (widget-image-insert widget + (widget-get widget :on) (widget-get widget :on-glyph)) - (widget-glyph-insert widget + (widget-image-insert widget (widget-get widget :off) (widget-get widget :off-glyph)))) @@ -2101,9 +1956,15 @@ :button-prefix "" :format "%[%v%]" :on "[X]" - :on-glyph "check1" + :on-glyph (create-image (make-bool-vector 49 1) + 'xbm t :width 7 :height 7 + :foreground "grey75" ; like default mode line + :relief -3 :ascent 'center) :off "[ ]" - :off-glyph "check0" + :off-glyph (create-image (make-bool-vector 49 1) + 'xbm t :width 7 :height 7 + :foreground "grey75" + :relief 3 :ascent 'center) :help-echo "Toggle this item." :action 'widget-checkbox-action) @@ -2137,18 +1998,18 @@ ;; Insert all values (let ((alist (widget-checklist-match-find widget (widget-get widget :value))) (args (widget-get widget :args))) - (while args + (while args (widget-checklist-add-item widget (car args) (assq (car args) alist)) (setq args (cdr args))) (widget-put widget :children (nreverse (widget-get widget :children))))) (defun widget-checklist-add-item (widget type chosen) - ;; Create checklist item in WIDGET of type TYPE. - ;; If the item is checked, CHOSEN is a cons whose cdr is the value. + "Create checklist item in WIDGET of type TYPE. +If the item is checked, CHOSEN is a cons whose cdr is the value." (and (eq (preceding-char) ?\n) (widget-get widget :indent) (insert-char ? (widget-get widget :indent))) - (widget-specify-insert + (widget-specify-insert (let* ((children (widget-get widget :children)) (buttons (widget-get widget :buttons)) (button-args (or (widget-get type :sibling-args) @@ -2162,7 +2023,7 @@ (let ((escape (aref (match-string 1) 0))) (replace-match "" t t) (cond ((eq escape ?%) - (insert "%")) + (insert ?%)) ((eq escape ?b) (setq button (apply 'widget-create-child-and-convert widget 'checkbox @@ -2180,7 +2041,7 @@ (t (widget-create-child-value widget type (car (cdr chosen))))))) - (t + (t (error "Unknown escape `%c'" escape))))) ;; Update properties. (and button child (widget-put child :button button)) @@ -2199,7 +2060,7 @@ found rest) (while values (let ((answer (widget-checklist-match-up args values))) - (cond (answer + (cond (answer (let ((vals (widget-match-inline answer values))) (setq found (append found (car vals)) values (cdr vals) @@ -2207,46 +2068,45 @@ (greedy (setq rest (append rest (list (car values))) values (cdr values))) - (t + (t (setq rest (append rest values) values nil))))) (cons found rest))) (defun widget-checklist-match-find (widget vals) - ;; Find the vals which match a type in the checklist. - ;; Return an alist of (TYPE MATCH). + "Find the vals which match a type in the checklist. +Return an alist of (TYPE MATCH)." (let ((greedy (widget-get widget :greedy)) (args (copy-sequence (widget-get widget :args))) found) (while vals (let ((answer (widget-checklist-match-up args vals))) - (cond (answer + (cond (answer (let ((match (widget-match-inline answer vals))) (setq found (cons (cons answer (car match)) found) vals (cdr match) args (delq answer args)))) (greedy (setq vals (cdr vals))) - (t + (t (setq vals nil))))) found)) (defun widget-checklist-match-up (args vals) - ;; Rerturn the first type from ARGS that matches VALS. + "Return the first type from ARGS that matches VALS." (let (current found) (while (and args (null found)) (setq current (car args) args (cdr args) found (widget-match-inline current vals))) (if found - current - nil))) + current))) (defun widget-checklist-value-get (widget) ;; The values of all selected items. (let ((children (widget-get widget :children)) child result) - (while children + (while children (setq child (car children) children (cdr children)) (if (widget-value (widget-get child :button)) @@ -2319,7 +2179,7 @@ ;; Insert all values (let ((args (widget-get widget :args)) arg) - (while args + (while args (setq arg (car args) args (cdr args)) (widget-radio-add-item widget arg)))) @@ -2330,7 +2190,7 @@ (and (eq (preceding-char) ?\n) (widget-get widget :indent) (insert-char ? (widget-get widget :indent))) - (widget-specify-insert + (widget-specify-insert (let* ((value (widget-get widget :value)) (children (widget-get widget :children)) (buttons (widget-get widget :buttons)) @@ -2347,10 +2207,10 @@ (let ((escape (aref (match-string 1) 0))) (replace-match "" t t) (cond ((eq escape ?%) - (insert "%")) + (insert ?%)) ((eq escape ?b) (setq button (apply 'widget-create-child-and-convert - widget 'radio-button + widget 'radio-button :value (not (null chosen)) button-args))) ((eq escape ?v) @@ -2358,14 +2218,14 @@ (widget-create-child-value widget type value) (widget-create-child widget type))) - (unless chosen + (unless chosen (widget-apply child :deactivate))) - (t + (t (error "Unknown escape `%c'" escape))))) ;; Update properties. (when chosen (widget-put widget :choice type)) - (when button + (when button (widget-put child :button button) (widget-put widget :buttons (nconc buttons (list button)))) (when child @@ -2418,8 +2278,8 @@ (match (and (not found) (widget-apply current :match value)))) (widget-value-set button match) - (if match - (progn + (if match + (progn (widget-value-set current value) (widget-apply current :activate)) (widget-apply current :deactivate)) @@ -2467,7 +2327,7 @@ (defun widget-insert-button-action (widget &optional event) ;; Ask the parent to insert a new item. - (widget-apply (widget-get widget :parent) + (widget-apply (widget-get widget :parent) :insert-before (widget-get widget :widget))) ;;; The `delete-button' Widget. @@ -2480,7 +2340,7 @@ (defun widget-delete-button-action (widget &optional event) ;; Ask the parent to insert a new item. - (widget-apply (widget-get widget :parent) + (widget-apply (widget-get widget :parent) :delete-at (widget-get widget :widget))) ;;; The `editable-list' Widget. @@ -2513,10 +2373,10 @@ (cond ((eq escape ?i) (and (widget-get widget :indent) (insert-char ? (widget-get widget :indent))) - (apply 'widget-create-child-and-convert + (apply 'widget-create-child-and-convert widget 'insert-button (widget-get widget :append-button-args))) - (t + (t (widget-default-format-handler widget escape))))) (defun widget-editable-list-value-create (widget) @@ -2557,7 +2417,7 @@ found) (while (and value ok) (let ((answer (widget-match-inline type value))) - (if answer + (if answer (setq found (append found (car answer)) value (cdr answer)) (setq ok nil)))) @@ -2570,11 +2430,11 @@ (inhibit-read-only t) before-change-functions after-change-functions) - (cond (before + (cond (before (goto-char (widget-get before :entry-from))) (t (goto-char (widget-get widget :value-pos)))) - (let ((child (widget-editable-list-entry-create + (let ((child (widget-editable-list-entry-create widget nil nil))) (when (< (widget-get child :entry-from) (widget-get widget :from)) (set-marker (widget-get widget :from) @@ -2620,7 +2480,7 @@ (let ((type (nth 0 (widget-get widget :args))) (widget-push-button-gui widget-editable-list-gui) child delete insert) - (widget-specify-insert + (widget-specify-insert (save-excursion (and (widget-get widget :indent) (insert-char ? (widget-get widget :indent))) @@ -2630,7 +2490,7 @@ (let ((escape (aref (match-string 1) 0))) (replace-match "" t t) (cond ((eq escape ?%) - (insert "%")) + (insert ?%)) ((eq escape ?i) (setq insert (apply 'widget-create-child-and-convert widget 'insert-button @@ -2641,16 +2501,16 @@ (widget-get widget :delete-button-args)))) ((eq escape ?v) (if conv - (setq child (widget-create-child-value + (setq child (widget-create-child-value widget type value)) - (setq child (widget-create-child-value + (setq child (widget-create-child-value widget type (widget-apply type :value-to-external (widget-default-get type)))))) - (t + (t (error "Unknown escape `%c'" escape))))) - (widget-put widget - :buttons (cons delete + (widget-put widget + :buttons (cons delete (cons insert (widget-get widget :buttons)))) (let ((entry-from (copy-marker (point-min))) @@ -2717,14 +2577,13 @@ (setq argument (car args) args (cdr args) answer (widget-match-inline argument vals)) - (if answer + (if answer (setq vals (cdr answer) found (append found (car answer))) (setq vals nil args nil))) (if answer - (cons found vals) - nil))) + (cons found vals)))) ;;; The `visibility' Widget. @@ -2754,8 +2613,8 @@ widget-push-button-suffix)) (setq off "")) (if (widget-value widget) - (widget-glyph-insert widget on "down" "down-pushed") - (widget-glyph-insert widget off "right" "right-pushed")))) + (widget-image-insert widget on "down" "down-pushed") + (widget-image-insert widget off "right" "right-pushed")))) ;;; The `documentation-link' Widget. ;; @@ -2764,13 +2623,9 @@ (define-widget 'documentation-link 'link "Link type used in documentation strings." :tab-order -1 - :help-echo 'widget-documentation-link-echo-help + :help-echo "Describe this symbol" :action 'widget-documentation-link-action) -(defun widget-documentation-link-echo-help (widget) - "Tell what this link will describe." - (concat "Describe the `" (widget-get widget :value) "' symbol.")) - (defun widget-documentation-link-action (widget &optional event) "Display documentation for WIDGET's value. Ignore optional argument EVENT." (let* ((string (widget-get widget :value)) @@ -2829,7 +2684,7 @@ (widget-put widget :buttons buttons))) (let ((indent (widget-get widget :indent))) (when (and indent (not (zerop indent))) - (save-excursion + (save-excursion (save-restriction (narrow-to-region from to) (goto-char (point-min)) @@ -2855,7 +2710,7 @@ (let ((before (substring doc 0 (match-beginning 0))) (after (substring doc (match-beginning 0))) buttons) - (insert before " ") + (insert before ?\ ) (widget-documentation-link-add widget start (point)) (push (widget-create-child-and-convert widget 'visibility @@ -2874,12 +2729,12 @@ (widget-put widget :buttons buttons)) (insert doc) (widget-documentation-link-add widget start (point)))) - (insert "\n")) + (insert ?\n)) (defun widget-documentation-string-action (widget &rest ignore) ;; Toggle documentation. (let ((parent (widget-get widget :parent))) - (widget-put parent :documentation-shown + (widget-put parent :documentation-shown (not (widget-get parent :documentation-shown)))) ;; Redraw. (widget-value-set widget (widget-value widget))) @@ -2955,7 +2810,7 @@ widget)))) (define-widget 'file 'string - "A file widget. + "A file widget. It will read a file name from the minibuffer when invoked." :complete-function 'widget-file-complete :prompt-value 'widget-file-prompt-value @@ -3015,7 +2870,7 @@ ;;; (widget-apply widget :notify widget event))) (define-widget 'directory 'file - "A directory widget. + "A directory widget. It will read a directory name from the minibuffer when invoked." :tag "Directory") @@ -3043,7 +2898,7 @@ (defun widget-symbol-prompt-internal (widget prompt initial history) ;; Read file from minibuffer. - (let ((answer (completing-read prompt obarray + (let ((answer (completing-read prompt obarray (widget-get widget :prompt-match) nil initial history))) (if (and (stringp answer) @@ -3089,10 +2944,8 @@ ;; Read coding-system from minibuffer. (intern (completing-read (format "%s (default %s) " prompt value) - (mapcar (function - (lambda (sym) - (list (symbol-name sym)) - )) + (mapcar (lambda (sym) + (list (symbol-name sym))) (coding-system-list))))) (defun widget-coding-system-action (widget &optional event) @@ -3167,16 +3020,11 @@ (let ((found (read-string prompt (if unbound nil (cons (prin1-to-string value) 0)) (widget-get widget :prompt-history)))) - (save-excursion - (let ((buffer (set-buffer (get-buffer-create " *Widget Scratch*")))) - (erase-buffer) - (insert found) - (goto-char (point-min)) - (let ((answer (read buffer))) - (unless (eobp) - (error "Junk at end of expression: %s" - (buffer-substring (point) (point-max)))) - answer))))) + (let ((answer (read-from-string found))) + (unless (= (cdr answer) (length found)) + (error "Junk at end of expression: %s" + (substring found (cdr answer)))) + (car answer)))) (define-widget 'restricted-sexp 'sexp "A Lisp expression restricted to values that match. @@ -3219,12 +3067,12 @@ "A character." :tag "Character" :value 0 - :size 1 + :size 1 :format "%{%t%}: %v\n" :valid-regexp "\\`.\\'" :error "This field should contain a single character" :value-to-internal (lambda (widget value) - (if (stringp value) + (if (stringp value) value (char-to-string value))) :value-to-external (lambda (widget value) @@ -3247,7 +3095,7 @@ :value-to-internal (lambda (widget value) (append value nil)) :value-to-external (lambda (widget value) (apply 'vector value))) -(defun widget-vector-match (widget value) +(defun widget-vector-match (widget value) (and (vectorp value) (widget-group-match widget (widget-apply widget :value-to-internal value)))) @@ -3262,7 +3110,7 @@ :value-to-external (lambda (widget value) (cons (nth 0 value) (nth 1 value)))) -(defun widget-cons-match (widget value) +(defun widget-cons-match (widget value) (and (consp value) (widget-group-match widget (widget-apply widget :value-to-internal value)))) @@ -3285,7 +3133,7 @@ (let* ((options (widget-get widget :options)) (key-type (widget-get widget :key-type)) (widget-plist-value-type (widget-get widget :value-type)) - (other `(editable-list :inline t + (other `(editable-list :inline t (group :inline t ,key-type ,widget-plist-value-type))) @@ -3331,7 +3179,7 @@ (let* ((options (widget-get widget :options)) (key-type (widget-get widget :key-type)) (widget-alist-value-type (widget-get widget :value-type)) - (other `(editable-list :inline t + (other `(editable-list :inline t (cons :format "%v" ,key-type ,widget-alist-value-type))) @@ -3367,7 +3215,7 @@ :prompt-value 'widget-choice-prompt-value) (defun widget-choice-prompt-value (widget prompt value unbound) - "Make a choice." + "Make a choice." (let ((args (widget-get widget :args)) (completion-ignore-case (widget-get widget :case-fold)) current choices old) @@ -3440,7 +3288,7 @@ ;;; The `color' Widget. -(define-widget 'color 'editable-field +(define-widget 'color 'editable-field "Choose a color name (with sample)." :format "%t: %v (%{sample%})\n" :size 10 @@ -3501,7 +3349,7 @@ (defun widget-color-notify (widget child &optional event) "Update the sample, and notofy the parent." - (overlay-put (widget-get widget :sample-overlay) + (overlay-put (widget-get widget :sample-overlay) 'face (widget-apply widget :sample-face-get)) (widget-default-notify widget child event)) @@ -3516,11 +3364,10 @@ "Display the help echo for widget at POS." (let* ((widget (widget-at pos)) (help-echo (and widget (widget-get widget :help-echo)))) - (cond ((stringp help-echo) - (message "%s" help-echo)) - ((and (symbolp help-echo) (fboundp help-echo) - (stringp (setq help-echo (funcall help-echo widget)))) - (message "%s" help-echo))))) + (if (or (stringp help-echo) + (and (symbolp help-echo) (fboundp help-echo) + (stringp (setq help-echo (funcall help-echo widget))))) + (message "%s" help-echo)))) ;;; The End: