branch: externals/compat commit abe97399f840929e6cff55fe9f5fb9110b6a7c97 Author: Daniel Mendler <m...@daniel-mendler.de> Commit: Daniel Mendler <m...@daniel-mendler.de>
compat-30: Add static-if --- compat-30.el | 13 +++++++++++-- compat-tests.el | 9 +++++++++ compat.texi | 25 +++++++++++++++++++++++++ 3 files changed, 45 insertions(+), 2 deletions(-) diff --git a/compat-30.el b/compat-30.el index 72110f23c0..3aaf99759e 100644 --- a/compat-30.el +++ b/compat-30.el @@ -22,8 +22,7 @@ ;;; Code: (eval-when-compile (load "compat-macs.el" nil t t)) -;; TODO Update to 29.1 as soon as the Emacs emacs-29 branch version bumped -(compat-require compat-29 "29.0.90") +(compat-require compat-29 "29.1") ;; TODO Update to 30.1 as soon as the Emacs emacs-30 branch version bumped (compat-version "30.0.50") @@ -56,5 +55,15 @@ tree) tree))) +(compat-defmacro static-if (condition then-form &rest else-forms) ;; <compat-tests:static-if> + "A conditional compilation macro. +Evaluate CONDITION at macro-expansion time. If it is non-nil, +expand the macro to THEN-FORM. Otherwise expand it to ELSE-FORMS +enclosed in a `progn' form. ELSE-FORMS may be empty." + (declare (indent 2) (debug (sexp sexp &rest sexp))) + (if (eval condition lexical-binding) + then-form + (cons 'progn else-forms))) + (provide 'compat-30) ;;; compat-30.el ends here diff --git a/compat-tests.el b/compat-tests.el index 1bb1f3ed35..98bb0d9028 100644 --- a/compat-tests.el +++ b/compat-tests.el @@ -75,6 +75,7 @@ (defmacro should-equal (a b) `(should (equal ,a ,b))) +;; TODO replace `compat-tests--if' with `static-if' (defmacro compat-tests--if (cond then &rest else) (declare (indent 2)) (if (eval cond t) then (macroexp-progn else))) @@ -3049,5 +3050,13 @@ "(a (b ((c) . d) e) (f))" "(a (b ((c) . d) e) (f))")))))) +(ert-deftest compat-static-if () + ;; TODO enable if CI Emacs 30 snapshot has been updated + (compat-tests--if (< emacs-major-version 30) + (progn + (should-equal "true" (static-if t "true")) + (should-not (static-if nil "true")) + (should-equal "else2" (static-if nil "true" "else1" "else2"))))) + (provide 'compat-tests) ;;; compat-tests.el ends here diff --git a/compat.texi b/compat.texi index 178106c564..a6ea20b753 100644 --- a/compat.texi +++ b/compat.texi @@ -3348,6 +3348,31 @@ older than 30.1. Note that due to upstream changes, it might happen that there will be the need for changes, so use these functions with care. +@defmac static-if condition then-form else-forms... +Test @var{condition} at macro-expansion time. If its value is +non-@code{nil}, expand the macro to @var{then-form}, otherwise expand +it to @var{else-forms} enclosed in a @code{progn}. @var{else-forms} +may be empty. + +Here is an example of its use from CC Mode, which prevents a +@code{defadvice} form being compiled in newer versions of Emacs: +@example +@group +(static-if (boundp 'comment-line-break-function) + (progn) + (defvar c-inside-line-break-advice nil) + (defadvice indent-new-comment-line (around c-line-break-advice + activate preactivate) + "Call `c-indent-new-comment-line' if in CC Mode." + (if (or c-inside-line-break-advice + (not c-buffer-is-cc-mode)) + ad-do-it + (let ((c-inside-line-break-advice t)) + (c-indent-new-comment-line (ad-get-arg 0)))))) +@end group +@end example +@end defmac + @subsection Extended Definitions These functions must be called explicitly via @code{compat-call}, since their calling convention or behavior was extended in Emacs 30.1: