Is there a way to rename an open file in Emacs? While I'm viewing it? Something like save-as, but the original one should go away.
Is there a way to rename an open file in Emacs? While I'm viewing it? Something like save-as, but the original one should go away.
Yes, with dired mode, you can:
C-x d to open diredRET to select directory of current fileC-x C-j (dired-jump to the name of the current file, in Dired)R to rename the file (or dired-do-rename). q to go back to the (renamed) file bufferThe rename is equivalent to a shell mv, but it will also update any open buffers, and unlike mv it will not change the access and modify times on the file in the filesystem.
Try this function from Steve Yegge's .emacs:
;; source: http://steve.yegge.googlepages.com/my-dot-emacs-file
(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)))
(if (not filename)
(message "Buffer '%s' is not visiting a file!" name)
(if (get-buffer new-name)
(message "A buffer named '%s' already exists!" new-name)
(progn
(rename-file filename new-name 1)
(rename-buffer new-name)
(set-visited-file-name new-name)
(set-buffer-modified-p nil))))))
Take a look at that page, there's another really useful related function there, called "move-buffer-file".
If you're using Spacemacs then you get this behavior for free since it comes with an implementation of rename-current-buffer-file (based on magnars) that by default bound to SPC-f-R.
Emacs 26.3 (2020-04-03) has rename-file function which can be invoked using M-x rename-file for renaming the current file or any other file for that matter.
The excellent crux package has crux-rename-file-and-buffer (along with many other useful functions).
I know the post is sooo old but in all the answer I have found, nothing is more simple that what said Emacs in their tutorial:
M-x Dired (launch dired)
C-x C-q (toggle read only in dired)
change the filename like if it was just a line in a text file:
prev:
/home/okiw4n/Documents/project/light_script:
total used in directory 20 available 339.2 GiB
drwxr-xr-x. 2 okiw4n okiw4n 4096 Sep 7 09:07 .
drwxr-xr-x. 3 okiw4n okiw4n 4096 Sep 4 10:03 ..
-rw-r--r--. 1 okiw4n okiw4n 3594 Sep 7 08:39 explication.org
-rw-r--r--. 1 okiw4n okiw4n 85 Sep 4 10:09 script.sh
-rw-r--r--. 1 okiw4n okiw4n 3594 Sep 5 20:08 tuc.org~
after:
/home/okiw4n/Documents/project/light_script:
total used in directory 20 available 339.2 GiB
drwxr-xr-x. 2 okiw4n okiw4n 4096 Sep 7 09:07 .
drwxr-xr-x. 3 okiw4n okiw4n 4096 Sep 4 10:03 ..
-rw-r--r--. 1 okiw4n okiw4n 3594 Sep 7 08:39 explication.org
-rw-r--r--. 1 okiw4n okiw4n 85 Sep 4 10:09 script.sh
-rw-r--r--. 1 okiw4n okiw4n 3594 Sep 5 20:08 TRUC.org~ (I have rewrite this file)
C-x C-s (for save the changes)
C-x C-k (kill the buffer and return to the file).
I didn't find any of the proposed solutions sufficient for my needs (buffer selection, overwrite confirmation, fast response, actually working etc.), here's what I'm using:
(defun rename-buffer-and-file (buffer newname)
(interactive "bRename buffer and its visiting file: \nFNew name: ")
(let ((oldname (buffer-file-name)))
(if (not oldname)
(message "Buffer '%s' is not visiting a file" buffer)
(if (file-exists-p newname)
(if (file-directory-p newname)
;; Signal an error if the user specified the name of an
;; existing directory.
(error "%s is a directory" newname)
(unless (y-or-n-p (format-message
"File `%s' exists; overwrite? "
newname))
(error "Canceled"))))
;; Rename buffer and its visiting file
(set-visited-file-name newname)
;; Delete old file
(delete-file oldname)
(save-buffer))))
bound to C-x C-r for convenience with
(global-set-key (kbd "C-x C-r") 'rename-buffer-and-file)