如何在 Emacs Dired 的子目录中创建文件?

How can I create a file in a sub-directory in Emacs Dired?

我使用 dired 浏览目录及其子目录 i (dired-maybe-insert-subdir)

当光标在子目录中时,我 C-x C-f,默认目录是我缓冲区的根目录,有没有办法改变它?

因此,如果我访问 /foo/bar,然后在栏的缓冲区中插入 /foo/bar/baz 的内容并将光标放在那里,当我在 /foo/bar/baz/ 时获得一个迷你缓冲区要求访问文件(使用默认键绑定或其他,这对我来说无关紧要)。

不,default-directory 是缓冲区本地的,而不仅仅是缓冲区的一部分。这是设计使然,无法更改。

但是您当然可以定义一个命令来获取子目录,然后在读取要访问的文件名时将 default-directory 绑定到该目录,等等)。

例如,这个命令将读取一个文件名,默认目录是你想要的,然后访问该文件:

(defun foo (file)
  "..."
  (interactive
   (let ((default-directory  (dired-current-directory)))
     (list (read-file-name "File: "))))
  (find-file file))

而且,开箱即用,您当然可以访问另一个 Dired 缓冲区中的子目录,其中 default-directory 就是您想要的。 dired-do-find-marked-files (F) 和 dired-display-file (C-o) 这样的命令.

但是为什么要 default-directory 反映您所在列表的子目录?你的用例是什么?

我将 精炼为一个完全符合我要求的函数:

(defun dired-find-file ()
  "Find a file in the current dired directory"
  (interactive)
  (let ((default-directory (dired-current-directory)))
    (find-file (read-file-name "Find file:"))))

然后我将此功能绑定到一个方便的组合键:

(add-hook 'dired-mode-hook
   (lambda ()
     (local-set-key (kbd "C-x M-f") 'dired-find-file)))

以下是我自己的解决方法

(defun dired-subdir-aware (orig-fun &rest args)
  (if (eq major-mode 'dired-mode)
      (let ((default-directory (dired-current-directory)))
        (apply orig-fun args))
    (apply orig-fun args)))

(advice-add 'find-file-read-args :around 'dired-subdir-aware)

我刚刚学会了如何使用建议函数来扩充现有函数(和宏)。参见 (elisp) Advising Functions

现在,如果您转到 dired 和 运行 C-x C-f 下的子目录,系统将提示您输入正确的路径。

更新:

最近开始玩(ido) Top。定义 dired-subdir-aware 后,我可以轻松扩展 ido-find-file 以使用以下代码识别子目录。

(dolist (fun '(find-file-read-args ido-expand-directory))
  (advice-add fun :around 'dired-subdir-aware))