An Elisp Editing Tip

One of the first things new Emacs users learn is the eval-last-sexp (C-x C-e) command and that Emacs can interpret elisp anywhere it appears. Here’s a quick tip about using this command when writing elisp that you may not have discovered.

If you call it with a prefix (C-u) argument, it prints (or attempts to print) the result in place in the buffer. Better yet, call it with an argument of 0 (C-0 C-x C-e) to avoid truncating longer results.

Variables evaluate to their values, so here it prints the current values of these variables:

This is handy when writing elisp, for example if you want to tweak the current value of a variable:

I replace eval-last-sexp everywhere with pp-eval-last-sexp, which produces a cleaner result:

(global-set-key [remap eval-last-sexp] 'pp-eval-last-sexp)

That is all.

Comment via email
Kaushal Modi
2021-10-25

I have been using the eros (Evaluation Result OverlayS) package, which got inspired from this endlessparentheses.com post.

I am mentioning it because it’s very much related to this post, and C-u C-x C-e works even after eros overrides eval-last-sexp to eros-eval-last-sexp.

Karthik
2021-10-25
@Kaushal Modi: Eros looks useful! I’ve never used CIDER so I didn’t realize this exists. It seems like this can be abstracted into a general library for prog-mode that can work for any interpreted language. That’s too big a project for me right now, but I wonder if there’s been some work towards this already…
Kaushal Modi
2021-10-26

@Karthik I don’t use CIDER either. The endlessparentheses post references CIDER, but then the eros package is exactly what you said.. it extracts the overlay piece of CIDER code into a separate package.

To use this, you just do M-x package-install eros and require the package; that’s it. The package does the job of remapping eval-last-sexp to eros-eval-last-sexp.

Karthik
2021-10-26

@Kaushal Modi: I understand. I mentioned CIDER because this feature has apparently been part of it for longer than eros has existed and I never encountered it.

My secondary point was that eros only works for emacs-lisp evaluation. It would be useful to extend the idea to other interpreted languages. It doesn’t seem like it needs much changing. Something like this will work. Define

(defun eros-eval-statement (&optional arg)
  "Wrapper that overlays results."
  (interactive "P")
  (eros--eval-overlay
   (funcall repl-eval arg)
   (point)))

where repl-eval is set to a major-mode specific evaluation function that collects comint output and formats it appropriately. For example, some variant of python-shell-send-statement for python-mode. Now we have result overlays for all languages that Emacs has comint support for.