How do I rename an open file in Emacs?

后端 未结 11 1665
别跟我提以往
别跟我提以往 2020-12-07 07:03

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.

相关标签:
11条回答
  • 2020-12-07 07:21

    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.

    https://github.com/syl20bnr/spacemacs/blob/bd7ef98e4c35fd87538dd2a81356cc83f5fd02f3/layers/%2Bdistributions/spacemacs-base/funcs.el#L294

    0 讨论(0)
  • 2020-12-07 07:23

    based on magnars version, I modified as below, fixed the INIT file name part:

    (defun rename-current-buffer-file ()
      "Renames current buffer and file it is visiting."
      (interactive)
      (let* ((name (buffer-name))
            (filename (buffer-file-name))
            (basename (file-name-nondirectory filename)))
        (if (not (and filename (file-exists-p filename)))
            (error "Buffer '%s' is not visiting a file!" name)
          (let ((new-name (read-file-name "New name: " (file-name-directory filename) basename nil basename)))
            (if (get-buffer new-name)
                (error "A buffer named '%s' already exists!" new-name)
              (rename-file filename new-name 1)
              (rename-buffer new-name)
              (set-visited-file-name new-name)
              (set-buffer-modified-p nil)
              (message "File '%s' successfully renamed to '%s'"
                       name (file-name-nondirectory new-name)))))))
    
    0 讨论(0)
  • 2020-12-07 07:23

    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.

    0 讨论(0)
  • 2020-12-07 07:25

    My favorite is the one from Magnars (of emacs rocks screencasts fame.)

    Unlike the other alternatives, you don't have to type the name out from scratch - you get the current name to modify.

    (defun rename-current-buffer-file ()
      "Renames current buffer and file it is visiting."
      (interactive)
      (let* ((name (buffer-name))
            (filename (buffer-file-name))
            (basename (file-name-nondirectory filename)))
        (if (not (and filename (file-exists-p filename)))
            (error "Buffer '%s' is not visiting a file!" name)
          (let ((new-name (read-file-name "New name: " (file-name-directory filename) basename nil basename)))
            (if (get-buffer new-name)
                (error "A buffer named '%s' already exists!" new-name)
              (rename-file filename new-name 1)
              (rename-buffer new-name)
              (set-visited-file-name new-name)
              (set-buffer-modified-p nil)
              (message "File '%s' successfully renamed to '%s'"
                       name (file-name-nondirectory new-name)))))))
    

    Thanks to James Yang for a correct version.

    0 讨论(0)
  • 2020-12-07 07:28

    Just for completeness, since some folks may visit this page thinking they will get an answer for the "save as" feature of Emacs, that's C-x C-w for an open file.

    0 讨论(0)
  • 2020-12-07 07:33

    Here's a more robust version adapted from stevey.

    ;; Originally from stevey, adapted to support moving to a new directory.
    (defun rename-file-and-buffer (new-name)
      "Renames both current buffer and file it's visiting to NEW-NAME."
      (interactive
       (progn
         (if (not (buffer-file-name))
             (error "Buffer '%s' is not visiting a file!" (buffer-name)))
         ;; Disable ido auto merge since it too frequently jumps back to the original
         ;; file name if you pause while typing. Reenable with C-z C-z in the prompt.
         (let ((ido-auto-merge-work-directories-length -1))
           (list (read-file-name (format "Rename %s to: " (file-name-nondirectory
                                                           (buffer-file-name))))))))
      (if (equal new-name "")
          (error "Aborted rename"))
      (setq new-name (if (file-directory-p new-name)
                         (expand-file-name (file-name-nondirectory
                                            (buffer-file-name))
                                           new-name)
                       (expand-file-name new-name)))
      ;; Only rename if the file was saved before. Update the
      ;; buffer name and visited file in all cases.
      (if (file-exists-p (buffer-file-name))
          (rename-file (buffer-file-name) new-name 1))
      (let ((was-modified (buffer-modified-p)))
        ;; This also renames the buffer, and works with uniquify
        (set-visited-file-name new-name)
        (if was-modified
            (save-buffer)
          ;; Clear buffer-modified flag caused by set-visited-file-name
          (set-buffer-modified-p nil)))
    
      (setq default-directory (file-name-directory new-name))
    
      (message "Renamed to %s." new-name))
    
    0 讨论(0)
提交回复
热议问题