emacs-31 2066a0c9e86 1/2: New variable 'macroexp-enable-pos-preservation' (bug#79599)

Sean Whitton <[email protected]>
Newsgroups gmane.emacs.diffs
Message-ID <[email protected]>
branch: emacs-31
commit 2066a0c9e865f7673a0e8fec8ac2de40abe5e862
Author: Eshel Yaron <[email protected]>
Commit: Sean Whitton <[email protected]>

    New variable 'macroexp-enable-pos-preservation' (bug#79599)
    
    * lisp/emacs-lisp/macroexp.el
    (macroexp-enable-pos-preservation): New variable.
    (macroexp-preserve-posification): Respect it.
    * lisp/emacs-lisp/elisp-scope.el (elisp-scope-1): Use it.
    * test/lisp/emacs-lisp/macroexp-tests.el
    (macroexp--test-macroexp-enable-pos-preservation): New test.
---
 lisp/emacs-lisp/elisp-scope.el         |  1 +
 lisp/emacs-lisp/macroexp.el            |  5 ++++-
 test/lisp/emacs-lisp/macroexp-tests.el | 21 +++++++++++++++++++++
 3 files changed, 26 insertions(+), 1 deletion(-)

diff --git a/lisp/emacs-lisp/elisp-scope.el b/lisp/emacs-lisp/elisp-scope.el
index f95ea41e496..4d1b7c69f15 100644
--- a/lisp/emacs-lisp/elisp-scope.el
+++ b/lisp/emacs-lisp/elisp-scope.el
@@ -2794,6 +2794,7 @@ are analyzed."
                    (symbols-with-pos-enabled t)
                    (message-log-max nil)
                    (inhibit-message t)
+                   (macroexp-enable-pos-preservation nil)
                    (macroexpand-all-environment
                     (append (mapcar #'list elisp-scope-unsafe-macros) macroexpand-all-environment)))
                (ignore-errors (macroexpand-1 form macroexpand-all-environment)))
diff --git a/lisp/emacs-lisp/macroexp.el b/lisp/emacs-lisp/macroexp.el
index 6a16ebb0fd2..49b8b022780 100644
--- a/lisp/emacs-lisp/macroexp.el
+++ b/lisp/emacs-lisp/macroexp.el
@@ -304,6 +304,9 @@ modified FORM."
   (let ((new-form (macroexp--posify-form-1 form call-pos 10)))
     (or new-form form)))
 
+(defvar macroexp-enable-pos-preservation t
+  "Whether to attach position of a macro call to the expanded form.")
+
 (defmacro macroexp-preserve-posification (pos-form &rest body)
   "Evaluate BODY..., posifying the result with POS-FORM's position, if any.
 If the result of body happens to have a position already, we do not
@@ -316,7 +319,7 @@ change this."
                     ((symbol-with-pos-p ,pos-form)
                      (symbol-with-pos-pos ,pos-form))))
          (new-value (progn ,@body)))
-     (if (and call-pos
+     (if (and macroexp-enable-pos-preservation call-pos
               (not (or (and (consp new-value)
                             (symbol-with-pos-p (car new-value)))
                        (and (symbol-with-pos-p new-value)))))
diff --git a/test/lisp/emacs-lisp/macroexp-tests.el b/test/lisp/emacs-lisp/macroexp-tests.el
index 94bd1e98920..a8deb79dfb6 100644
--- a/test/lisp/emacs-lisp/macroexp-tests.el
+++ b/test/lisp/emacs-lisp/macroexp-tests.el
@@ -182,4 +182,25 @@
               (user-error (error-message-string err))))))
      (should (and (stringp res) (string-match "new-replacement" res))))))
 
+(defmacro macroexp--test-with-foo (&rest body)
+  "Eagerly macro-expand BODY."
+  (macroexpand-all `(progn . ,body) macroexpand-all-environment))
+
+(ert-deftest macroexp--test-macroexp-enable-pos-preservation ()
+  (let* ((symbols-with-pos-enabled t)
+         (form (read-positioning-symbols
+                "(macroexp--test-with-foo (pop command-history))"))
+         (pop-pos (symbol-with-pos-pos (caadr form)))
+         (exp1 (macroexpand-1 form))
+         (macroexp-enable-pos-preservation nil)
+         (exp2 (macroexpand-1 form)))
+    ;; Position of `pop' preserved in EXP1.  There's no way to tell that
+    ;; the position information in EXP1 is synthetic, which may confuse
+    ;; consumers such as semantic highlighting.
+    (should (symbol-with-pos-p (caadr exp1)))
+    (should (= (symbol-with-pos-pos (caadr exp1)) pop-pos))
+    ;; Position preservation was disabled, so EXP2 is clean of synthetic
+    ;; position information.
+    (should-not (symbol-with-pos-p (caadr exp2)))))
+
 ;;; macroexp-tests.el ends here
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.