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