2008-12-21 26 views

Trả lời

76

Hãy thử chức năng này từ 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)))))) 

Hãy nhìn vào trang đó, có một chức năng có liên quan thực sự hữu ích ở đó, gọi là "di chuyển-đệm-file".

+1

Lưu ý: phương pháp này là không tương thích với '(setq uniquify-đệm-tên-style 'phía trước)' ý nghĩa nếu bạn có đệm tên 'users \ index.html' (vì bạn đã có một bộ đệm khác cho 'posts \ index.html') việc đổi tên sẽ thất bại – dolzenko

+0

' (set-buffer-modified-p nil) 'có vẻ không cần thiết. Nếu bạn gọi 'rename-file-and-buffer' trên một bộ đệm đã sửa đổi và sau đó đã cố gắng để loại bỏ nó, nó sẽ vui vẻ làm điều đó mà không cảnh báo bạn về những thay đổi chưa được lưu. – roldugin

+0

Chức năng này cũng sẽ (hơi khó chịu) yêu cầu bạn nhập một tên mới * trước khi * kiểm tra xem bộ đệm hiện tại có được liên kết với một tệp nào không (trong trường hợp này nó sẽ hủy bỏ). – Thomas

284

Vâng, với chế độ dired, bạn có thể:

  • C-x C-j (dired-jump đến tên của tập tin hiện tại, trong Dired)
  • R để đổi tên tập tin (hoặc dired-do-rename).
  • C-x k RET để quay trở lại (đổi tên) tập tin đệm

Các đổi tên là tương đương với một vỏ mv, nhưng nó cũng sẽ cập nhật bất kỳ bộ đệm mở.

+8

Không trực tiếp đổi tên tệp hiện tại. – Pablo

+4

C-x b và bạn quay lại bộ đệm gốc. Bạn có thể viết một hàm Elisp để làm điều đó, nhưng tôi nghi ngờ bạn sẽ lưu nhiều lần nhấn phím với nó. –

+5

Ngoài ra, thay vì C-x b, bạn có thể nhấn C-x k để trở lại bộ đệm gốc. – Yoo

111

Chỉ để hoàn thành, vì một số người có thể truy cập trang này, họ sẽ nhận được câu trả lời cho tính năng "lưu dưới dạng" của Emacs, đó là C-x C-w cho tệp mở.

+0

C-x C-w hoặc sử dụng menu 'Tệp> Lưu dưới dạng ...' – Yoo

+0

Không hoàn toàn "lưu dưới dạng", vì tệp bạn đang chỉnh sửa vẫn sẽ là tệp gốc. – asmeurer

+9

@asmeurer Bạn sai rồi! Sau khi lưu, bạn sẽ chỉnh sửa tệp mới. – Droidzone

14

Dưới đây là phiên bản mạnh mẽ hơn được điều chỉnh từ 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

Chuyển sang thư mục mới không hoạt động với tôi :) – dolzenko

+0

Cảm ơn bạn rất nhiều. – lawlist

+0

Đẹp nhất. Bây giờ làm lạnh trong functions.el của tôi. –

-1

Có thể đạt được bằng bản sao. shift + c trên tập tin và emacs sẽ yêu cầu bạn biểu thị tên cho đường dẫn bao gồm tên tệp, vì vậy bạn chỉ cần cung cấp tên mới và nhập ... tất nhiên, bạn phải xóa tên cũ.

+0

Bạn dường như đang đề cập đến "C" ở chế độ được hướng dẫn? Đó là sao chép các tập tin, không đổi tên nó, mà (như @ ChrisConway lưu ý) trong dired được thực hiện với "R". Và bên cạnh đó, OP yêu cầu đổi tên bộ đệm hiện tại. –

10

Dưới đây là một phiên bản khác, đó là khá mạnh mẽ và VC biết:

(defun rename-file-and-buffer() 
    "Rename the current buffer and file it is visiting." 
    (interactive) 
    (let ((filename (buffer-file-name))) 
    (if (not (and filename (file-exists-p filename))) 
     (message "Buffer is not visiting a file!") 
     (let ((new-name (read-file-name "New name: " filename))) 
     (cond 
     ((vc-backend filename) (vc-rename-file filename new-name)) 
     (t 
      (rename-file filename new-name t) 
      (set-visited-file-name new-name t t))))))) 

Bạn có thể đọc thêm về nó here.

20

ưa thích của tôi là một trong những từ Magnars (của emacs rocks screencasts nổi tiếng.)

Không giống như các giải pháp thay thế khác, bạn không cần phải gõ tên ra từ đầu - bạn sẽ có được tên hiện tại để sửa đổi.

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

Cảm ơn James Yang về phiên bản chính xác.

+0

Điều này KHÔNG hoạt động đúng cách. Điều này thêm một "/" ở phần cuối của tập tin. – mythicalcoder

+0

Điều này tốt hơn http://stackoverflow.com/a/37456354/2369867 – mythicalcoder

+1

Cảm ơn bạn đã đăng bài đó cho tôi. Cách SO là sửa các câu trả lời, chứ không phải đăng các câu trả lời mới, được sửa đổi một chút. –

2

dựa trên phiên bản magnars, tôi sửa đổi như dưới đây, cố định phần INIT tên file:

(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

Cái này tốt hơn. Phiên bản magnars được đưa ra ở trên KHÔNG hoạt động đúng. Thêm ký tự "/" ở cuối – mythicalcoder

3

Có một cách rất dễ dàng, bạn nhấn lệnh Mx và hơn loại vc-rename- tập tin, sau đó bạn chỉ cần chọn tập tin hiện tại của bạn tại thư mục, và hơn chọn tên mới. Buff có tệp đã thay đổi sẽ được làm mới.

Nguồn:https://www.gnu.org/software/emacs/manual/html_node/emacs/VC-Delete_002fRename.html

+0

Điều này có tác dụng phụ (không nhất thiết mong muốn) khi thêm các tệp cũ và mới được cam kết vào kiểm soát phiên bản. Nhưng +1 vì nó sử dụng hàm dựng sẵn (chủ yếu) trả lời câu hỏi của OP. – dinosaur

Các vấn đề liên quan