Is it possible from within Emacs to find directories with a given depth from the current directory from within Emacs and receive their respective location in form of a list? I want it to work cross platform...
4 Answers
I'd be inclined to use find
for that:
(let ((dirname (expand-file-name "~/"))
(depth 3))
(split-string
(shell-command-to-string
(format "find %s -mindepth %d -maxdepth %d -type d -print0 2>/dev/null"
(shell-quote-argument dirname) depth depth))
"\0" :omit-nulls))
n.b. -mindepth
, -maxdepth
, and print0
are not POSIX options, so YMMV regarding portability.

- 48,657
- 3
- 76
- 115
-
I know but find would not work across different platforms. – sidharth arya Oct 23 '18 at 09:54
-
@sidhartharya You didn't mention the requirement that the code should work across platforms in your question. Therefore, this answer is equally valid as the others. (That's why I up-voted it.) Furthermore, the gnu-`find` tool is available for several platforms. E.g., on [Windows](https://www.microsoft.com/en-us/windows) by [mingw](http://www.mingw.org/wiki/MSYS). – Tobias Oct 24 '18 at 09:43
-
Yes gnu find is available across platforms but I want to do it , in a way, so the user doesn't have to explicitely install something specifically for that.. And also if i had to issue a shell command why would i ask it here. But thank's i will make the edit – sidharth arya Oct 24 '18 at 09:51
The elgrep-search command has options :mindepth
and :maxdepth
. Elgrep is available via package-install from the melpa package archive (instructions how to add melpa
to package-archives
can be found on the melpa "Getting Started" page).
You can use elgrep
as follows to get a list of matching file names of a specific depth. In the example I search in my HOME-directory (~/
) for files matching \.el\'
without in-file matches (that's the nil
) with minimal and maximal recursion depth 2.
(require 'elgrep)
(mapcar 'car (elgrep-search "~/" "\\.el\\'" nil :recursive t :mindepth 2 :maxdepth 2))
Elgrep actually returns filematches. That are conses of the file name and a list of in-file matches. In our case the list of in-file matches is empty since we passed nil
for the in-file regexp.
Because of that structure you need the (mapcar 'car ...)
. See the documentation of the elgrep-search
command for further details.
Note, that mindepth
and maxdepth
are also available via the gui-version elgrep-menu
. There you can let elgrep search asynchronously. That way it does not block your Emacs.

- 32,569
- 1
- 34
- 75
Library find-dired+.el
can help with this. C-h f find-dired
:
find-dired
is an interactive compiled Lisp function infind-dired+.el
.
(find-dired DIR ARGS &optional DEPTH-LIMITS EXCLUDED-PATHS)
Run
find
and put its output in a buffer in Dired Mode.Then run
find-dired-hook
anddired-after-readin-hook
.The
find’ command run (after changing into
DIR) is essentially this, where
LS-SWITCHESis
(car find-ls-option)`:find . \( ARGS \) LS-SWITCHES
Optional args:
DEPTH-LIMITS
: Minimum and maximum depths:(MIN-DEPTH MAX-DEPTH)
.EXCLUDED-PATHS
: Strings matching paths to be excluded. Usesfind
switch-path
.When both optional args are non-
nil
, thefind
command run is this:find . -mindepth MIN-DEPTH -maxdepth MAX-DEPTH \( -path EXCLUDE1 -o -path EXCLUDE2 ... \) -prune -o \( ARGS \) LS-SWITCHES
where
EXCLUDE1
,EXCLUDE2
... are theEXCLUDED-PATHS
, but shell-quoted.
Same thing for the related commands: find-name-dired
, find-grep-dired
, and find-time-dired
- they all take arg DEPTH-LIMITS
.
To reply to @Tobias's comment: Yes, find-dired+.el
(which extends standard library find-dired.el
) depends on a UNIX or GNU/Linux find
command. On MS Windows you can use Cygwin or any other porting of the command to Windows.

- 75,699
- 9
- 109
- 225
-
As I understand the code [`find-dired+.el`](https://www.emacswiki.org/emacs/download/find-dired%2b.el) uses the external `find` program. Therefore, the same comments as for [Phils answer](https://emacs.stackexchange.com/a/45521/2370) apply. Disclaimer: I had only a short glance on the code. It may be that you have some fallback there that uses emacs-internals when gnu-`find` is not available. I didn't check for that. Please correct me if that is the case. – Tobias Oct 24 '18 at 09:46
You can use the ls
command of the built-in eshell
for listing the files with some predefined depth.
You have to specify the depth by the right number of concatenated file name generator expressions */
.
Example:
(split-string
(substring-no-properties
(eshell-command-result "ls /usr/share/emacs/26.1/*/*/*/*/*/*(.)")
)
"\n" t)
The appended modifier (.)
says that the generator only expands regular file paths.
Note that the backend eshell-do-ls
command is a pure Emacs Lisp implementation of the ls
command.
Yet in this case the actual work is not done by ls
but by eshell-glob
.
If you also want to list directories you should add the -d
switch to the ls
command. Otherwise the files contained in the directories would also be listed:
(split-string
(substring-no-properties
(eshell-command-result "ls -d /usr/share/emacs/26.1/*/*/*/*/*/*")
)
"\n" t)
If you actually don't want any special features of ls
you can also use pure eshell-extended-glob
:
(eshell-extended-glob "/usr/share/emacs/26.1/*/*/*/*/*/*")
If you want to list all files with some minimal depths you can expand with the two-star form **
, e.g.,
(eshell-extended-glob "/usr/share/emacs/26.1/*/*/*/**/*")

- 32,569
- 1
- 34
- 75