branch: externals/compat commit 68ead168f83bacda23de623a32fb9fa76aaaa7a9 Author: Daniel Mendler <m...@daniel-mendler.de> Commit: Daniel Mendler <m...@daniel-mendler.de>
compat-29: Add buttonize and buttonize-region --- NEWS.org | 1 + compat-28.el | 17 ----------------- compat-29.el | 45 +++++++++++++++++++++++++++++++++++++++++++++ compat-macs.el | 19 ++++++++++++------- compat-tests.el | 23 +++++++++++++++++++++++ compat.texi | 29 +++++++++++++++++++---------- 6 files changed, 100 insertions(+), 34 deletions(-) diff --git a/NEWS.org b/NEWS.org index 968b938364..7a418d1514 100644 --- a/NEWS.org +++ b/NEWS.org @@ -7,6 +7,7 @@ - compat-28: Add ~make-separator-line~. - compat-29: Minor fixes to ~keymap-*~ functions. - compat-29: Add ~with-memoization~. +- compat-29: Add ~buttonize~ and ~buttonize-region~. * Release of "Compat" Version 29.1.1.0 diff --git a/compat-28.el b/compat-28.el index 8b0cae84f2..0235ce44a4 100644 --- a/compat-28.el +++ b/compat-28.el @@ -768,23 +768,6 @@ The previous values will be be restored upon exit." variables) ,@body)) -;;;; Defined in button.el - -(compat-defun button-buttonize (string callback &optional data) ;; <UNTESTED> - "Make STRING into a button and return it. -When clicked, CALLBACK will be called with the DATA as the -function argument. If DATA isn't present (or is nil), the button -itself will be used instead as the function argument." - :feature button - (propertize string - 'face 'button - 'button t - 'follow-link t - 'category t - 'button-data data - 'keymap button-map - 'action callback)) - ;;;; Defined in time-data.el (compat-defun decoded-time-period (time) ;; <OK> diff --git a/compat-29.el b/compat-29.el index b330f33569..d05d617ca6 100644 --- a/compat-29.el +++ b/compat-29.el @@ -957,5 +957,50 @@ command exists in this specific map, but it doesn't have the ,@(nreverse props)) defvar-form)))) +;;;; Defined in button.el + +(compat-defun button--properties (callback data help-echo) ;; <OK> + "Helper function." + (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)) + +(defun buttonize (string callback &optional data help-echo) ;; <OK> + "Make STRING into a button and return it. +When clicked, CALLBACK will be called with the DATA as the +function argument. If DATA isn't present (or is nil), the button +itself will be used instead as the function argument. + +If HELP-ECHO, use that as the `help-echo' property. + +Also see `buttonize-region'." + (let ((string + (apply #'propertize string + (button--properties callback data help-echo)))) + ;; Add the face to the end so that it can be overridden. + (add-face-text-property 0 (length string) 'button t string) + string)) + +(compat-defun buttonize-region (start end callback &optional data help-echo) ;; <OK> + "Make the region between START and END into a button. +When clicked, CALLBACK will be called with the DATA as the +function argument. If DATA isn't present (or is nil), the button +itself will be used instead as the function argument. + +If HELP-ECHO, use that as the `help-echo' property. + +Also see `buttonize'." + (add-text-properties start end (button--properties callback data help-echo)) + (add-face-text-property start end 'button t)) + +;; Obsolete Alias since 29 +(compat-defalias button-buttonize buttonize :obsolete t) + (provide 'compat-29) ;;; compat-29.el ends here diff --git a/compat-macs.el b/compat-macs.el index 62e1bce0f5..f37c0ab1e5 100644 --- a/compat-macs.el +++ b/compat-macs.el @@ -25,12 +25,12 @@ ;; around. (require 'subr-x) -(defvar compat--current-version nil +(defvar compat--version nil "Version of the currently defined compatibility definitions.") (defmacro compat-declare-version (version) "Set the Emacs version that is currently being handled to VERSION." - (setq compat--current-version version) + (setq compat--version version) (let ((before (1- (car (version-to-list version))))) (when (and (< 24 before) (< emacs-major-version before)) `(require ',(intern (format "compat-%d" before)))))) @@ -45,7 +45,7 @@ Prepend compatibility notice to the actual documentation string." If this is not documented on yourself system, you can check \ `(compat) Emacs %s' for more details.]\n\n%s" type name - compat--current-version compat--current-version + compat--version compat--version docstring)) (let ((fill-column 80)) (fill-region (point-min) (point-max))) @@ -76,7 +76,7 @@ If this is not documented on yourself system, you can check \ (eval cond t) ;; The current Emacs must be older than the current declared Compat ;; version, see `compat-declare-version'. - (version< emacs-version compat--current-version))))) + (version< emacs-version compat--version))))) (defun compat--guarded-definition (attrs args fun) "Guard compatibility definition generation. @@ -138,6 +138,8 @@ REST are attributes and the function BODY." ATTRS is a plist of attributes, which specify the conditions under which the definition is generated. +- :obsolete :: Mark the alias as obsolete. + - :min-version :: Install the definition if the Emacs version is greater or equal than the given version. @@ -148,13 +150,16 @@ under which the definition is generated. - :cond :: Install the definition if :cond evaluates to non-nil." (declare (debug (name symbolp [&rest keywordp sexp]))) - (compat--guarded-definition attrs () - (lambda () + (compat--guarded-definition attrs '(:obsolete) + (lambda (obsolete) ;; The fboundp check is performed at runtime to make sure that we never ;; redefine an existing definition if Compat is loaded on a newer Emacs ;; version. `((unless (fboundp ',name) - (defalias ',name ',def)))))) + ,(if obsolete + `(define-obsolete-function-alias + ',name ',def ,compat--version) + `(defalias ',name ',def))))))) (defmacro compat-defun (name arglist docstring &rest rest) "Define compatibility function NAME with arguments ARGLIST. diff --git a/compat-tests.el b/compat-tests.el index d402eadded..a66e467668 100644 --- a/compat-tests.el +++ b/compat-tests.el @@ -60,6 +60,29 @@ (setq list (funcall sym list "first" 1 #'string=)) (should (eq (compat-call plist-get list "first" #'string=) 1)))) +(ert-deftest buttonize () + (let ((b (buttonize "button" 'c 'd 'h))) + (should-equal b "button") + (should-equal 'c (get-text-property 0 'action b)) + (should-equal 'c (get-text-property 5 'action b)) + (should-equal 'd (get-text-property 0 'button-data b)) + (should-equal 'd (get-text-property 5 'button-data b)) + (should-equal 'h (get-text-property 0 'help-echo b)) + (should-equal 'h (get-text-property 5 'help-echo b)))) + +(ert-deftest buttonize-region () + (with-temp-buffer + (insert "<button>") + (buttonize-region 2 7 'c 'd 'h) + (should-not (get-text-property 1 'action)) + (should-not (get-text-property 7 'action)) + (should-equal 'c (get-text-property 2 'action)) + (should-equal 'c (get-text-property 6 'action)) + (should-equal 'd (get-text-property 2 'button-data)) + (should-equal 'd (get-text-property 6 'button-data)) + (should-equal 'h (get-text-property 2 'help-echo)) + (should-equal 'h (get-text-property 6 'help-echo)))) + (ert-deftest with-memoization () (let ((x (cons nil nil)) y computed) (with-memoization (car x) diff --git a/compat.texi b/compat.texi index a08d05d19e..2b4e415e6f 100644 --- a/compat.texi +++ b/compat.texi @@ -1770,16 +1770,6 @@ environment variable and @var{value} is that variable's value. @xref{System Environment,System Environment,,elisp}. @end defmac -@c based on lisp/button.el -@defun button-buttonize string callback &optional data help-echo -Return a button with @var{string} as its label. When interacted on, the -one-argument function in @var{callback} is called and @var{data} (or -@code{nil} is not present) will be passed as the argument. - -If non-@code{nil}, the argument @var{help-echo} will be used to set the -@code{help-echo} text property. -@end defun - @c based on src/xfaces.c @defun color-values-from-color-spec spec Convert the textual color specification @var{spec} to a color triple @@ -2041,6 +2031,25 @@ Like @code{line-end-position}, but ignores fields (and is more efficient). @end defun +@c copied from lispref/display.texi +@defun buttonize string callback &optional data help-echo +Sometimes it's more convenient to make a string into a button without +inserting it into a buffer immediately, for instance when creating +data structures that may then, later, be inserted into a buffer. This +function makes @var{string} into such a string, and @var{callback} +will be called when the user clicks on the button. The optional +@var{data} parameter will be used as the parameter when @var{callback} +is called. If @code{nil}, the button is used as the parameter instead. +@end defun + +@defun buttonize-region start end callback &optional data help-echo +Make the region between START and END into a button. When clicked, +CALLBACK will be called with the DATA as the function argument. If +DATA isn't present (or is nil), the button itself will be used instead +as the function argument. If HELP-ECHO, use that as the help-echo +property. +@end defun + @c copied from lispref/display.texi @defun get-display-property position prop &optional object properties This convenience function can be used to get a specific display