How do I rename an open file in Emacs?

Viewed 83679

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.

14 Answers

Yes, with dired mode, you can:

  • C-x d to open dired
  • RET to select directory of current file
  • C-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 buffer

The 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".

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)
Related