1

How can I insert multiple unrelated (non-subdirectory) directories into one dired buffer? In my case, I'd like to prepare a dired buffer containing unrelated directories with multiple file changes (e.g., in 'wdired' mode with multiple renames and changes, or simply with multiple marks across different directories), doublecheck them visually, and then execute them with one keystroke.

1 Answer 1

3
+50

Provide a list of strings, instead of a directory name, as the (first) argument to function dired.

  • The first element in the list is the name of the Dired buffer.

  • The other elements in the list are directory or file names.

The resulting Dired buffer will have a line for each element in the list.

Any directory listed can of course be inserted (i.e. expanded to its file listing) by using i on it in the Dired buffer.

For example, evaluate this:

(dired-other-window '("my dired buffer" DIR1 FILE1 DIR2 FILE2 FILE3))

where the DIRN are directory names (strings) and the FILEN are file names (strings). You can use absolute names or names relative to the current value of default-directory.

The result here is Dired buffer my dired buffer, with lines for directories DIR1 and DIR2 and files FILE1, FILE2, and FILE3.

Not sure I follow the rest of your question. But the resulting Dired buffer from the above is a normal Dired buffer. You can use wdired to allow changes etc.


Update #1, after your comment --

Good point. Yes, Dired's i (dired-maybe-insert-subdir) requires that all of the inserted subdirs belong to the same directory tree. I don't know why. Perhaps some of the code (and there is a lot of it to consider), perhaps dealing with handling of ls, depends on that. Or perhaps it is a restriction that is not really necessary.

One way to deal with (work around) this restriction is to start at a common ancestor directory to all of the subdirs that you include in the listing. IOW start by doing M-x cd to that common ancestor directory, before creating your Dired buffer. At the extreme, this would mean M-x cd to the root directory. That will definitely work in all cases. You will likely need to use absolute file names for the dirs and files that you pass to dired for the listing.

But as you say, if you use MS Windows and the dirs are on different drive letters, then this is not a solution.

Below is another thing you can try. Dunno whether it might cause problems somewhere else. (I'd be interested in knowing what problems you encounter, if it does. See the file header of library dired+.el for contact info.)

Copy the source code for these two functions from file dired-aux.el: dired-insert-subdir and dired-insert-subdir-newpos, and then modify the copies as follows:

  • For dired-insert-subdir, comment out this line:

    (dired-insert-subdir-validate dirname switches)
    
  • For dired-insert-subdir-newpos, change the code to this:

    (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))
    

Then load your modified code after loading the vanilla Dired code, effectively replacing the original functions. (Alteratively, you could advise those functions.)

This seems to make things work as expected, obviating the need to start from a common ancestor dir. But as I say, I don't know whether some other parts of the Dired (or the Wdired) code might be bothered by such a change. Just experiment a bit.

Note, however, that dired-insert-subdir-validate actually checks two things, only one of which should be removed, perhaps (?). Besides checking whether the subdir to be inserted is in the same dir tree, it checks whether ls switches for it are compatible with those of the overall listing. I haven't noticed a problem with removing dired-insert-subdir-validate altogether, but if this switches check is really important then you can try just removing this part of the dired-insert-subdir-validate code, which checks the dir tree:

  (or (dired-in-this-tree dirname (expand-file-name default-directory))
      (error  "%s: not in this directory tree" dirname))

If it seems that such code changes do not have unwanted side effects that cannot be fixed easily, I will consider adding them to Dired+.

Thanks for bringing this to my attention. I guess I usually create such listings from a common ancestor, so I haven't been noticed this limitation before.


BTW -- I filed Emacs "bug" #18421 for this enhancement request: let Dired accommodate directory listings that are not from the same tree.


* UPDATE #2 *

I've added this feature to Dired+.

I modified the definitions of C-x d (dired), C-x 4 d (dired-other-window), and C-x 5 d (dired-other-frame) so that if you use a non-positive prefix arg (e.g., C-- C-x d) then you are prompted for (1) the Dired buffer name (anything you like, not necessarily a directory name) and (2) the individual files or directories that you want listed.

A non-negative prefix arg still prompts you for the ls switches to use. (So C-0 does both: prompts for switches and for buffer name and files to list.)

I fixed i (dired-maybe-insert-subdir) so that it works with arbitrary directories. And you can of course still use a prefix arg with i to specify different ls switches to use for the inserted subdir listing.

4
  • Under Windows Emacs 23.1.1, hitting 'i' refuses to insert the directory, complaining "<my-dir>: not in this directory tree". Do you see the same thing? Since the directories I'm interested in are under two different drive letters, I can't start dired under a single directory that contains both as subdirs.
    – user38983
    Sep 6, 2014 at 22:16
  • Right - see my update to the answer. Let me know what you find out.
    – Drew
    Sep 7, 2014 at 15:36
  • FWIW, I updated Dired+ to support this. Dunno whether any problems will be reported with it. Seems to work OK so far.
    – Drew
    Sep 7, 2014 at 20:01
  • O-okay. Submit a request, and get an answer and a fix. Download the fix, and find out that the library's author put the fix in and has been answering my other emacs questions as well. I tried this and it met my needs perfectly for over a month at this point.
    – user38983
    Jan 10, 2015 at 23:04

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .