如何将多个不相关的(非子目录)目录插入到一个 dired 缓冲区中?就我而言,我想准备一个 dired 缓冲区,其中包含具有多个文件更改的不相关目录(例如,在 'wdired' 模式下具有多个重命名和更改,或者只是在不同目录中具有多个标记),目视检查它们,然后通过一次击键执行它们。
答案1
提供一个字符串列表(而不是目录名称)作为函数的(第一个)参数dired
。
列表中的第一个元素是 Dired 缓冲区的名称。
列表中的其他元素是目录或文件名。
生成的 Dired 缓冲区将为列表中的每个元素分配一行。
当然,可以i
在 Dired 缓冲区中使用列出的任何目录来插入(即扩展到其文件列表)。
例如,评估这一点:
(dired-other-window '("my dired buffer" DIR1 FILE1 DIR2 FILE2 FILE3))
其中DIRN
是目录名称(字符串), 是FILEN
文件名(字符串)。您可以使用绝对名称或相对于 的当前值的名称default-directory
。
此处的结果是 Dired 缓冲区my dired buffer
,其中包含目录DIR1
和DIR2
文件FILE1
、、FILE2
和的行FILE3
。
我不确定我是否理解了您问题的其余部分。但上面生成的 Dired 缓冲区是正常的 Dired 缓冲区。您可以使用它wdired
来允许更改等。
更新 #1,在您的评论之后——
说得好。是的,Dired 的i
( dired-maybe-insert-subdir
) 要求所有插入的子目录都属于同一目录树。我不知道为什么。也许部分代码(有很多需要考虑)——也许处理 ——ls
取决于此。或者也许这是一个并非真正必要的限制。
处理(解决)此限制的一种方法是,从列表中包含的所有子目录的共同祖先目录开始。换句话说,M-x cd
在创建 Dired 缓冲区之前,先对该共同祖先目录进行操作。在极端情况下,这意味着M-x cd
到根目录。这在所有情况下都绝对有效。您可能需要对传递给列表的目录和文件使用绝对文件名dired
。
但是正如您所说,如果您使用 MS Windows,并且目录位于不同的驱动器号上,那么这不是解决方案。
下面是您可以尝试的另一件事。不知道它是否会在其他地方引起问题。(如果确实如此,我很想知道您遇到了什么问题。请参阅库的文件头dired+.el
了解联系方式。
dired-aux.el
从文件:dired-insert-subdir
和中复制这两个函数的源代码dired-insert-subdir-newpos
,然后对副本进行如下修改:
对于
dired-insert-subdir
,注释掉此行:(dired-insert-subdir-validate dirname switches)
对于
dired-insert-subdir-newpos
,将代码更改为:(defun dired-insert-subdir-newpos (new-dir) ;; Find pos for new subdir, according to tree order. (let ((alist dired-subdir-alist) elt dir new-pos) (while alist (setq elt (car alist) alist (cdr alist) dir (car elt)) (if (dired-tree-lessp dir new-dir) ;; Insert NEW-DIR after DIR (setq new-pos (dired-get-subdir-max elt) alist ()) (setq new-pos (point-max)))) (goto-char new-pos)) ;; want a separating newline between subdirs (unless (eobp) (forward-line -1)) (insert "\n") (point))
然后在加载原始 Dired 代码后加载修改后的代码,从而有效地替换原始函数。(或者,您可以建议这些函数。)
这似乎使事情按预期进行,无需从共同祖先目录开始。但正如我所说,我不知道 Dired(或 Wdired)代码的其他部分是否会受到这种变化的影响。只需进行一些实验即可。
但请注意,这dired-insert-subdir-validate
实际上检查了两件事,也许只有其中一件事应该被删除(?)。除了检查要插入的子目录是否在同一目录树中,它还检查它ls
的开关是否与整个列表的开关兼容。我没有注意到dired-insert-subdir-validate
完全删除的问题,但如果这个开关检查真的很重要,那么您可以尝试只删除代码的这一部分dired-insert-subdir-validate
,该部分检查目录树:
(or (dired-in-this-tree dirname (expand-file-name default-directory))
(error "%s: not in this directory tree" dirname))
如果看起来这样的代码更改没有无法轻易修复的不良副作用,我会考虑将它们添加到迪雷德+。
感谢您提醒我注意这一点。我想我通常都是从共同祖先创建此类列表,所以之前我没有注意到这个限制。
顺便说一句 —— 我针对这个增强请求提交了 Emacs“bug”#18421:让 Dired 容纳不来自同一棵树的目录列表。
*更新 #2*
我已经将此功能添加到迪雷德+。
我修改了C-x d
(dired
),C-x 4 d
(dired-other-window
), 和C-x 5 d
(dired-other-frame
)这样如果您使用非正前缀参数(例如C-- C-x d
),那么系统会提示您输入(1)Dired 缓冲区名称(任何您喜欢的名称,不一定是目录名称)和(2)您想要列出的单个文件或目录。
非负前缀参数仍会提示您ls
使用开关。(C-0
提示开关和要列出的缓冲区名称和文件也是如此。)
我解决了i
( dired-maybe-insert-subdir
) 以便它适用于任意目录。当然,您仍然可以使用前缀参数来i
指定ls
用于插入子目录列表的不同开关。