9

How can I find all files from a folder and its subfolders recursively, containing a regexp in the filename, using helm?

For example: how to search for all files with the extension .el and containing the string dired in the directory emacs-24.3 its subdirectories, using helm?

caisah
  • 4,056
  • 1
  • 23
  • 43

3 Answers3

10

On systems that provide GNU find utility, you can use helm-find (by default bound to C-x c /) to get the desired behavior. Starting helm-find with a prefix argument C-u C-x c / prompts for the directory (emacs24.3 in the example) first and then for the pattern (dired el in the example). Without the prefix argument, it uses the default directory of the current buffer.

EDIT: Note that helm-find cannot use wildcards or regexps unlike the actual find utility. It does however support a whitespace separator to match multiple pattern within a string. For instance dired .el matches only filenames that contain both the strings dired and .el in the path in any order.

Vamsi
  • 3,916
  • 22
  • 35
4

This answer isn't exactly what you want (it does not use helm and does not use regexp) but Emacs has a built-in command called find-name-dired which finds recursively in a directory all files matching a given shell wildcard and opens a Dired buffer with all the matching files.

For your particular example you can do

M-x find-name-dired RET /path/to/emacs-24.3 RET *.el RET

itsjeyd
  • 14,586
  • 3
  • 58
  • 87
Iqbal Ansari
  • 7,468
  • 1
  • 28
  • 31
1

If you don't care about using Helm, you can do what you ask using Icicles.

What is it that you want to do with the files you find? Open them? Search them? I'll assume you want to open them, as an illustration.

Here are a couple different ways. The first is simpler; the second shows some additional features that you can also use in other ways.


  1. Use multi-command icicle-locate-file-other-window to open files under a given directory, matching them by name or content, or both. You are prompted for the directory within which to look. (On platforms that have system command locate you can use icicle-locate instead, which is faster than icicle-locate-file.)

    Then type a multi-completion pattern to match. For example:

    f.* C-M-j some text .*in the file
    

    The files with names matching regexp f.* and with content matching regexp some text .*in the file are the completion candidates. Each part here is optional: if you want, you can filter on just file names or just file contents. The matching (absolute) file names appear in buffer *Completions*.

    C-M-j here is a multi-completion separator. (Helm uses a space similarly, but in Icicles space chars are often used in the patterns themselves, which can be any regexps. Actually, what is used for the separator is defined by a user option.)

    Optionally, hit S-SPC and then type more patterns to narrow the completion choices further. You can use S-SPC to add as many patterns as you like. This is progressive completion.

    Type C-! to open all of the candidate files.

    Without exiting multi-command icicle-locate-file-other-window, you can change the filtering expressions to get a different subset of the file names, and then act on them as well. However, if you accumulated patterns using progressive completion, then any patterns you entered before the last S-SPC are locked in, unless you use C-x C-0 to restore the original domain of candidates (which in this case is all of the files under the given directory).


  1. With the second approach, you first save the names of all files in and below the current directory. You can save that list in a cache file, in an Emacs fileset, or in a variable. If you want to save it in a variable, you can be prompted for it or just use the default variable for this, icicle-saved-completion-candidates.

    You can do this in Dired using command icicle-dired-save-marked-recursive. If you use library Dired+ then this command is bound to M-+ C-M->.

    (M-+ is a Dired+ prefix for acting on all files under a directory, or all marked files there and in marked subdirs, defined recursively. C-M-> is the standard Icicles completion action key for saving candidates.)

    You can later retrieve the list of file names (as many times as you like), to act on the files themselves. When you do this, you can filter the files - by name or by content, using one or more regexps or substrings.

    For example, if you want to open all of the files (among those whose names were saved) whose names match f.* and whose content matches some text .*in the file, then do this:

      C-u C-x 4 C-f C-M-< f.* C-M-j some text .*in the file C-!
    

    Decomposing that:

    • C-x 4 C-f is Icicles command icicle-file-other-window, which is a multi-command version of find-file-other-window. But with C-u the candidates are absolute file names. (The names saved using M-+ C-M->, which you are going to retrieve, are absolute, as they are in different directories.)

    • C-M-< is the opposite of C-M->. It retrieves a saved set of files (by default, from variable icicle-saved-completion-candidates).

    • Just as in the first method, f.* C-M-j some text .*in the file says to match regexp f.* against file names and match regexp some text .*in the file against the file contents. This filters the set of file names to those that satisfy these two constraints.

    • C-! means act on all candidates. The action here is to find (open) the file.

    As with the first method, without exiting multi-command icicle-file-other-window, you can change the filtering expressions to get a different subset of the saved file names, and then act on them as well.

Drew
  • 75,699
  • 9
  • 109
  • 225