I have this code:






I want to copy all the \bibitem{<bibkey>} strings in a temp buffer, edit them, and see the output side-by-side with the main buffer until I press C-x 1.

I can do this creating a temp file physically saved on my hard disk, but I'm trying to do this without saving any file. Is it possible?

My attempt

(defun leo ()
  (let* ((beg (copy-marker (progn
                             (goto-char (point-min))
                             (re-search-forward "^\\\\begin{thebibliography}" nil t)
         (end (copy-marker (progn
                             (re-search-forward "^\\\\end{thebibliography}" nil t)
                             (forward-line -1)
         (buf (current-buffer))
         (counter 0))

      (switch-to-buffer-other-window (current-buffer))
      (rename-buffer "*tmp*" t)
      (insert-buffer-substring buf beg end)

      ;; edits
      (goto-char (point-min))
      (while (re-search-forward "^\\(.+\\)" nil t)
        (keep-lines "^\\\\bibitem.+"))

          (flush-lines "^[ ]*$" (point-min) (point-max))))

      ;; i-th \bibitem{bibkey} ==> [i]: bibkey
      (replace-regexp "^\\\\bibitem{\\([^}]+\\)}"
                      (list (lambda (replacement counter)
                              (concat "["
                                      (format "%d" (+ counter 1))
                                      "]: \\1"))))

      ;; without this the *tmp* buffer is not shown...
      (read-key-sequence "Bibkeys")



  • Without (read-key-sequence "Bibkeys") the *tmp* buffer is not shown.
  • If I switch flush-lines with replace-regexp it seems that replace-regexp is being ignored.
  • Basically I can't do anything with my new buffer because as soon as I try to do anything, the buffer stays in place but any changes I've made disappear and I end up with a 1:1 copy of the bibliography.

How can I fix my code?

1 Answer 1


I'm not exactly sure what you are trying to do (e.g. why go to all that work to edit a temporary buffer that will eventually disappear without a trace?), but here are some notes that might help you understand what is going on.

with-temp-buffer will run its body and then kill the temporary buffer. If you want the buffer to become visible for some time, then you will have to somehow not exit the body for that time. One way is to ask for input, as you have done:

  (switch-to-buffer-other-window (current-buffer))
  (rename-buffer "*tmp*" t)
  (insert "foo")
  (read-from-minibuffer "Foo: "))

Until that input is provided, the read-from-minibuffer will not return, so you are still within the with-temp-buffer and the buffer remains alive.

Another is to delay for some time:

  (switch-to-buffer-other-window (current-buffer))
  (rename-buffer "*tmp*" t)
  (insert "foo")
  (sit-for 10))

will wait for 10 seconds before exiting the body and killing the buffer.

It seems to me that the input method will allow you to do what you want somewhat clumsily: when you are asked for input, switch to the temporary buffer instead, edit it as you want, and when you are done, switch back to the minibuffer, press RET and the buffer will be gone.

  • 1
    I am a professional typesetter. Sometimes authors ask "change [27] to [151]"', and then I have to find the bibkey for [151], the one for [27] and do the replacement throughout the paper. It also happens that they ask to change [27-31] with [57-62] and in these cases it is really useful to have all the bibkeys in a dedicated buffer, so you can select the ones you need in bulk and make these corrections faster. I've already tried your solution and it works, but as you said it's clumsy. In any case your answer was helpful for me to understand how with-temp-buffer works. Dec 3, 2022 at 17:34
  • Thanks for the explanation! That helped me understand why you wanted this in the first place.
    – NickD
    Dec 3, 2022 at 18:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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