有没有办法在 Emacs 中重命名打开的文件?我在看的时候?类似另存为的东西,但原来的应该消失。
是的,使用 dired
模式,您可以:
Cx d 打开dired
RET 选择当前文件的目录
Cx Cj (dired-跳转到当前文件的名称,在 Dired 中)
R 重命名文件(或 dired-do-rename)。
返回(重命名的)文件缓冲区
重命名等效于 shell mv
,但它也会更新任何打开的缓冲区,并且与 mv
不同,它不会更改文件系统中文件的访问和修改时间。
只是为了完整起见,因为有些人可能会访问此页面,以为他们会得到 Emacs 的“另存为”功能的答案,即打开文件的 Cx Cw。
File > Save as...
从 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))))))
看看那个页面,那里还有另一个非常有用的相关函数,叫做“move-buffer-file”。
(setq uniquify-buffer-name-style 'forward)
不兼容,这意味着如果您有名为 users\index.html
的缓冲区(因为您已有 posts\index.html
的另一个缓冲区)重命名将失败
(set-buffer-modified-p nil)
似乎没有必要。如果您在修改后的缓冲区上调用 rename-file-and-buffer
然后试图杀死它,它会很高兴地执行此操作,而不会警告您未保存的更改。
我最喜欢的是 Magnars 的那个(emacs rocks screencasts 成名。)
与其他替代方案不同,您不必从头开始输入名称 - 您可以获得当前名称来修改。
(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)))))))
感谢 James Yang 的正确版本。
这是改编自 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)))))))
您可以阅读有关它的更多信息here。
如果您使用 Spacemacs,那么您可以免费获得此行为,因为它附带了一个默认绑定到 SPC-f-R
的 rename-current-buffer-file
(基于 magnars)的实现。
有一种方法很简单,你按下命令 Mx 然后输入 vc-rename-file ,然后你只需要在目录中选择你当前的文件,然后选择新的名称。已更改文件的 buff 将被刷新。
来源:https://www.gnu.org/software/emacs/manual/html_node/emacs/VC-Delete_002fRename.html
vc-rename-file
时得到这个,请在移动文件之前更新文件`
Emacs 26.3 (2020-04-03) 具有 rename-file
函数,可以使用 M-x rename-file
调用该函数来重命名当前文件或任何其他文件。
基于 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 会要求你为包含文件名的路径指定一个名称,所以你只需提供新名称,然后输入...当然,你必须删除前一个。
不定期副业成功案例分享
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
)。