一个 Dired 缓冲区中有多个不相关的目录

一个 Dired 缓冲区中有多个不相关的目录

如何将多个不相关的(非子目录)目录插入到一​​个 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,其中包含目录DIR1DIR2文件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 ddired),C-x 4 ddired-other-window), 和C-x 5 ddired-other-frame)这样如果您使用非正前缀参数(例如C-- C-x d),那么系统会提示您输入(1)Dired 缓冲区名称(任何您喜欢的名称,不一定是目录名称)和(2)您想要列出的单个文件或目录。

非负前缀参数仍会提示您ls使用开关。(C-0提示开关和要列出的缓冲区名称和文件也是如此。)

我解决了i( dired-maybe-insert-subdir) 以便它适用于任意目录。当然,您仍然可以使用前缀参数来i指定ls用于插入子目录列表的不同开关。

相关内容