4

How can I define two separate directories, create a virtual directory out of them in dired, and also bookmark that? I want to launch the bookmark and get the combined view.

I know dired+ has something close, but as far as I can tell, this gives you a list of directories. Iwant the content of these directories instead.

1 Answer 1

5

A. Wrt the Dired union buffer part of your question:

Yes, take another look at Dired+, in particular, C-x D (command diredp-dired-union).

If you have some Dired buffers whose contents you want to combine, say dirbuf1, dirbuf2, and dirbuf3, then use:

C-x D my-union-dired-buf RET dirbuf1 RET dirbuf2 RET dirbuf3 RET C-g

That is:

  • my-union-dired-buf to name the Dired buffer to use. (You can also add the contents of dirs to an existing Dired buffer.)

  • dirbuf1, dirbuf2, and dirbuf3 to specify the Dired buffers whose contents you want to combine.

  • C-g to say you're done.

If you do not have existing Dired buffers, and you want to create a Dired buffer whose contents combines the contents of multiple directories, say dir1, dir2 and dir3, then use a negative prefix arg with C-x D:

M-- C-x D my-union-dired-buf RET dir1/* RET dir2/* RET C-g

That is:

  • M-- to tell diredp-dired-union you will specify dirs to include (not necessarily dirs in Dired buffers).

  • my-union-dired-buf to name the Dired buffer to use. (You can also add the contents of dirs to an existing Dired buffer.)

  • dir1/*, dir2/*, and dir3/* to specify that you want the contents of those directories. (Specify the directories either relative to the current default-directory or as absolute names.)

  • C-g to say you're done.

In this example, if you used, say, dir2 instead of dir2/* then you would get a Dired buffer with the contents of dir1 and dir3 and a single line for directory dir2/. The glob pattern dir2/* means all files and subdirectories in directory dir2 (directly, as children, not recursively, as descendants).

C-h f diredp-dired-union:

diredp-dired-union is an interactive compiled Lisp function in dired+.el.

It is bound to menu-bar subdir diredp-dired-union, C-x D.

(diredp-dired-union DIRED-NAME DIRBUFS &optional SWITCHES EXTRA)

Create a Dired buffer that is the union of some existing Dired buffers. With a non-negative prefix arg, you are prompted for ls switches. With a non-positive prefix arg, you are prompted for file and dir names to add to the listing - see below.

You are prompted for the name of the Dired union buffer. Completion against names of existing Dired buffers is available, but you can enter any other name to create a new Dired buffer of that name.

If the union buffer name you choose names an existing Dired buffer, then what happens depends on whether that buffer is an ordinary Dired directory listing or a list of arbitrary file names. That is, it depends on whether dired-directory is a directory name or a cons of a Dired buffer name plus file names.

  • If the buffer is an ordinary Dired listing, then it is converted to an explicit list of absolute file names, just as if these had been chosen individually. The existing buffer and window are replaced by new ones that show the explicit listing. (This replacement is necessary because the list of files contained in an ordinary Dired listing cannot be modified.)

  • If the buffer lists arbitrary file names explicitly, then it is updated to include also the files from any Dired buffers and any additional files that you specify.

    If the union buffer name you choose does not name an existing Dired buffer, then its default-directory is the same as the default-directory before invoking the command.

    If you use a non-positive prefix arg, then you can next choose additional file and directory names to add to the listing. Use C-g when done choosing them. Any directory names you choose this way are included as single entries in the listing - the directory contents are not included (these directories are not unioned).

    You are then prompted for the Dired buffers to union. Use C-g when done choosing them. These Dired listings to union are included in the order that you chose them, and each entry is listed only once in the new Dired buffer.

    The new Dired listing respects the markings, subdirectory insertions, and hidden subdirectories of the selected Dired listings. However, in case of conflict between marked or unmarked status for the same entry, the entry is marked. Similarly, in case of conflict over an included subdirectory between it being hidden or shown, it is hidden, but its contained files are also listed.

    From Lisp:

    DIRED-NAME is the name of the resulting Dired union buffer.

    DIRBUFS is a list of the names of Dired buffers to union.

    SWITCHES is a string of ls switches.

    EXTRA is a list of files & directories to be included in the listing.

B. Wrt the bookmarking part of your question:

If you use Bookmark+ then you can bookmark the result of creating such a Dired buffer (see part A), by using a function bookmark. The function to invoke when the bookmark is "jumped to" would invoke diredp-dired-union to accomplish what is described in part A. Just define a function foo that invokes diredp-dired-union with the proper arguments, and then create a function bookmark that invokes foo.

I've added this command to Bookmark+, to do what you request:

(defun bmkp-set-dired-bookmark-for-files (bookmark-name dired-name to-add &optional switches msg-p)
  "Create a Dired bookmark for a set of files and directories.
You are prompted for the Dired buffer name and the file or directory
entries to include.  With a prefix arg, you are also prompted for the
`ls' switches.

Use `C-g' when done choosing file and directory names.  Any directory
names you choose this way are included as single entries in the
listing - the directory contents are not included.  To instead include
the contents of a directory, use a glob pattern: put `/*' after the
directory name.

You need library `Dired+' for this command."
  (interactive
   (let* ((_IGNORE             (unless (require 'dired+ nil t)
                                 (error "You need library `Dired+' for this command")))
          (current-prefix-arg  (if current-prefix-arg 0 -1))
          (all                 (diredp-dired-union-interactive-spec
                                "add files/dirs "
                                'NO-DIRED-BUFS
                                'READ-EXTRA-FILES-P)))
     (list (bmkp-completing-read-lax "Bookmark") (nth 0 all) (nth 3 all) (nth 2 all) 'MSG)))
  (bmkp-make-function-bookmark
   bookmark-name
   `(lambda () (diredp-add-to-dired-buffer ',dired-name ',to-add ',switches))
   msg-p))
9
  • thx alot drew. part A (diredp-dired-union) works great! im still stuck on part B since i dont know how to code (im an academic in the humaneties..thats my excuse at least ;-)). can you show me an example on how to use the function bookmark and tie it to the diredp-dired-union? thx alot! Z
    – zeltak
    Commented Apr 23, 2016 at 17:37
  • OK, I added a command that does this to Bookmark+. Copy it from here or get it from the latest bookmark+-1.el.
    – Drew
    Commented Apr 23, 2016 at 22:24
  • this is awesome, thx so much. only 1 tiny issue remains. the doc says: To instead include the contents of a directory, use a glob pattern: put /*' after the directory name. when i do that i get an error when trying to launch the bookmark: insert-directory: Reading directory: no such file or directory, /home/zeltak/ZH_tmp/*`. any clue? this is the current elisp entry for the bookmark: paste.xinu.at/11K
    – zeltak
    Commented Apr 24, 2016 at 4:36
  • Vanilla Emacs that is not on MS Windows does not use ls-lisp.el. Instead, it uses the ls that is provided by the OS (e.g. GNU/Linux). The code for insert-directory is different. I cannot test on a non-Windows platform. But you can try loading standard library ls-lisp, by putting (require 'ls-lisp) in your init file. See if that helps. Let me know (see the email contact info in the file header). It might be appropriate to file an Emacs bug/enhancement request for this. Note that ls-lisp is better for some things and not as good for other things, compared with built-in ls.
    – Drew
    Commented Apr 24, 2016 at 13:55
  • More precisely, ls-lisp.el advises insert-directory to use ls-lisp--insert-directory instead.
    – Drew
    Commented Apr 24, 2016 at 14:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.