Есть ли способ переименовать открытый файл в Emacs? Пока смотрю? Что-то вроде save-as, но оригинал должен уйти.
Как мне переименовать открытый файл в Emacs?
Ответы (12)
Попробуйте эту функцию из .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))))))
Взгляните на эту страницу, там есть еще одна действительно полезная связанная функция, которая называется "файл-буфера-перемещения".
(setq uniquify-buffer-name-style 'forward)
, что означает, что если у вас есть буфер с именем users\index.html
(потому что у вас уже есть другой буфер для posts\index.html
), переименование не удастся.
- person dolzenko; 27.09.2012
(set-buffer-modified-p nil)
кажется ненужным. Если вы вызвали rename-file-and-buffer
для измененного буфера, а затем попытались его убить, он с радостью сделает это, не предупреждая вас о несохраненных изменениях.
- person roldugin; 11.07.2013
Да, в режиме 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
сначала делает его связанным.
- person ntc2; 31.10.2013
quit-window
привязан к q
, так что это просто вопрос C-x C-j R [filename] RET q
. Насколько косвенно это на практике?
- person Francesco Napolitano; 16.06.2016
C-x C-j
не привязан, просто выполнить M-x dired-jump
в первый раз. Он автоматически загрузит dired-x
(что также приведет к определению C-x C-j
с этого момента).
- person Fernando Basso; 11.08.2016
dired-do-rename
однозначно переименовывает файл. Я не уверен, против чего возражает @pupeno.
- person ctpenrose; 04.12.2020
Просто для полноты, поскольку некоторые люди могут посетить эту страницу, думая, что они получат ответ на функцию Emacs «сохранить как», это C-x C-w для открытого файла.
File > Save as...
- person Yoo; 14.10.2010
Мне больше всего нравится снимок от 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)))))))
Спасибо Джеймсу Яну за правильную версию.
Вот более надежная версия, адаптированная от 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))
Вот еще одна версия, довольно надежная и поддерживающая 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)))))))
Подробнее об этом можно узнать здесь.
Если вы используете Spacemacs, вы получаете это поведение бесплатно, поскольку оно поставляется с реализацией rename-current-buffer-file
(на основе магнаров) который по умолчанию привязан к SPC-f-R
.
Есть очень простой способ: вы нажимаете команду Mx и затем набираете vc-rename-file, после чего вам просто нужно выбрать текущий файл в каталоге, и чем выбрать новое имя. Бафф с измененным файлом будет обновлен.
Источник: 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)))))))
Превосходный crux
пакет имеет crux-rename-file-and-buffer
(наряду со многими другими полезными функциями).
Emacs 26.3 (2020-04-03) имеет функцию rename-file
, которую можно вызвать с помощью M-x rename-file
для переименования текущего файла или любого другого файла, если на то пошло.
Этого можно добиться копированием. shift + c в файле, и emacs попросит вас указать имя для пути, включая имя файла, поэтому вы просто указываете новое имя и вводите ... конечно, вы должны удалить прежнее.