aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBasil L. Contovounesios2019-09-27 00:04:33 +0100
committerBasil L. Contovounesios2019-10-03 23:05:14 +0100
commit0fc8177414801e428ca184e8a9ba8b79a291c15a (patch)
tree7ed7df57104eee1e0beaa6074efba73670adf3b0
parent660d509acd9da23d9795b5aaa12a5453e6c61bbd (diff)
downloademacs-0fc8177414801e428ca184e8a9ba8b79a291c15a.tar.gz
emacs-0fc8177414801e428ca184e8a9ba8b79a291c15a.zip
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.
-rw-r--r--doc/lispref/display.texi19
-rw-r--r--lisp/button.el26
-rw-r--r--test/lisp/button-tests.el56
3 files changed, 86 insertions, 15 deletions
diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi
index 494bf0d3f7e..61bd4ce8830 100644
--- a/doc/lispref/display.texi
+++ b/doc/lispref/display.texi
@@ -6607,14 +6607,23 @@ in the variable @code{button-map}, which defines @key{RET} and
6607The button type. @xref{Button Types}. 6607The button type. @xref{Button Types}.
6608 6608
6609@item help-echo 6609@item help-echo
6610@kindex help-index @r{(button property)} 6610@kindex help-echo @r{(button property)}
6611A string displayed by the Emacs tool-tip help system; by default, 6611A string displayed by the Emacs tooltip help system; by default,
6612@code{"mouse-2, RET: Push this button"}. 6612@code{"mouse-2, RET: Push this button"}. Alternatively, a function
6613that returns, or a form that evaluates to, a string to be displayed or
6614@code{nil}. For details see @ref{Text help-echo}.
6615
6616The function is called with three arguments, @var{window},
6617@var{object}, and @var{pos}. The second argument, @var{object}, is
6618either the overlay that had the property (for overlay buttons), or the
6619buffer containing the button (for text property buttons). The other
6620arguments have the same meaning as for the special text property
6621@code{help-echo}.
6613 6622
6614@item follow-link 6623@item follow-link
6615@kindex follow-link @r{(button property)} 6624@kindex follow-link @r{(button property)}
6616The follow-link property, defining how a @key{mouse-1} click behaves 6625The @code{follow-link} property, defining how a @key{mouse-1} click
6617on this button, @xref{Clickable Text}. 6626behaves on this button, @xref{Clickable Text}.
6618 6627
6619@item button 6628@item button
6620@kindex button @r{(button property)} 6629@kindex button @r{(button property)}
diff --git a/lisp/button.el b/lisp/button.el
index 32efc2f95be..04e77ca904f 100644
--- a/lisp/button.el
+++ b/lisp/button.el
@@ -467,13 +467,22 @@ return t."
467 (button-activate button use-mouse-action) 467 (button-activate button use-mouse-action)
468 t)))) 468 t))))
469 469
470(defun button--help-echo (button)
471 "Evaluate BUTTON's `help-echo' property and return its value."
472 (let ((help (button-get button 'help-echo)))
473 (if (functionp help)
474 (let ((obj (if (overlayp button) button (current-buffer))))
475 (funcall help (selected-window) obj (button-start button)))
476 (eval help lexical-binding))))
477
470(defun forward-button (n &optional wrap display-message no-error) 478(defun forward-button (n &optional wrap display-message no-error)
471 "Move to the Nth next button, or Nth previous button if N is negative. 479 "Move to the Nth next button, or Nth previous button if N is negative.
472If N is 0, move to the start of any button at point. 480If N is 0, move to the start of any button at point.
473If WRAP is non-nil, moving past either end of the buffer continues from the 481If WRAP is non-nil, moving past either end of the buffer continues from the
474other end. 482other end.
475If DISPLAY-MESSAGE is non-nil, the button's help-echo string is displayed. 483If DISPLAY-MESSAGE is non-nil, the button's `help-echo' property
476Any button with a non-nil `skip' property is skipped over. 484is displayed. Any button with a non-nil `skip' property is
485skipped over.
477 486
478If NO-ERROR, return nil if no further buttons could be found 487If NO-ERROR, return nil if no further buttons could be found
479instead of erroring out. 488instead of erroring out.
@@ -506,13 +515,9 @@ Returns the button found."
506 (unless (button-get button 'skip) 515 (unless (button-get button 'skip)
507 (setq n (1- n))))))) 516 (setq n (1- n)))))))
508 (if (null button) 517 (if (null button)
509 (if no-error 518 (unless no-error
510 nil
511 (user-error (if wrap "No buttons!" "No more buttons"))) 519 (user-error (if wrap "No buttons!" "No more buttons")))
512 (let ((msg (and display-message (button-get button 'help-echo)))) 520 (let ((msg (and display-message (button--help-echo button))))
513 (when (functionp msg)
514 (setq msg (funcall msg (selected-window) (current-buffer)
515 (button-start button))))
516 (when msg 521 (when msg
517 (message "%s" msg))) 522 (message "%s" msg)))
518 button))) 523 button)))
@@ -522,8 +527,9 @@ Returns the button found."
522If N is 0, move to the start of any button at point. 527If N is 0, move to the start of any button at point.
523If WRAP is non-nil, moving past either end of the buffer continues from the 528If WRAP is non-nil, moving past either end of the buffer continues from the
524other end. 529other end.
525If DISPLAY-MESSAGE is non-nil, the button's help-echo string is displayed. 530If DISPLAY-MESSAGE is non-nil, the button's `help-echo' property
526Any button with a non-nil `skip' property is skipped over. 531is displayed. Any button with a non-nil `skip' property is
532skipped over.
527 533
528If NO-ERROR, return nil if no further buttons could be found 534If NO-ERROR, return nil if no further buttons could be found
529instead of erroring out. 535instead of erroring out.
diff --git a/test/lisp/button-tests.el b/test/lisp/button-tests.el
index d54a992ab89..44a7ea6f6e5 100644
--- a/test/lisp/button-tests.el
+++ b/test/lisp/button-tests.el
@@ -37,4 +37,60 @@
37 (widget-create 'link "link widget") 37 (widget-create 'link "link widget")
38 (should-not (button-at (1- (point)))))) 38 (should-not (button-at (1- (point))))))
39 39
40(ert-deftest button--help-echo-string ()
41 "Test `button--help-echo' with strings."
42 (with-temp-buffer
43 ;; Text property buttons.
44 (let ((button (insert-text-button "text" 'help-echo "text help")))
45 (should (equal (button--help-echo button) "text help")))
46 ;; Overlay buttons.
47 (let ((button (insert-button "overlay" 'help-echo "overlay help")))
48 (should (equal (button--help-echo button) "overlay help")))))
49
50(ert-deftest button--help-echo-form ()
51 "Test `button--help-echo' with forms."
52 (with-temp-buffer
53 ;; Test text property buttons with dynamic scoping.
54 (let* ((help (make-symbol "help"))
55 (form `(funcall (let ((,help "lexical form"))
56 (lambda () ,help))))
57 (button (insert-text-button "text" 'help-echo form)))
58 (set help "dynamic form")
59 (should (equal (button--help-echo button) "dynamic form")))
60 ;; Test overlay buttons with lexical scoping.
61 (setq lexical-binding t)
62 (let* ((help (make-symbol "help"))
63 (form `(funcall (let ((,help "lexical form"))
64 (lambda () ,help))))
65 (button (insert-button "overlay" 'help-echo form)))
66 (set help "dynamic form")
67 (should (equal (button--help-echo button) "lexical form")))))
68
69(ert-deftest button--help-echo-function ()
70 "Test `button--help-echo' with functions."
71 (with-temp-buffer
72 ;; Text property buttons.
73 (let* ((owin (selected-window))
74 (obuf (current-buffer))
75 (opos (point))
76 (help (lambda (win obj pos)
77 (should (eq win owin))
78 (should (eq obj obuf))
79 (should (= pos opos))
80 "text function"))
81 (button (insert-text-button "text" 'help-echo help)))
82 (should (equal (button--help-echo button) "text function"))
83 ;; Overlay buttons.
84 (setq help (lambda (win obj pos)
85 (should (eq win owin))
86 (should (overlayp obj))
87 (should (eq obj button))
88 (should (eq (overlay-buffer obj) obuf))
89 (should (= (overlay-start obj) opos))
90 (should (= pos opos))
91 "overlay function"))
92 (setq opos (point))
93 (setq button (insert-button "overlay" 'help-echo help))
94 (should (equal (button--help-echo button) "overlay function")))))
95
40;;; button-tests.el ends here 96;;; button-tests.el ends here