2008-12-21 11 views

Odpowiedz

76

Wypróbuj tę funkcję od 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)))))) 

Spójrz na tej stronie, nie ma innego bardzo przydatna funkcja powiązany tam, zwany "move-buffer-file".

+1

Uwaga: ta metoda nie jest kompatybilny z '(setq uniquify-bufor-name-style„do przodu) 'znaczenia, jeśli masz bufor o nazwie' Users \ index.html' (bo Ciebie już ma inny bufor dla 'posts \ index.html') zmiana nazwy nie powiedzie się – dolzenko

+0

' (set-buffer-modified-p nil) 'wydaje się niepotrzebna. Jeśli wywołałeś 'rename-file-and-buffer' na zmodyfikowanym buforze, a następnie próbowałeś go zabić, z przyjemnością zrobiłbyś to bez ostrzeżenia o niezapisanych zmianach. – roldugin

+0

Ta funkcja również (nieco denerwująco) poprosi cię o nową nazwę * przed * sprawdzenie, czy bieżący bufor jest w ogóle powiązany z plikiem (w takim przypadku jest on przerywany). – Thomas

284

Tak, w trybie dired można:

  • C-x C-j (dired-jump do nazwy bieżącego pliku, w DIRED)
  • R aby zmienić nazwę pliku (lub dired-do-rename).
  • C-x k RET wrócić do bufora pliku (przemianowany)

zmiany nazwy jest równoważne powłoce mv, ale również aktualizować wszystkie otwarte bufory.

+8

To nie jest bezpośrednio zmiana nazwy bieżącego pliku. – Pablo

+4

C-x b i wróciłeś do oryginalnego bufora. Możesz napisać funkcję Elisp, żeby to zrobić, ale wątpię, że zachowasz przy tym wiele klawiszy. –

+5

Ponadto, zamiast C-x b, można nacisnąć C-x k, aby powrócić do oryginalnego bufora. – Yoo

111

Tylko dla kompletności, ponieważ niektórzy mogą odwiedzać tę stronę, myśląc, że dostaną odpowiedź na funkcję "zapisz jako" Emacsa, to C-x C-w dla otwartego pliku.

+0

C-x C-w lub użyj menu 'Plik> Zapisz jako ...' – Yoo

+0

Nie całkiem "zapisz jako", ponieważ plik, który edytujesz, będzie nadal oryginalny. – asmeurer

+9

@memeurer Jesteś w błędzie! Po zapisaniu będziesz edytować nowy plik. – Droidzone

14

Oto bardziej solidna wersja dostosowana z 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

Przeprowadzka do nowego dra nie zadziałała dla mnie :) – dolzenko

+0

Dziękuję bardzo. – lawlist

+0

Niezły. Teraz chłodzenie w moim functions.el. –

-1

Można to osiągnąć, kopiując. shift + c do pliku, a emacs poprosi cię o podanie nazwy ścieżki zawierającej nazwę pliku, więc podaj tylko nową nazwę i wpisz ... oczywiście, musisz usunąć poprzednią.

+0

Wydaje się, że odnosisz się do "C" w trybie diredowym? To jest kopiowanie pliku, nie zmieniając jego nazwy, co (jak zauważył @ChrisConway) w diredach jest wykonywane z "R". Poza tym OP poprosił o zmianę nazwy bieżącego bufora. –

10

Oto kolejna wersja, że ​​to całkiem solidna i VC świadomy:

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

Możesz przeczytać więcej na ten temat here.

20

Moim ulubionym jest jednym z Magnars (od emacs rocks screencasts sławy.)

przeciwieństwie do innych alternatyw, nie trzeba wpisywać nazwy się od zera - dostaniesz obecna nazwa zmodyfikować.

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

Podziękowania dla Jamesa Yang za poprawną wersję.

+0

To NIE działa poprawnie. Ten dodaje "/" na końcu pliku. – mythicalcoder

+0

To jest lepsze http://stackoverflow.com/a/37456354/2369867 – mythicalcoder

+1

Dzięki za opublikowanie tego dla mnie. Jednym ze sposobów jest poprawianie odpowiedzi, a nie nowych, nieznacznie zmodyfikowanych. –

2

na podstawie wersji magnars, I zmodyfikowane jak poniżej, stała się częścią nazwy pliku INIT:

(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

Ten jest lepszy. Podana powyżej wersja magnars NIE działa poprawnie. Dodaj znak "/" na końcu – mythicalcoder

3

istnieje sposób bardzo prosty, po naciśnięciu polecenia Mx i od rodzaju vc-rename- plik, po tym wystarczy wybrać bieżący plik w katalogu, a następnie wybrać nową nazwę. Buff, który ma zmieniony plik, zostanie odświeżony.

Źródło:https://www.gnu.org/software/emacs/manual/html_node/emacs/VC-Delete_002fRename.html

+0

Ma to (niekoniecznie pożądany) efekt uboczny dodawania starych i nowych plików do zatwierdzenia wersji. Ale +1, ponieważ używa wbudowanej funkcji do (w większości) odpowiedzi na pytanie OP. – dinosaur

Powiązane problemy