Eval And Replace In Emacs

I was watching another of Tim Visher's VimGolf videos in which he builds a multiplication table by the clever use of keyboard macros. What got my attention, however, was his use of the function eval-and-replace that evaluates the sexp preceding the point and replaces it with its value. This seemed like a useful thing to be able to do but as Visher explained, eval-and-replace is part of the Emacs Starter Kit and not part of Emacs itself.

I have a fairly large init.el that I've developed over time and therefore never installed the starter kit even though I've heard good things about it. Rather than hunt up the starter kit to get the function, I just rolled my own:

(defun eval-and-replace (value)
  "Evaluate the sexp at point and replace it with its value"
  (interactive (list (eval-last-sexp nil)))
  (kill-sexp -1)
  (insert (format "%S" value)))

The eval-last-sexp in the interactive declaration evaluates the sexp and passes its value to eval-and-replace. Then the (kill-sexp -1) deletes the sexp from the buffer. Finally the value is inserted into the buffer with the insert function.

I originally wrote the function using a let to capture the value of the sexp instead of using the interactive declaration but this seemed a bit shorter and I wanted to use an expression in the interactive declaration, as I wrote about here, to fix the idea in my mind.

I can see all sorts of uses for eval-and-replace. As a trivial example, suppose I want to say 223=8388608 but I don't remember the value of 223. I could switch over to my calculator buffer to make the calculation and then cut and paste it to my text or I can just write

2^23=(expt 2 23)

and call eval-and-replace to put the value in the text for me.

I've added eval-and-replace to my init.el so that I'll have it available the next time I have a need for it.

This entry was posted in Programming and tagged , . Bookmark the permalink.
  • danlei

    How about C-u M-: (expt 2 23) RET?

    • jcs

      Sure, I use that all the time. The downside, I suppose, is that you have to make it into a region first, but really it's about the same thing. That example, though, was just to give an example of a possible use of evaluate-and-replace.

      • danlei

        What do you mean by "you have to make it a region first"?

        • jcs

          I mean you have to select the region consisting of the sexp before the C-uM-:(expt 2 23).

  • danlei

    Maybe we're talking past each other. Running vanilla Emacs 23 (-q), it makes no difference whether a region is active or not when using C-u M-: ... RET.

    If all you want to do is inserting the value of an expression into a buffer, you just type C-u M-: ... RET, and you're done. Now, if you really need a command to substitute the value of an expression, sure, then that's exactly what eval-and-replace will do, but I can't see where this would be useful, except maybe if you spotted something that evaluates to a constant value in Lisp code. If you want to insert the value of an expression, why write the expression itself in a buffer in the first place?

    Maybe it's really just the example that confuses me. I don't wanna say that this is not useful at all, but I fail to see the "all sorts of uses". I rather think that this is a command I'd maybe use once or twice in a year for a pretty special use-case.

    • jcs

      OK, I see what you're saying. I Agee that the example I gave was trivial but it's the first thing that popped into my mind. You can look at Tim Visher's video to see a more realistic example--at least if building a multiplication table in the minimum keystrokes is realistic.

  • Phil Hudson

    For critical comparison, here's what I use:

    (defun ph/eval-and-replace ()
    "Replaces the preceding sexp with its value.

    Taken from http://nflath.com/2009/08/easier-emacs/ by N Flath."
    (condition-case nil
    (prin1 (eval (read (current-kill 0)))
    (error (message "Invalid expression")
    (insert (current-kill 0)))))

    • jcs

      Nice solution

  • @danlei: I think the primary difference between `C-u M-:` and eval-and-replace (I bind it to `C-c e`) is that you're not confined to the minibuffer for the construction of your sexp.

    I find the minibuffer to be a semi-awkward location to construct anything but the most trivial expressions. It's why I use Regexp Builder instead of the mini-buffer when I need to construct a particularly complicated regexp for use in some query-replace-regexp operation.

    But other than that, you may be more sure-fingered when working in elisp than me and not find it so awkward. I find the same challenge when working at a repl. Once I get to the point where I want to indent things for clarity, I usually drop to a buffer where that sort of thing is trivial.

  • danlei

    I understand, and yes, I also usually prefer writing my Lisp code in the REPL, so maybe this comes down to taste. I agree that C-u M-x will be awkward to use for bigger expressions, but usually, that's not what I need in this case (at least for keyboard macros).

    Also, if you really need those complicated expressions, and the buffer is not in emacs-lisp-mode, or a related lisp-editing mode, editing those expressions in there might not be optimal, too (but still better than the minibuffer, I agree).

    The really nice thing is, of course, that we can all easily make Emacs behave as it fits our taste, and introduce something like eval-and-replace, if we want to.