1
0
mirror of https://git.savannah.gnu.org/git/emacs.git synced 2024-11-22 07:09:54 +00:00

Further improve button.el support for help-echo

The last change to forward-button added support for help-echo values
that are functions.  This patch fixes the arguments passed to such
functions and further adds support for help-echo values that are
forms (bug#37515).
* doc/lispref/display.texi (Button Properties): Fix description of
help-echo button property.
* lisp/button.el (button--help-echo): New function.
(forward-button): Use it.
(backward-button): Clarify help-echo reference in docstring.
* test/lisp/button-tests.el (button--help-echo-string)
(button--help-echo-form, button--help-echo-function): New tests.
This commit is contained in:
Basil L. Contovounesios 2019-09-27 00:04:33 +01:00
parent 660d509acd
commit 0fc8177414
3 changed files with 86 additions and 15 deletions

View File

@ -6607,14 +6607,23 @@ in the variable @code{button-map}, which defines @key{RET} and
The button type. @xref{Button Types}.
@item help-echo
@kindex help-index @r{(button property)}
A string displayed by the Emacs tool-tip help system; by default,
@code{"mouse-2, RET: Push this button"}.
@kindex help-echo @r{(button property)}
A string displayed by the Emacs tooltip help system; by default,
@code{"mouse-2, RET: Push this button"}. Alternatively, a function
that returns, or a form that evaluates to, a string to be displayed or
@code{nil}. For details see @ref{Text help-echo}.
The function is called with three arguments, @var{window},
@var{object}, and @var{pos}. The second argument, @var{object}, is
either the overlay that had the property (for overlay buttons), or the
buffer containing the button (for text property buttons). The other
arguments have the same meaning as for the special text property
@code{help-echo}.
@item follow-link
@kindex follow-link @r{(button property)}
The follow-link property, defining how a @key{mouse-1} click behaves
on this button, @xref{Clickable Text}.
The @code{follow-link} property, defining how a @key{mouse-1} click
behaves on this button, @xref{Clickable Text}.
@item button
@kindex button @r{(button property)}

View File

@ -467,13 +467,22 @@ return t."
(button-activate button use-mouse-action)
t))))
(defun button--help-echo (button)
"Evaluate BUTTON's `help-echo' property and return its value."
(let ((help (button-get button 'help-echo)))
(if (functionp help)
(let ((obj (if (overlayp button) button (current-buffer))))
(funcall help (selected-window) obj (button-start button)))
(eval help lexical-binding))))
(defun forward-button (n &optional wrap display-message no-error)
"Move to the Nth next button, or Nth previous button if N is negative.
If N is 0, move to the start of any button at point.
If WRAP is non-nil, moving past either end of the buffer continues from the
other end.
If DISPLAY-MESSAGE is non-nil, the button's help-echo string is displayed.
Any button with a non-nil `skip' property is skipped over.
If DISPLAY-MESSAGE is non-nil, the button's `help-echo' property
is displayed. Any button with a non-nil `skip' property is
skipped over.
If NO-ERROR, return nil if no further buttons could be found
instead of erroring out.
@ -506,13 +515,9 @@ Returns the button found."
(unless (button-get button 'skip)
(setq n (1- n)))))))
(if (null button)
(if no-error
nil
(unless no-error
(user-error (if wrap "No buttons!" "No more buttons")))
(let ((msg (and display-message (button-get button 'help-echo))))
(when (functionp msg)
(setq msg (funcall msg (selected-window) (current-buffer)
(button-start button))))
(let ((msg (and display-message (button--help-echo button))))
(when msg
(message "%s" msg)))
button)))
@ -522,8 +527,9 @@ Returns the button found."
If N is 0, move to the start of any button at point.
If WRAP is non-nil, moving past either end of the buffer continues from the
other end.
If DISPLAY-MESSAGE is non-nil, the button's help-echo string is displayed.
Any button with a non-nil `skip' property is skipped over.
If DISPLAY-MESSAGE is non-nil, the button's `help-echo' property
is displayed. Any button with a non-nil `skip' property is
skipped over.
If NO-ERROR, return nil if no further buttons could be found
instead of erroring out.

View File

@ -37,4 +37,60 @@
(widget-create 'link "link widget")
(should-not (button-at (1- (point))))))
(ert-deftest button--help-echo-string ()
"Test `button--help-echo' with strings."
(with-temp-buffer
;; Text property buttons.
(let ((button (insert-text-button "text" 'help-echo "text help")))
(should (equal (button--help-echo button) "text help")))
;; Overlay buttons.
(let ((button (insert-button "overlay" 'help-echo "overlay help")))
(should (equal (button--help-echo button) "overlay help")))))
(ert-deftest button--help-echo-form ()
"Test `button--help-echo' with forms."
(with-temp-buffer
;; Test text property buttons with dynamic scoping.
(let* ((help (make-symbol "help"))
(form `(funcall (let ((,help "lexical form"))
(lambda () ,help))))
(button (insert-text-button "text" 'help-echo form)))
(set help "dynamic form")
(should (equal (button--help-echo button) "dynamic form")))
;; Test overlay buttons with lexical scoping.
(setq lexical-binding t)
(let* ((help (make-symbol "help"))
(form `(funcall (let ((,help "lexical form"))
(lambda () ,help))))
(button (insert-button "overlay" 'help-echo form)))
(set help "dynamic form")
(should (equal (button--help-echo button) "lexical form")))))
(ert-deftest button--help-echo-function ()
"Test `button--help-echo' with functions."
(with-temp-buffer
;; Text property buttons.
(let* ((owin (selected-window))
(obuf (current-buffer))
(opos (point))
(help (lambda (win obj pos)
(should (eq win owin))
(should (eq obj obuf))
(should (= pos opos))
"text function"))
(button (insert-text-button "text" 'help-echo help)))
(should (equal (button--help-echo button) "text function"))
;; Overlay buttons.
(setq help (lambda (win obj pos)
(should (eq win owin))
(should (overlayp obj))
(should (eq obj button))
(should (eq (overlay-buffer obj) obuf))
(should (= (overlay-start obj) opos))
(should (= pos opos))
"overlay function"))
(setq opos (point))
(setq button (insert-button "overlay" 'help-echo help))
(should (equal (button--help-echo button) "overlay function")))))
;;; button-tests.el ends here