Skip to content

Mark Empty Folders in Dired

One feature I was missing in Dired is visual difference between empty folders and those that contain some files. Conventional file managers usually display some kind of icon, like ‘+’ sign or some arrow to denote that a folder contain some files and that it can be expanded. There is no such funcionality in Dired that I know of. I don’t need to see that difference all the time though, so I figured out I could have this feature rather on-demand

It turnes out it was rather simple; we just need a predicate to test if a folder is empty or not:

(when (version< emacs-version "28")
  (defun directory-empty-p (file-name)
    "Check if a directory contains any other files then dot-files"
    (when (file-directory-p file-name)
      (null (directory-files file-name nil
                             directory-files-no-dot-files-regexp t)))))

on which we can invoke `dired-mark' which is built-in Dired function to mark files, though we have to iterate through dired buffer ourselves, since dired-mark operates on the current line where point is.

(defun dired-mark-empty-dirs ()
  "Interactively mark all empty directories in current Dired buffer."
  (when (equal major-mode 'dired-mode)
      (while (not (eobp))
          (when (directory-empty-p (dired-get-filename))
            (dired-mark 1)
            (dired-previous-line 1)))
        (dired-next-line 1)))))

The rather verbose named `directory-files-no-dot-files-regexp' is just a regular expression saying that we don't wish to return `.' and `..' in the list of file names.

`dired-go-to-first' is my own little function which puts point at the start of the first file name, instead at the headline as the default behaviour is.

(defun dired-go-to-first ()
    (goto-char (point-min))
    (dired-next-line 1)
    (skip-chars-forward " \n\t"))

As a remark, this is rather inneficient. The function `directory-files' as it is implemented in Emacs at the moment, will iterate through entire directory listing, every time we invoke this predicate. That means that `dired-mark-empty-dirs' has, a sort-of, n² complexity for running time (actually linear in number of files in each directory times number of files in Dired buffer from which it is called). That is slow, and it is noticable if you have directories with few thousands of files (some backups here). An uppcomming patch, if it goes through, will change the behaviour of `directory-files' (when asked) to rather constant time, which will speed things up.


As suggested by Oantolin (Omar Antolin Camarena), there is an alternative, more elegant version possible, which uses some built-in machinery in Dired:

(defun dired-mark-empty-directories (&optional arg)
  "Mark empty directories.
A prefix argument means to unmark them instead."
  (interactive "P")
  (let ((dired-marker-char (if arg ?\s dired-marker-char)))
     (when-let ((dir (dired-get-filename t t)))
       (directory-is-empty-p dir))
     "empty directory")))

Thanks Omar!

{ 1 } Comments