From f23ee932509e0a67aaafc499f0cd6b25535e4b95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Le=20Gouguec?= Date: Thu, 20 Feb 2025 22:37:13 +0100 Subject: [PATCH] Prevent button.el from clearing help-echo strings In order to fix one of the issues discussed in bug#61413, i.e. 'buttonize' clobbering the help-echo property set by 'icon-string'. This is a reasonable interpretation of the button.el docstrings - "if HELP-ECHO, use that as the `help-echo' property"; conversely, if not HELP-ECHO, then do not do anything, preserving existing values for that property. * lisp/button.el (button--properties): Only add a help-echo property if HELP-ECHO is non-nil. Add an additional property for bookkeeping. (unbuttonize-region): Check for that bookkeeping property before clearing help-echo. * test/lisp/button-tests.el (button--preserve-help-echo): Validate these changes. --- lisp/button.el | 32 +++++++++++++++++++++----------- test/lisp/button-tests.el | 28 ++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 11 deletions(-) diff --git a/lisp/button.el b/lisp/button.el index 674de1bb4fa..58f00c4c2ad 100644 --- a/lisp/button.el +++ b/lisp/button.el @@ -652,15 +652,19 @@ Also see `buttonize-region'." string)) (defun button--properties (callback data help-echo) - (list 'font-lock-face 'button - 'mouse-face 'highlight - 'help-echo help-echo - 'button t - 'follow-link t - 'category t - 'button-data data - 'keymap button-map - 'action callback)) + (append + (list 'font-lock-face 'button + 'mouse-face 'highlight + 'button t + 'follow-link t + 'category t + 'button-data data + 'keymap button-map + 'action callback) + (and help-echo + (list 'help-echo help-echo + ;; Record that button.el is responsible for this property. + 'help-echo-button t)))) (defun buttonize-region (start end callback &optional data help-echo) "Make the region between START and END into a button. @@ -681,8 +685,14 @@ This removes both text-property and overlay based buttons." (when (overlay-get o 'button) (delete-overlay o))) (with-silent-modifications - (remove-text-properties start end - (button--properties nil nil nil)) + (remove-text-properties + start end + (append + (button--properties nil nil nil) + ;; Only remove help-echo if it was added by button.el. + (and (get-text-property start 'help-echo-button) + (list 'help-echo nil + 'help-echo-button nil)))) (add-face-text-property start end 'button nil))) diff --git a/test/lisp/button-tests.el b/test/lisp/button-tests.el index 7f6a5bd52cd..b784cf02e28 100644 --- a/test/lisp/button-tests.el +++ b/test/lisp/button-tests.el @@ -101,4 +101,32 @@ (setq button (insert-button "overlay" 'help-echo help)) (should (equal (button--help-echo button) "overlay: x"))))) +(ert-deftest button--preserve-help-echo () + "Ensure buttonizing functions preserve existing `help-echo' properties." + ;; buttonize. + (let* ((string (propertize "button text" 'help-echo "help text")) + (button (buttonize string #'ignore))) + (should (equal (get-text-property 0 'help-echo button) + "help text"))) + ;; buttonize-region. + (with-temp-buffer + (insert (propertize "button text" 'help-echo "help text")) + (buttonize-region (point-min) (point) #'ignore) + (should (equal (get-text-property (point-min) 'help-echo) + "help text")) + ;; unbuttonize-region should not clear the property either. + (unbuttonize-region (point-min) (point)) + (should (equal (get-text-property (point-min) 'help-echo) + "help text"))) + ;; unbuttonize-region should still clear properties applied with + ;; buttonize. + (with-temp-buffer + (insert "button text") + (buttonize-region (point-min) (point) #'ignore nil "help text") + (should (equal (get-text-property (point-min) 'help-echo) + "help text")) + (unbuttonize-region (point-min) (point)) + (should (equal (get-text-property (point-min) 'help-echo) + nil)))) + ;;; button-tests.el ends here