Q: is there an alternative to save-excursion
that only saves/restores point?
When writing elisp functions, I often need to save point, do some stuff in the current buffer, and then restore point. I had always used save-excursion
for doing so, but the docstring notes that it will:
Save point, mark, and current buffer; execute BODY; restore those things. Executes BODY just like
progn
. The values of point, mark and the current buffer are restored even in case of abnormal exit (throw or error). The state of activation of the mark is also restored.
Now: that seems like overkill if all I care about is point and I'm not touching (or otherwise don't care about) the mark and current buffer. In the absence of something like save-point
, I wrote the following macro:
(defmacro save-point (&rest body)
(cl-declare (debug t) (indent 0))
(let ((orig (cl-gensym)))
`(let ((,orig (point-marker)))
(unwind-protect
(progn ,@body)
(goto-char ,orig)))))
save-excursion
is written in C, so it wasn't a priori clear that this macro would be faster than the C code despite saving and restoring fewer objects. And, in fact, it's about an order of magnitude slower:
(benchmark-run-compiled 1000
(save-point t)) ; => .0005ish
(benchmark-run-compiled 1000
(save-excursion t)) ; => .00005ish
It currently looks like the macro is a fool's errand. So:
- Does something like this
save-point
macro already exist? - How could one streamline this macro to speed it up?
- Is there any way to make up the speed difference between the C code and the elisp code?
post-self-insert-hook
). It may turn out to be a red herring, so right now it's a curiosity question.save-excursion
no longer saves the mark.