Відповіді:
Спробуйте цю функцію від .emacs Стіва Йегге :
;; джерело: http://steve.yegge.googlepages.com/my-dot-emacs-file
(розблокувати перейменувати файл-і-буфер (нове ім'я)
"Перейменує поточний буфер і файл, який він відвідує, в NEW-NAME."
(інтерактивне "sNew name:")
(нехай ((ім'я (ім'я буфера))
(ім'я файлу (буфер-ім’я файлу)))
(якщо (не ім'я файлу)
(повідомлення "Буфер"% s "не відвідує файл!")
(якщо (get-buffer new-name)
(повідомлення "Буфер з назвою"% s "вже існує!")
(прогн
(перейменувати-ім'я файлу new-name 1)
(перейменувати буфер нового імені)
(set-visit-file-name new-name)
(набір-буфер-змінено-p nil))))))
Погляньте на цю сторінку, там є ще одна справді корисна пов'язана функція, яка називається "move-buffer-file".
(set-buffer-modified-p nil)здається непотрібним. Якщо ви запустили rename-file-and-bufferмодифікований буфер, а потім спробували його вбити, він із задоволенням зробить це, не попереджаючи вас про незбережені зміни.
Так, за допомогою diredрежиму ви можете:
C-x d відкрити дірRET вибрати каталог поточного файлуC-x C-j( dired-jumpдо імені поточного файлу в Dired)Rперейменувати файл (або dired-do-rename).q щоб повернутися до (перейменованого) файлового буфераПерейменування еквівалентно оболонці mv, але воно також оновить будь-які відкриті буфери, і на відміну від mvцього не змінить доступ та змінить час файлу у файловій системі.
C-x C-jза замовчуванням не пов'язане. Роблячи M-x load-library RET dired-x RETперший робить це неминуче.
C-x C-jвона не пов'язана - це просто зробити M-x dired-jumpз першого разу. Він автоматично завантажується dired-x(що також C-x C-jбуде визначено з цього моменту).
Просто для повноти, оскільки деякі люди можуть завітати на цю сторінку, думаючи, що вони отримають відповідь за функцію "зберегти як" Emacs, це Cx Cw для відкритого файлу.
File > Save as...
Мій улюблений - той із Magnars (про екрани слави екранів Emacs .)
На відміну від інших альтернатив, вам не доведеться вводити ім’я з нуля - ви отримуєте поточне ім’я для зміни.
(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)))))))
Дякуємо Джеймсу Ян за правильну версію.
Ось більш надійна версія, адаптована зі стеві.
;; 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))
Ось ще одна версія, яка є досить надійною і знає:
(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)))))))
Більше про це можна прочитати тут .
Якщо ви використовуєте Spacemacs, ви отримуєте таку поведінку безкоштовно, оскільки вона реалізується з реалізацією rename-current-buffer-file(заснованої на магнарах), до якої за замовчуванням прив’язана SPC-f-R.
Є спосіб дуже простий, ти натискаєш команду Mx і потім набираєш набираєш vc-rename-файл , після чого потрібно просто вибрати поточний файл у каталозі, а потім вибрати нове ім'я. Баф із зміненим файлом буде оновлений.
Джерело: https://www.gnu.org/software/emacs/manual/html_node/emacs/VC-Delete_002fRename.html
На основі версії Magnars я змінив, як показано нижче, виправив частину імені файлу 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)))))))
Це можна досягти за допомогою копії. shift + c у файлі, а emacs попросить вас позначити ім'я для шляху, включаючи ім'я файлу, тому ви просто вкажете нове ім'я та введіть ... звичайно, вам потрібно видалити попереднє.
(setq uniquify-buffer-name-style 'forward)значенням, якщо у вас є ім'я буфераusers\index.html(оскільки у вас вже є інший буферposts\index.html), перейменування не вдасться