2

I try to use find-name-dired, everything works out as expected. Is there a way to save the selection of files for reuse?

Drew
  • 75,699
  • 9
  • 109
  • 225
u38078
  • 21
  • 2
  • You seem to be asking two different questions: (1) save the names of the files in the resulting Dired buffer and (2) "specify the selection rules by multiple paths". I removed the second question. Please post it separately - only one question per post. (And I don't know what you mean by that second question - please clarify it when you post it separately.) – Drew May 20 '22 at 17:41

4 Answers4

1

To get a list of the (absolute names of the) files in a Dired directory (including one produced by find-name-dired etc.), just use t with no files marked, to mark them all, and then use (dired-get-marked-files). (You can use t again to unmark them all.)

You can save such a list in various ways, depending on what you mean - e.g. set a variable to it and save the variable, e.g., with savehist-additional-variables (library savehist.el).


You can use (dired (cons BUFNAME FILES)) to open Dired on your (saved) list of files, where BUFNAME is the name you want to give to the Dired buffer and FILES is your list of saved file names.

This uses a little-known feature of function dired (likewise dired-other-window etc.): If the DIRNAME arg you give it is, instead of a string that names a directory, a list of strings, then it uses the first string in that list as the Dired buffer name and the other strings as the file names to list.

This means that dired can create a Dired buffer with an arbitrary list of files and directories, from anywhere - even in different trees of your file system.


If you use Dired+ (dired+.el) then you can use command diredp-dired-for-files to create such a Dired buffer of arbitrary files interactively. You're prompted for the files/dirs to include in the listing.

But see also my other two answers here, for easy ways to create such a snapshot Dired listing. And see Dired Snapshot and section Saving and Restoring Dired Listings in the Commentary of dired+.el.

Drew
  • 75,699
  • 9
  • 109
  • 225
0

If you use Dired+ (dired+.el) then you can use command diredp-marked (or diredp-marked-other-window, which is bound to C-M-*) to create a Dired buffer that's a snapshot of the marked buffers in the Dired buffer produced by find-name-dired (and other find-dired commands).

And with a multiple-C-u prefix arg you can do the same but ignore markings and instead pick up all of the files:

A prefix ARG that is non-positive or a single C-u means prompt for ls listing switches, as in command dired.

A prefix ARG also specifies the files to use instead of the marked files (any markings are ignored), as follows:

If ARG is positive or negative, use the files named on the next ARG lines. E.g., 1 or -1: use the file on the current line; 3 or -3: use the file on the current line and those on the following 2 lines.

If ARG is C-u C-u, C-u C-u C-u, or C-u C-u C-u C-u, use all files in the Dired buffer, where:

  • C-u C-u includes only files - no directories

  • C-u C-u C-u includes directories except . and ..

  • C-u C-u C-u C-u includes all directories (even . and ..)

If ARG is otherwise non-nil (e.g. 0, M-- or a single C-u), use the file or dir of the current line (same as ARG = -1).

The listing is a snapshot, meaning that the fact that it results from a find command is lost. You can access it directly, without re-finding, to save searching. Of course this also means that any changes that find would notice won't be reflected in use of the snapshot.


OK, but then how to persist this snapshot across Emacs sessions? For that you need library Bookmark+. Then you can just bookmark the snapshot Dired buffer.

You need Bookmark+ for this because a vanilla Emacs Dired bookmark doesn't really record anything useful. With Bookmark+ a Dired bookmark records the current state of the Dired buffer: its marked files, inserted subdirs, etc. -- including, for a snapshot listing, the complete set of files and dirs listed.

When you jump to the bookmark your Dired snapshot is restored. The bookmark is a persistent cache of the set of files and dirs found by your find command (e.g. find-name-dired).

See Dired Snapshot and section Saving and Restoring Dired Listings in the Commentary of dired+.el.

Drew
  • 75,699
  • 9
  • 109
  • 225
0

If you use Dired+ (dired+.el) then there's another solution, which doesn't require that you also use library Bookmark+.

That solution is to use Dired+ command diredp-define-snapshot-dired-commands in the Dired buffer that results from your find command. That creates two commands (same-window and other-window) that each create a snapshot Dired buffer with the files and dirs listed by your find command.

When you create these commands a buffer pops up with their Lisp definitions (defuns). Copy either or both definitions to your init file, to give you persistent access to the snapshot Dired buffer.

See Dired Snapshot and section Saving and Restoring Dired Listings in the Commentary of dired+.el.

Drew
  • 75,699
  • 9
  • 109
  • 225
0

Just run M-x my-save-current-buffer, then open saved file in Emacs.

Here is the code,

(defun my-save-current-buffer ()
  "Save current buffer (Dired, Grep, ...) to re-use in the future."
  (interactive)
  (let* ((file (read-file-name "Save buffer to file (its extension must be \"el\"): "))
         (content (buffer-string))
         (can-save-p t)
         (header (format "-*- mode:%s; default-directory: \"%s\" -*-\n"
                         (replace-regexp-in-string "-mode" "" (format "%s" major-mode))
                         default-directory)))
    (when file
      ;; double check file name extension
      (unless (equal (file-name-extension file) "el")
        (setq file (concat (file-name-base file) ".el")))

      (when (file-exists-p file)
        (setq can-save-p
              (yes-or-no-p (format "File %s exists.  Override it?" fil))))
      (when can-save-p
        (with-temp-buffer
          (insert header)
          (insert content)
          ;; write buffer content into file
          (write-region (point-min) (point-max) file))))))

(add-hook 'dired-mode-hook (lambda () (unless dired-subdir-alist (dired-build-subdir-alist))))

Notes:

  • my-save-current-buffer is a generic function. It could be used to save any kind of buffer
  • dired-build-subdir-alist need be called in dired-mode-hook
  • If you use global-auto-revert-mode, global-auto-revert-non-file-buffers should stay in its default value nil. Or else dired-revert is called which screws up the dired buffer content
  • I learned the techniques from studying code of ivy.
chen bin
  • 4,781
  • 18
  • 36