[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[nongnu] elpa/macrostep 3757ec4 033/110: Extend macrostep-environment wh
From: |
ELPA Syncer |
Subject: |
[nongnu] elpa/macrostep 3757ec4 033/110: Extend macrostep-environment while printing macrolet body forms |
Date: |
Sat, 7 Aug 2021 09:17:57 -0400 (EDT) |
branch: elpa/macrostep
commit 3757ec49975e2d6ffbe05ed59a811edb9ab22394
Author: joddie <jonxfield@gmail.com>
Commit: joddie <jonxfield@gmail.com>
Extend macrostep-environment while printing macrolet body forms
This correctly handles macros like the following:
(defmacro with-local-do-something (&rest forms)
(declare (indent 0))
`(cl-macrolet ((do-something (arg) ...))
,@forms))
When the following form is expanded, `(do-something ...)` should be
correctly
highlighted as a macro form:
(with-local-do-something
(do-something (here)))
See `with-js` in `js.el.gz` for a real example.
---
macrostep-test.el | 57 ++++++++++++++++++++++++++++++++++++++
macrostep.el | 82 +++++++++++++++++++++++++++++++++++--------------------
2 files changed, 110 insertions(+), 29 deletions(-)
diff --git a/macrostep-test.el b/macrostep-test.el
index 7fda05e..3363c9b 100644
--- a/macrostep-test.el
+++ b/macrostep-test.el
@@ -161,7 +161,64 @@
(apply (cdr (assq 'get env)) '(:begin))
'(plist-get list :begin))))))
+(ert-deftest macrostep-print-sexp ()
+ (cl-macrolet ((should-print (form string)
+ `(should (equal
+ (with-temp-buffer
+ (macrostep-print-sexp ,form)
+ (buffer-string))
+ ,string))))
+ (should-print 'symbol "symbol")
+ (should-print '(single-element-list) "(single-element-list)")
+ (should-print '(two-element list) "(two-element list)")
+ (should-print '(three element list) "(three element list)")
+ (should-print '(dotted . list) "(dotted . list)")
+ (should-print '(four element dotted . list) "(four element dotted . list)")
+ (should-print '(nested (list (elements))) "(nested (list (elements)))")
+ (should-print '((deeply (nested)) (list (elements)))
+ "((deeply (nested)) (list (elements)))")
+ (should-print '(quote fishes) "'fishes")
+ (should-print '`(backquoted form) "`(backquoted form)")
+ (should-print '`(backquoted (form) ,with ,@splices)
+ "`(backquoted (form) ,with ,@splices)")))
+
+(ert-deftest macrostep-print-sexp-macrolet-environment ()
+ (with-temp-buffer
+ (emacs-lisp-mode)
+ (save-excursion
+ (macrostep-print-sexp
+ '(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)
+ (goto-char (match-beginning 0))
+ ;; Leave point on the head of the form
+ (forward-char)))
+ ;; The occurrence of "(some-macro" in the binding list should
+ ;; not be fontified as a macro form
+ (search "(some-macro (&rest")
+ (should-not
+ (eq (get-char-property (point) 'font-lock-face)
+ 'macrostep-macro-face))
+
+ ;; However, the two occurrences in the body of the macrolet should be.
+ (search "(some-macro with (arguments)")
+ (should
+ (eq (get-char-property (point) 'font-lock-face)
+ 'macrostep-macro-face))
+
+ (search "(some-macro with (more)")
+ (should
+ (eq (get-char-property (point) 'font-lock-face)
+ 'macrostep-macro-face))))))
+
+
(when noninteractive
(load-file (expand-file-name "macrostep.el"
(file-name-directory load-file-name)))
(ert-run-tests-batch "^macrostep"))
+
+
diff --git a/macrostep.el b/macrostep.el
index b920402..c5a3621 100644
--- a/macrostep.el
+++ b/macrostep.el
@@ -709,36 +709,60 @@ expansion will not be fontified. See also
(macrostep-print-sexp (cadr sexp)))
(t ; other list form
- ;; 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-expanded-text sexp)
- ;; Fontify the head of the macro
- (macrostep-propertize
- (prin1 head (current-buffer))
- 'font-lock-face 'macrostep-macro-face)
- (when (cdr sexp) (insert " "))
- (setq sexp (cdr sexp)))
- ;; Not a macro form
- (insert "("))
-
- ;; Print remaining list elements
- (while sexp
- (if (listp sexp)
+ ;; If the sexp is a (cl-)macrolet form, the
+ ;; macro-expansion environment should be extended using
+ ;; its bindings while printing the body forms in order to
+ ;; correctly mark any uses of locally-bound macros. (See
+ ;; `with-js' in `js.el.gz' for an example of a macro that
+ ;; works this way).
+ (let ((extended-environment
+ (pcase sexp
+ (`(,(or `cl-macrolet `macrolet) ,bindings . ,_)
+ (append (macrostep-bindings-to-environment bindings)
+ macrostep-environment))
+ (_ macrostep-environment))))
+
+ ;; Is it an (unquoted) macro form?
+ (if (and (not quoted-form-p)
+ (macrostep-macro-form-p sexp))
(progn
- (macrostep-print-sexp (car sexp) quoted-form-p)
- (when (cdr sexp) (insert " "))
- (setq sexp (cdr sexp)))
- ;; Print tail of dotted list
- (insert ". ")
- (macrostep-print-sexp sexp)
- (setq sexp nil)))
- (insert ")")))))
+ ;; Save the real expansion as a text property on the
+ ;; opening paren
+ (macrostep-propertize
+ (insert "(")
+ 'macrostep-expanded-text sexp)
+ ;; Fontify the head of the macro
+ (macrostep-propertize
+ (prin1 head (current-buffer))
+ 'font-lock-face 'macrostep-macro-face))
+ ;; Not a macro form
+ (insert "(")
+ (prin1 head (current-buffer)))
+
+ ;; Print remaining list elements
+ (setq sexp (cdr sexp))
+ (when sexp (insert " "))
+ ;; macrostep-environment will be setq'd after printing
+ ;; the second element of the list (i.e., the binding
+ ;; list in a macrolet form)
+ (let ((macrostep-environment macrostep-environment))
+ (while sexp
+ (if (listp sexp)
+ (progn
+ (macrostep-print-sexp (car sexp) quoted-form-p)
+ (when (cdr sexp) (insert " "))
+ (setq sexp (cdr sexp))
+ ;; At this point the first and second
+ ;; elements of the list have been printed, so
+ ;; it is time to extend the macro-expansion
+ ;; environment inside a macrolet for the body
+ ;; forms.
+ (setq macrostep-environment extended-environment))
+ ;; Print tail of dotted list
+ (insert ". ")
+ (macrostep-print-sexp sexp)
+ (setq sexp nil))))
+ (insert ")"))))))
;; Print everything except symbols and lists as normal
(t (prin1 sexp (current-buffer)))))
- [nongnu] elpa/macrostep 77c0c1a 023/110: update readme, (continued)
- [nongnu] elpa/macrostep 77c0c1a 023/110: update readme, ELPA Syncer, 2021/08/07
- [nongnu] elpa/macrostep b04f8db 026/110: Basic support for expanding macros bound by `macrolet', ELPA Syncer, 2021/08/07
- [nongnu] elpa/macrostep 7acce07 028/110: Require `cl-macs` at runtime, ELPA Syncer, 2021/08/07
- [nongnu] elpa/macrostep 51d5b6a 036/110: Fix a bug with printing the first element of a list., ELPA Syncer, 2021/08/07
- [nongnu] elpa/macrostep 07e14e2 032/110: Test for macrostep-environment-at-point, ELPA Syncer, 2021/08/07
- [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 <=
- [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, 2021/08/07
- [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