2

I'm trying to write a function to do the following tasks:

  1. Extract a piece of text from the current buffer (specifically, a diff)
  2. Switch to a temporary buffer in another window, and insert this text into that buffer.
  3. Set the temporary buffer's major mode (to diff-mode).
  4. Prompt the user to save that buffer to a file.
  5. Kill the buffer, and restore the window layout if necessary.

The rough skeleton of the function is as follows:

(defun extract-and-save ()
  (interactive)
  (let ((text-to-save (get-text-to-save)))
    (with-temp-buffer?
      (insert text-to-save)
      (diff-mode)
      (save-buffer))))

I'm not able to get the with-temp-buffer invocation right -- I either end up saving the buffer before it's visible and not killing it afterwards, or mess up the major mode of the previous buffer before switching.

I've tried using with-temp-buffer-window and variants, but I don't understand them well enough/they don't work.

Any pointers?

3

EDIT: After thinking about this some more, I realized that with-temp-buffer may be a good choice after all, as it can replace the unwind-protect form in my original answer and the whole thing will be both cleaner and more robust. Here's what I'm currently advocating:

(defun extract-and-save ()
  (interactive)
  (let ((text-to-save (get-text-to-save)))
    (with-temp-buffer
      (switch-to-buffer-other-window (current-buffer))
      (insert text-to-save)
      (diff-mode)
      (save-buffer))))

So, basically what you had to begin with, except for the explicit (and weird-looking) switch-to-buffer form. Again, this is because with-temp-buffer selects its temporary buffer but doesn't display it to the user without specific prompting.


(Original answer, for context)

I think with-temp-buffer is the wrong construct for this, because it makes the temporary buffer current but doesn't display it, and you want the user to see the diff they're about to save. It's probably better to name the buffer and select it manually. Try something like this:

(defun extract-and-save ()
  (interactive)
  (let ((text-to-save (get-text-to-save)))
    (save-window-excursion
      (switch-to-buffer-other-window (generate-new-buffer "*extraction*"))
      (insert text-to-save)
      (diff-mode)
      (unwind-protect (save-buffer) 
        (kill-buffer)))))

The generate-new-buffer form is there in case of a collision with an existing buffer. The unwind-protect around save-buffer is in case the user declines to save using C-g.

  • Your first approach worked, I guess the only part I missed was the switch-to-buffer-other-window invocation from the second approach. However, isn't this kind of thing exactly what with-temp-buffer-window and friends were made for? – sykora Jan 15 '16 at 18:21
  • Maybe? I've read the manual section on with-temp-buffer-window several times, and I still don't get it. I think it may be approaching the same problem from a different angle somehow. – Aaron Harris Jan 15 '16 at 21:23
  • I tried your revised approach as well, it works fine except it appears that diff-mode isn't itself applied. It seems that some other built-in function should work, but I don't understand the manuals any better, so I'll stick with your original approach. Thanks! – sykora Jan 15 '16 at 22:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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