(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))
- 这里 interactive 后面接的不是 “p” 这样的 code, 而是一个别的函数, 意义是什么? 对此我看了文档, 文档举了一个这样的例子:
For example, write (defun foo (arg buf) "Doc string" (interactive "P\nbbuffer: ") .... ) to make ARG be the raw prefix argument, and set BUF to an existing buffer, when ‘foo’ is called as a command.
- 函数有参数 new-file, 如果直接执行 M-x rename-file-and-buffer, 也不会出错, 但函数定义中有一行是:
(if (equal new-name "") (error "Aborted rename"))
按理说就应该出错. 为什么没出错呢? 怀疑与 interactive 这个问题有关.