Există o modalitate de a redenumi un fișier deschis în Emacs? În timp ce îl vizualizez? Ceva de genul save-as, dar cel original ar trebui să dispară.
Încercați această funcție din .emacs al lui Steve Yegge:
;; 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))))))
Aruncați o privire la acea pagină, există o altă funcție conexă foarte utilă acolo, numită „move-buffer-file”.
Da, cu dired
se poate:
C-x d
pentru a deschide diredRET
pentru a selecta directorul fișierului curentC-x C-j
(dired-jump
la numele fișierului curent, în Dired)R
să redenumiți fișierul (saudired-do-rename
).q
pentru a reveni la memoria tampon a fișierului (redenumit)
Redenumirea este echivalentă cu un shell mv
, dar va actualiza, de asemenea, orice buffer deschis și, spre deosebire de mv
nu va schimba timpii de acces și de modificare a fișierului în sistemul de fișiere.
- Aceasta nu redenumește direct fișierul curent. – > .
- C-x b și te întorci în bufferul original. Ați putea scrie o funcție Elisp pentru a face acest lucru, dar mă îndoiesc că veți economisi multe apăsări de taste cu ea. – > .
- De asemenea, în loc de C-x b, puteți apăsa C-x k pentru a vă întoarce în bufferul original. – > .
-
C-x C-j
nu este legat în mod implicit pentru mine. FacândM-x load-library RET dired-x RET
mai întâi îl face legat. – > . - O altă alternativă dacă
C-x C-j
este nelegat, este de a face doarM-x dired-jump
prima dată. Se va încărca automatdired-x
(ceea ce va determina, de asemenea, caC-x C-j
să fie definită din acest moment). – > .
34
Doar pentru a fi complet, deoarece unii oameni ar putea vizita această pagină crezând că vor primi un răspuns pentru funcția „save as” din Emacs, asta înseamnă C-x C-w pentru un fișier deschis.
- C-x C-w sau folosiți meniul
File > Save as...
– > . - Nu este chiar „save as”, deoarece fișierul pe care îl editați va fi în continuare cel original. – > .
- @asmeurer Te înșeli! După salvare, veți edita noul fișier. – > .
- Din nou, de ce nu există o funcție pentru a vota în jos comentariile!!! – > .
- Poate că asmeurer a vrut să spună: „fișierul pe care îl [editai] va continua să [existe]”. Atunci, este corect? Aș verifica, dar atunci, nu poți să dai downvote la comentariul meu, hahaha. – > .
Preferata mea este cea de la Magnars (de emacs rocks screencasts (emacs rocks screencasts) faimos.)
Spre deosebire de celelalte alternative, nu trebuie să tastați numele de la zero – primiți numele curent pentru a-l modifica.
(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)))))))
Mulțumiri lui James Yang pentru o versiune corectă.
- Aceasta NU funcționează corect. Aceasta adaugă un „/” la sfârșitul fișierului. – > .
- Mulțumesc că ai postat asta pentru mine. Modul SO este de a corecta răspunsurile, nu de a posta răspunsuri noi, ușor modificate. – > .
Iată o versiune mai robustă adaptată de la 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))
- Frumos. Acum se răcește în funcțiile mele.el. – > .
Iată o altă versiune, care este destul de robustă și conștientă de VC:
(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)))))))
Puteți citi mai multe despre ea aici.
Dacă utilizați Spacemacs atunci primiți acest comportament gratuit, deoarece vine cu o implementare a lui rename-current-buffer-file
(bazată pe magnars) care, în mod implicit, este legată de SPC-f-R
.
- Tocmai am testat acest lucru în Doom Emacs (v27.1) și funcționează la fel de bine. Vă mulțumesc. – > .
Există o modalitate foarte ușoară, apăsați comanda M-x și apoi tastați vc-rename-file, după care trebuie doar să selectați fișierul curent din director și apoi să alegeți noul nume. Buf-ul care conține fișierul modificat va fi actualizat.
Sursă:https://www.gnu.org/software/emacs/manual/html_node/emacs/VC-Delete_002fRename.html
- Acest lucru are efectul secundar (nu neapărat de dorit) de a adăuga fișierele vechi și noi care urmează să fie trimise în controlul versiunilor. Dar +1, deoarece folosește o funcție încorporată pentru a răspunde (în mare parte) la întrebarea lui OP. – > .
- Funcționează chiar și astăzi cu GNU Emacs 25.3.2 (x86_64-pc-linux-gnu, GTK+ Version 3.18.9) – > .
pe baza versiunii magnars, am modificat ca mai jos, am fixat partea cu numele fișierului 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)))))))
- Aceasta este mai bună. Versiunea magnars dată mai sus NU funcționează corect. Adăugați un caracter „/” la sfârșit – > .
Emacs 26.3 (2020-04-03) are rename-file
care poate fi invocată cu ajutorul funcției M-x rename-file
pentru redenumirea fișierului curent sau a oricărui alt fișier.
Excelentul crux
pachet are crux-rename-file-and-buffer
(împreună cu multe alte funcții utile).
Se poate realiza prin copiere. shift+c pe fișier și emacs vă va cere să denotați un nume pentru calea de acces, inclusiv numele fișierului, deci trebuie doar să furnizați noul nume,și să introduceți…desigur, trebuie să îl ștergeți pe cel anterior.
- Se pare că vă referiți la „C” în modul dired? Asta înseamnă copierea fișierului, nu redenumirea acestuia, care (după cum a observat @ChrisConway) în dired se face cu „R”. Și, în plus, OP a cerut o redenumire a bufferului curent. – > .
(setq uniquify-buffer-name-style 'forward)
ceea ce înseamnă că dacă aveți un buffer numitusersindex.html
(deoarece aveți deja un alt buffer pentrupostsindex.html
), redenumirea va eșua – > Por dolzenko.(set-buffer-modified-p nil)
pare inutilă. Dacă ați apelatrename-file-and-buffer
pe un buffer modificat și apoi ați încercat să îl omorâți, acesta ar face acest lucru cu plăcere fără să vă avertizeze cu privire la modificările nesalvate. – > Por roldugin.