[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[nongnu] elpa/macrostep 31e1dc2 060/110: Detect Elisp macro forms by adv
From: |
ELPA Syncer |
Subject: |
[nongnu] elpa/macrostep 31e1dc2 060/110: Detect Elisp macro forms by advising `macroexpand` |
Date: |
Sat, 7 Aug 2021 09:18:02 -0400 (EDT) |
branch: elpa/macrostep
commit 31e1dc27b7b040c9c27e2ee83d35cdd2df1742e7
Author: joddie <jonxfield@gmail.com>
Commit: joddie <jonxfield@gmail.com>
Detect Elisp macro forms by advising `macroexpand`
This works similarly to binding *MACROEXPAND-ALL* in CL, but is
implemented by changing the symbol binding of `macroexpand`.
This permits removing the special case for `lambda` and simplifying
`macrostep-print-sexp`.
---
macrostep-test.el | 7 +--
macrostep.el | 130 +++++++++++++++++++++++++++++++++---------------------
2 files changed, 83 insertions(+), 54 deletions(-)
diff --git a/macrostep-test.el b/macrostep-test.el
index 0d0233c..5fc6cbf 100644
--- a/macrostep-test.el
+++ b/macrostep-test.el
@@ -183,18 +183,19 @@
(should-print '`(backquoted (form) ,with ,@splices)
"`(backquoted (form) ,with ,@splices)")))
-(ert-deftest macrostep-print-sexp-macrolet-environment ()
+(ert-deftest macrostep-pp-macrolet-environment ()
(with-temp-buffer
(emacs-lisp-mode)
(save-excursion
- (macrostep-print-sexp
+ (macrostep-pp
'(macrolet ((some-macro (&rest forms) (cons 'progn forms)))
(some-macro with (arguments))
(intervening body forms)
(some-macro with (more) (arguments))))
(cl-flet ((search (text)
(goto-char (point-min))
- (search-forward text)
+ (let ((search-whitespace-regexp "[[:space:]\n]+"))
+ (search-forward-lax-whitespace text))
(goto-char (match-beginning 0))
;; Leave point on the head of the form
(forward-char)))
diff --git a/macrostep.el b/macrostep.el
index 379b351..5e60593 100644
--- a/macrostep.el
+++ b/macrostep.el
@@ -591,7 +591,6 @@ using `load-library' and the macro definition returned as
normal.
If INHIBIT-AUTOLOAD is non-nil, no files will be loaded, and the
value of DEFINITION in the result will be nil."
(pcase form
- (`(lambda . ,_) nil)
(`(,(and (pred symbolp) head) . ,_)
(let ((macrolet-definition
(assoc-default head macrostep-environment 'eq)))
@@ -745,24 +744,51 @@ Will not collapse overlays that begin at START and end at
END."
(overlay-get ol 'macrostep-original-text))
(macrostep-collapse-overlay ol t))))
+(defvar macrostep-collected-macro-forms nil)
+(defvar macrostep-collected-compiler-macro-forms nil)
+
(defun macrostep-pp (sexp)
- (let ((print-quoted t))
- (macrostep-print-sexp sexp)
- ;; Point is now after the expanded form; pretty-print it
- (save-restriction
- (narrow-to-region (scan-sexps (point) -1) (point))
- (save-excursion
- (pp-buffer)
- ;; Remove the extra newline inserted by pp-buffer
- (goto-char (point-max))
- (delete-region
- (point)
- (save-excursion (skip-chars-backward " \t\n") (point))))
- ;; Indent the newly-inserted form in context
- (widen)
- (save-excursion
- (backward-list)
- (indent-sexp)))))
+ (cl-destructuring-bind
+ (macrostep-collected-macro-forms
+ macrostep-collected-compiler-macro-forms)
+ (macrostep-collect-macro-forms sexp)
+ (let ((print-quoted t))
+ (macrostep-print-sexp sexp)
+ ;; Point is now after the expanded form; pretty-print it
+ (save-restriction
+ (narrow-to-region (scan-sexps (point) -1) (point))
+ (save-excursion
+ (pp-buffer)
+ ;; Remove the extra newline inserted by pp-buffer
+ (goto-char (point-max))
+ (delete-region
+ (point)
+ (save-excursion (skip-chars-backward " \t\n") (point))))
+ ;; Indent the newly-inserted form in context
+ (widen)
+ (save-excursion
+ (backward-list)
+ (indent-sexp))))))
+
+(defun macrostep-collect-macro-forms (form)
+ (let ((real-macroexpand (indirect-function #'macroexpand))
+ (macro-forms '())
+ (compiler-macro-forms '()))
+ (cl-letf
+ (((symbol-function #'macroexpand)
+ (lambda (form environment &rest args)
+ (let ((expansion
+ (apply real-macroexpand form environment args)))
+ (cond ((not (eq expansion form))
+ (setq macro-forms (cons form macro-forms)))
+ ((and (consp form)
+ (symbolp (car form))
+ (get (car form) 'compiler-macro))
+ (setq compiler-macro-forms
+ (cons form compiler-macro-forms))))
+ expansion))))
+ (macroexpand-all form))
+ (list macro-forms compiler-macro-forms)))
(defun macrostep-get-gensym-face (symbol)
"Return the face to use in fontifying SYMBOL in printed macro expansions.
@@ -791,16 +817,14 @@ fontified using the same face (modulo the number of
faces; see
collect `(put-text-property ,start (point)
,key ,value))))))
-(defun macrostep-print-sexp (sexp &optional quoted-form-p)
+(defun macrostep-print-sexp (sexp)
"Pretty-print SEXP, a macro expansion, in the current buffer.
Fontifies uninterned symbols and macro forms using
`font-lock-face' property, and saves the actual text of SEXP's
sub-forms as the `macrostep-expanded-text' text property so that
any uninterned symbols can be reused in macro expansions of the
-sub-forms. If QUOTED-FORM-P is non-nil then any macros in the
-expansion will not be fontified. See also
-`macrostep-sexp-at-point'."
+sub-forms. See also `macrostep-sexp-at-point'."
(cond
((symbolp sexp)
;; Fontify gensyms
@@ -817,17 +841,18 @@ expansion will not be fontified. See also
(cond ((and (eq head 'quote) ; quote
(= (length sexp) 2))
(insert "'")
- (macrostep-print-sexp (cadr sexp) t))
+ (macrostep-print-sexp (cadr sexp)))
((and (eq head '\`) ; backquote
(= (length sexp) 2))
- ;; Treat backquote as a macro
- (macrostep-propertize
- (insert "`")
- 'macrostep-expanded-text sexp
- 'macrostep-macro-start t
- 'font-lock-face 'macrostep-macro-face)
- (macrostep-print-sexp (cadr sexp) t))
+ (if (memq sexp macrostep-collected-macro-forms)
+ (macrostep-propertize
+ (insert "`")
+ 'macrostep-expanded-text sexp
+ 'macrostep-macro-start t
+ 'font-lock-face 'macrostep-macro-face)
+ (insert "`"))
+ (macrostep-print-sexp (cadr sexp)))
((and (memq head '(\, \,@)) ; unquote
(= (length sexp) 2))
@@ -848,26 +873,29 @@ expansion will not be fontified. See also
macrostep-environment))
(_ macrostep-environment))))
- ;; Is it an (unquoted) macro form?
- (if (and (not quoted-form-p)
- (macrostep-macro-form-p sexp))
- (progn
- ;; Save the real expansion as a text property on the
- ;; opening paren
- (macrostep-propertize
- (insert "(")
- 'macrostep-macro-start t
- 'macrostep-expanded-text sexp)
- ;; Fontify the head of the macro
- (macrostep-propertize
- (macrostep-print-sexp head)
- 'font-lock-face
- (pcase (macrostep-macro-form-p sexp)
- (`macro 'macrostep-macro-face)
- (`compiler-macro 'macrostep-compiler-macro-face))))
- ;; Not a macro form
- (insert "(")
- (macrostep-print-sexp head quoted-form-p))
+ ;; Is it a macro form?
+ (let ((macro?
+ (memq sexp macrostep-collected-macro-forms))
+ (compiler-macro?
+ (memq sexp macrostep-collected-compiler-macro-forms)))
+ (if (or macro? compiler-macro?)
+ (progn
+ ;; Save the real expansion as a text property on the
+ ;; opening paren
+ (macrostep-propertize
+ (insert "(")
+ 'macrostep-macro-start t
+ 'macrostep-expanded-text sexp)
+ ;; Fontify the head of the macro
+ (macrostep-propertize
+ (macrostep-print-sexp head)
+ 'font-lock-face
+ (if macro?
+ 'macrostep-macro-face
+ 'macrostep-compiler-macro-face)))
+ ;; Not a macro form
+ (insert "(")
+ (macrostep-print-sexp head)))
;; Print remaining list elements
(setq sexp (cdr sexp))
@@ -879,7 +907,7 @@ expansion will not be fontified. See also
(while sexp
(if (listp sexp)
(progn
- (macrostep-print-sexp (car sexp) quoted-form-p)
+ (macrostep-print-sexp (car sexp))
(when (cdr sexp) (insert " "))
(setq sexp (cdr sexp))
;; At this point the first and second
- [nongnu] elpa/macrostep c93c2d6 053/110: Language-agnostic macro-form boundaries, (continued)
- [nongnu] elpa/macrostep c93c2d6 053/110: Language-agnostic macro-form boundaries, ELPA Syncer, 2021/08/07
- [nongnu] elpa/macrostep e3e5c12 034/110: Merge branch 'expand-macrolet', ELPA Syncer, 2021/08/07
- [nongnu] elpa/macrostep 4ea178a 045/110: Simplify overlay collapsing, ELPA Syncer, 2021/08/07
- [nongnu] elpa/macrostep 2519692 038/110: Restore narrowing, ELPA Syncer, 2021/08/07
- [nongnu] elpa/macrostep c748996 057/110: Tweak macrostep-slime-macro-form-p, ELPA Syncer, 2021/08/07
- [nongnu] elpa/macrostep 3757ec4 033/110: Extend macrostep-environment while printing macrolet body forms, ELPA Syncer, 2021/08/07
- [nongnu] elpa/macrostep a478a3a 054/110: Bind inhibit-read-only instead of buffer-read-only, ELPA Syncer, 2021/08/07
- [nongnu] elpa/macrostep 8d72b62 044/110: Fix indentation in new macrostep-pp function, ELPA Syncer, 2021/08/07
- [nongnu] elpa/macrostep 8950313 037/110: Bump version number and changelog for 0.8, ELPA Syncer, 2021/08/07
- [nongnu] elpa/macrostep 5680278 056/110: Gross hack to macrostep--slime-propertize-macros, ELPA Syncer, 2021/08/07
- [nongnu] elpa/macrostep 31e1dc2 060/110: Detect Elisp macro forms by advising `macroexpand`,
ELPA Syncer <=
- [nongnu] elpa/macrostep c61b836 062/110: Use SB-WALKER:WALK-FORM to collect macro forms, ELPA Syncer, 2021/08/07
- [nongnu] elpa/macrostep 39e809a 064/110: swank-macrostep: call PROVIDE at the end, ELPA Syncer, 2021/08/07
- [nongnu] elpa/macrostep 1be6c4d 061/110: Extract Elisp macro environments accurately, ELPA Syncer, 2021/08/07
- [nongnu] elpa/macrostep d9c7629 063/110: Improvements to Elisp environment handling, ELPA Syncer, 2021/08/07
- [nongnu] elpa/macrostep 59972eb 071/110: Fix handling of subforms contained within other subforms, ELPA Syncer, 2021/08/07
- [nongnu] elpa/macrostep a0ae61c 073/110: Properly handle forms not present in the expansion, ELPA Syncer, 2021/08/07
- [nongnu] elpa/macrostep 817322b 074/110: Properly place the macrostep[-compiler]-macro-face, ELPA Syncer, 2021/08/07
- [nongnu] elpa/macrostep aa40d97 076/110: Test expansion within Elisp macro-defining macros, ELPA Syncer, 2021/08/07
- [nongnu] elpa/macrostep 1edee85 080/110: Reorganise and comment, ELPA Syncer, 2021/08/07
- [nongnu] elpa/macrostep bbfb033 081/110: Reorganise and document generic interface, ELPA Syncer, 2021/08/07