DiredReuseDirectoryBuffer

In Dired, when you choose a directory to visit, it is normally visited in a new buffer – the Dired buffer you chose it in is not deleted.

Some don’t like this behavior, because as you navigate around the directory tree you accumulate Dired buffers, one for each directory you visit.

You can bury Dired buffers with ‘q’, which is bound to ‘quit-window’ in DiredMode. But that does not kill the buffers – they still accumulate, whether or not they are displayed.

Libraries that Provide Reuse

Do It Yourself?

For those who do not want to load a library (too easy!) —

Starting with Emacs 22, ‘a’ is bound in DiredMode by default to ‘dired-find-alternate-file’ instead of ‘dired-find-file’ (which is bound to ‘e’, ‘f’, and ‘RET’). Command ‘dired-find-alternate-file’ (like command `find-alternate-file`) replaces the current Dired buffer with another buffer (it kills the current buffer). If the cursor is on a directory line then the replacement buffer is a Dired buffer for that directory. If the cursor is on a file line then the replacement buffer is for that file.

The first time you try to use ‘a’ Emacs tells you that you’ve invoked a command that is disabled by default because new users might find its behavior confusing. The behavior is described, and Emacs asks you whether or not you want to disable the command. You can also try it temporarily but leave it disabled in general.

You can also just put this code in your InitFile to enable the command:

    (put 'dired-find-alternate-file 'disabled nil)

You could also of course bind ‘dired-find-alternate-file’ to the other keys for visiting a directory or file at point. By default this means keys ‘e’, ‘f’, and ‘RET’. But it’s likely that you will want at least one key that visits a file or directory at point without killing the current Dired buffer.

In any case, the approach of just using ‘dired-find-alternate-file’ does not help with mouse clicks to visit a file or directory.

Command ‘dired-find-alternate-file’ also does not help when you use `^’ to move up to the parent directory. If you want that behavior but also want to kill the current directory (the child) then you can do this:

(add-hook 'dired-mode-hook
          (lambda ()
            (define-key dired-mode-map (kbd "^")
                        (lambda () (interactive) (find-alternate-file "..")))))

And here are two ways to advise ‘dired-find-file’, so it reuses a directory buffer. (But see AdviceVsHooks.)

     (eval-after-load "dired"
      '(progn
         (defadvice dired-advertised-find-file (around dired-subst-directory activate)
           "Replace current buffer if file is a directory."
           (interactive)
            (let* ((orig (current-buffer))
                   ;; (filename (dired-get-filename))
                   (filename (dired-get-filename t t))
                  (bye-p (file-directory-p filename)))
             ad-do-it
             (when (and bye-p (not (string-match "[/\\\\]\\.$" filename)))
               (kill-buffer orig))))))
        ;; Another way of achieving this:
        ;; we want dired not not make always a new buffer if visiting a directory
        ;; but using only one dired buffer for all directories.
        (defadvice dired-advertised-find-file (around dired-subst-directory activate)
          "Replace current buffer if file is a directory."
          (interactive)
          (let ((orig (current-buffer))
                (filename (dired-get-filename)))
            ad-do-it
            (when (and (file-directory-p filename)
                       (not (eq (current-buffer) orig)))
              (kill-buffer orig))))
Using the advising methods above will still create a new buffer if you invoke ^ (dired-up-directory). To prevent this:
     (eval-after-load "dired"
       ;; don't remove `other-window', the caller expects it to be there
       '(defun dired-up-directory (&optional other-window)
          "Run Dired on parent directory of current directory."
          (interactive "P")
          (let* ((dir (dired-current-directory))
     	    (orig (current-buffer))
     	    (up (file-name-directory (directory-file-name dir))))
            (or (dired-goto-file (directory-file-name dir))
     	   ;; Only try dired-goto-subdir if buffer has more than one dir.
     	   (and (cdr dired-subdir-alist)
     		(dired-goto-subdir up))
     	   (progn
     	     (kill-buffer orig)
     	     (dired up)
     	     (dired-goto-file dir))))))

Experiences

I used to hate those Dired buffers cluttering up my Emacs so I had one of these hacks enabled for years. However, for some years now I have gone back to the default behaviour which has (at least) one advantage that is worth more to me than to have less buffers: performance when opening Dired buffers for directories on slow servers. I open a lot of directories on shares at different servers at work, many in remote locations. As with many Emacs concepts I have now got used to it and suspect that there was actually some thought behind this from the beginning even if it seems strange at first. Also, since I have F5 bound to a helper command to kill buffers, it is really easy to get rid of the dired buffers when I want to. And, sometimes when I drill down from one directory to a sub directory I discover that I wanted to go to the parent. Then for me I can just kill the current one (F5) or switch to the previous one (bound to F1 in my setup). So, that’s my experience and I just thought I should share it 😊 – MaDa

That is my experience as well, I struck a fine balance by using the ‘subdir’ commands—that way I don’t need to work on a buffer-per-directory basis. – Iceland_jack

CategoryDirectories