eval and replace anywhere
Being a living Elisp virtual machine, Emacs naturally provides the
ability to evaluate any Elisp expression anywhere. Just put the cursor
right after the expression to be evaluated and press C-xC-e
: the
result appears in the mini-buffer. I use this continuously, for
instance while reading about a variable to know its value. For
instance, imagine i see this line in one of my files:
(setq planner-project "planner")
and want to know if planner-project
has been modified. I just need to
put my cursor right after the variable name and get its value with
C-xC-e
.
As i said, C-xC-e
works in any (well, almost) buffer. Imagine you're
writing a note and need to perform an arithmetic operation: you could
write something like
Yesterday I spent (+ 2234.34 3423.4 (* 12.0 12.2) 10) dollars at ...
put the cursor just before 'dollars', press the eval shortcut, and see the result of the arithmetic operation in the mini-buffer. You memorize it, delete the Elisp expression… hmm, wait, this should be easier, shouldn't it? What we want is Emacs to eval and replace the expression for us.
I'm sure that you already know what comes next :-) As it happens, this time i didn't need to write the Elisp snippet myself: i stole it instead from Jorgen "forcer" Schäfer's configuration file:
(defun fc-eval-and-replace () "Replace the preceding sexp with its value." (interactive) (backward-kill-sexp) (prin1 (eval (read (current-kill 0))) (current-buffer)))
Complemented with the mandatory shortcut:
(global-set-key (kbd "C-c e") 'fc-eval-and-replace)
this little gem has probably the highest usefulness to lines of code ratio in my Elisp toolbox. Give it a try!
Update: pdq notes in a comment that, if the expression to be evaluated
is malformed (like, say, (+1 1)
) it gets deleted, and it would be nice
if it wouldn't. A quick way to get this functionality is to catch errors
in eval
and undo the killing in a generic error handler. To wit:
(defun fc-eval-and-replace () "Replace the preceding sexp with its value." (interactive) (backward-kill-sexp) (condition-case nil (prin1 (eval (read (current-kill 0))) (current-buffer)) (error (message "Invalid expression") (insert (current-kill 0)))))