Apparently, my last blog post about diffing buffer fragments sparked a small discussion on Twitter. Most comments fell into one of two categories: some people wanted to use ediff
(which I explicitly mentioned I didn’t want), and some people complained about the temp files (which do not bother me that much).
Well, it turns out that I really did not have to create the temp files after all! (At least, not myself.) The Emacs diff
function accepts not only filenames, but also buffers! Of course, it just creates temporary files itself, but it’s quite nice that I don’t have to deal with implementation details like this.
So, here is an improved version.
(defun diff-last-two-kills () "Put the last two kills to temporary buffers and diff them." (interactive) (let ((old (generate-new-buffer "old")) (new (generate-new-buffer "new"))) (set-buffer old) (insert (current-kill 0 t)) (set-buffer new) (insert (current-kill 1 t)) (diff old new) (kill-buffer old) (kill-buffer new)))
Interestingly, this version is longer and looks less elegant, since we cannot use with-temp-buffer
(as an analogue to with-temp-file
) – we need the temporary buffers to persist until diff
is called. Of course, under the hood Emacs still creates (but then promptly deletes) a bunch of temporary files:
$ inotifywait -m -e create -e delete /tmp Setting up watches. Watches established. /tmp/ CREATE buffer-content-XZ5c8a /tmp/ CREATE .#buffer-content-XZ5c8a /tmp/ DELETE .#buffer-content-XZ5c8a /tmp/ CREATE buffer-content-PBbzBQ /tmp/ CREATE .#buffer-content-PBbzBQ /tmp/ DELETE .#buffer-content-PBbzBQ /tmp/ DELETE buffer-content-XZ5c8a /tmp/ DELETE buffer-content-PBbzBQ /tmp/ CREATE diff17mFyyy /tmp/ CREATE diff2pEVWzg /tmp/ CREATE .#diff17mFyyy /tmp/ DELETE .#diff17mFyyy /tmp/ CREATE .#diff2pEVWzg /tmp/ DELETE .#diff2pEVWzg /tmp/ DELETE diff17mFyyy /tmp/ DELETE diff2pEVWzg
(Notice the ugly autosave files…)
I’m not sure which one you prefer – I am going to use the latter one now, but frankly I don’t care a lot about the differences. For me, the nicest takeaway is that I can give buffers instead of filenames to diff
– from now on, I am going to check if other Emacs functions accepting filenames can also accept buffers.