I am trying to write a macro. I have read the manual and learned about macroexpand. However, when I use it, I find the expansion difficult to read and work with.

How can I expand a macro in a readable, workable format?

Let me illustrate.

If I simply call macroexpand, the result is echoed in the minibuffer. When the expansion is large, the echo is all scrunched up:

(macroexpand '(with-temp-file (make-temp-file "test-file")))

enter image description here

I can go to *Messages* with C-h e, copy and paste it back into *scratch*, and then format it. But clearly that gets tiresome.

To save on the copy/paste, I have tried using eval-last-sexp with a universal argument, C-u C-x C-e. This indeed prints the output to the buffer...but it's in some weird interactive state that I cannot edit. Pressing RET causes it to alternate between an abbreviated and expanded form:

Abbreviated (expressions contain ellipses): enter image description here

Expanded (Placing point before the expansion and pressing RET causes the ellipses to expand and not insert a line break): enter image description here

After calling macroexpand, C-h k RET shows that elisp-last-sexp-toggle-display is now the binding for RET.

All of this implies some kind of workflow. However, the documentation for macroexpand describes none of this behavior. The source code is not distributed with my version of Emacs (Emacs 26.3 for Windows). Scouring the web has found no meaningful explanation of how to work with macro expansions.

  • In Lisp Interaction Mode, C-j evaluates the expression before point (it is bound to eval-print-last-sexp). The result is printed in the buffer. Does that make things a bit easier? – NickD Feb 25 at 14:32
  • Thank. Yes, but only marginally. It places the result on a newline. However, the ellipsis behavior is still there. – Lorem Ipsum Feb 25 at 15:44
  • What NickD said. Expand the ellipsis mark the region of the result and call Edit -> Text Properties -> Remove Text Properties. If you don't want to use the menu bar you can call M-x facemenu-remove-all to remove the fancy text properties. – Tobias Feb 25 at 15:53
  • 2
    More than being about macros your question is about the printing behavior of complex lists. See emacs.stackexchange.com/q/34413/5223 Also in the link of macrexpand you gave, below is macroexpand-1. Try it – Rusi Feb 25 at 15:58

The question is really more about printing Lisp sexps (including results of evaluation) than it is about macro expansion, per se. It's just that macro expansion typically results in a large Lisp sexp that can be difficult to work with or read, especially if parts of it are elided (...).

I use pp-eval-last-sexp, which I bind to C-x C-e. (With C-u it inserts the result at point, like eval-last-sexp.)

You've pointed out some difficulties with this. But try the version of it you get with library PP+ (pp+.el).

It respects user options pp-eval-expression-print-length, pp-eval-expression-print-level, and pp-max-tooltip-size. The first two are similar to but separate from the standard options with the same names but without prefix pp-. So you can have separate values for pretty printing and non-pretty printing.

I also bind M-: to pp-eval-expression, instead of eval-expression.

Both of these commands also let you use M-0 to toggle between using a tooltip for the result (when it is no larger than pp-max-tooltip-size) and the usual handling (echo area or insertion in current buffer).

(The commands also respect option eval-expression-debug-on-error.)

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.