As a disclaimer, this is the first function I have EVER written in Lisp or ELisp. Please, bash it as much as you would any other piece, but don't judge me for it please! :)
So, I realized I wanted a way to rename files without all the hassle of reopening the file etc. I googled and found a function at https://stackoverflow.com/questions/384284/can-i-rename-an-open-file-in-emacs (credit Steve Yegge).
However, it did not seem to work well with uniquify
. Which was a problem. Having two files open and trying to rename the first one to the same name as the second one (for example CMakeLists.txt, which there might be many of) caused it to bail since it only checked the name of the buffer (which wasn't unique yet, as uniquify doesn't do it's thing before something needs uniquifying).
The only way I found to force a "re-uniquification" was to close the previous buffer and open the new file. This seems very inelegant...
(defun is-unique-name-for-buffer (new-name)
(let ((file-name (buffer-file-name))
(dir-name (file-name-directory buffer-file-name)))
(let ((new-complete-name (concat dir-name new-name)))
(progn (not (string-equal file-name new-complete-name))))))
(defun rename-file-and-buffer (new-name)
"Renames both current buffer and file it's visiting to NEW-NAME."
(interactive "sNew name: ")
(let ((name (buffer-name))
(filename (buffer-file-name))
(dir-name (file-name-directory (buffer-file-name))))
(if (not filename)
(message "Buffer '%s' is not visiting a file!" name)
(if (not (is-unique-name-for-buffer new-name))
(message "A buffer named '%s' already exists in that location!" new-name)
(progn
(rename-file (file-name-nondirectory filename) new-name 1)
(kill-buffer)
(set-buffer (find-file (concat dir-name new-name))))))))
concat
to build absolute file names. Useexpand-file-name
:(expand-file-name dir-name new-name)
. That way, Emacs handles file names for different systems automatically. \$\endgroup\$find-file-noselect
, notfind-file
. \$\endgroup\$