Category Archives: dired

Speedy sorting in dired with dired-quick-sort

The package dired-quick-sort gives you a pop-up menu with lots of useful options to sort your dired view by name, time, size and extension, and optionally group all of the directories together at the top of the listing. This can be a bit fiddly and dired-quick-sort makes it really easy.

Install the package with

(use-package dired-quick-sort
  :ensure t

and then hit S in a dired buffer to bring up the sorting menu. Your sorting choice is then remembered for new dired buffers.

Batch-edit file permissions in dired

I’ve written before about using the editing features in dired (AKA wdired) to do neat things like redirect symlinks. I recently discovered that by adding the following option to your emacs config file:

;; allow editing file permissions
(setq wdired-allow-to-change-permissions t)

then you can also edit the file permissions directly in the dired buffer.

Here’s a quick animated example where I want to set group write permissions for all the pdf files in a particular directory. I use several tools to make this really easy:

  1. I used dired-narrow to filter the view down to just the pdf files
  2. I use C-x C-q to make the dired buffer editable
  3. I move to the group write permission spot on the first line and then use multiple cursors to add a cursor for each line
  4. I hit w to set the write permission, RET to quit multiple cursors, and C-c C-c to make the change permanent


Use Emacs as a two-paned FTP client

I’ve written before about using sunrise commander for two-paned dired allowing an intuitive way to copy files between directories. You can also use sunrise to connect to an ftp server. For example in sunrise commander I hit j to go to a new directory and enter / which prompts me for my password and then connects to the top level directory of my site. Note that the syntax is important – in this case I don’t need to specify I am using an ftp connection since the host name starts with ftp, but the trailing colon is needed to specify the top level directory. The full syntax is described in the manual.

Now you can have the local directory in the left pane and the remote directory in the right pane, and copy files back and forth. Of course the same approach can be used to connect to an ftp server in normal dired, but I find the two-paned view of sunrise commander particularly intuitive here.

Quickly preview images and other files with peep-dired

The package peep-dired lets you quickly scan through images (or any other documents) with previews in dired. In the example below, I invoke peep-dired (I bind it to P) and scan through a set of images in a dired listing. When I am finished I hit P again to quit peep-dired.


Here is my code to install and configure peep-dired with use-package

;;preview files in dired
(use-package peep-dired
  :ensure t
  :defer t ; don't access `dired-mode-map' until `peep-dired' is loaded
  :bind (:map dired-mode-map
              ("P" . peep-dired)))

Dynamically filter directory listing with dired-narrow

If you install the package dired-narrow (one of several neat packages described on the dired-hacks github page), then you can type filter strings to dynamically filter down a dired listing to match the filter.

For example, in the animation below I have a dired buffer containing lots of files. I invoke dired-narrow by hitting / and then type “png” to narrow to filenames matching “png”. I then hit RET to complete the filtering. At that point I can operate on the filtered dired list as I would for any dired buffer. I can even narrow further by simply invoking dired-narrow again and typing a new filter (I use “mirror” in the example below). Once I have finished with the filter, I hit g to revert back to the full directory listing.


As an aside, I have started using use-package to install and configure packages (see the update on this page). Here is the code I use to install and set up dired-narrow.

;;narrow dired to match filter
(use-package dired-narrow
  :ensure t
  :bind (:map dired-mode-map
              ("/" . dired-narrow)))

Open a recent directory in dired: revisited

I wrote recently about how to use the command diredp-dired-recent-dirs from dired+ to open a recently used directory in dired. It turns out I had misunderstood what that command was for – it is intended to create a dired buffer containing a list of recently used directories, which is not exactly what I wanted.

Here is a function to give you a list of recent directories, using ivy (part of swiper) to narrow it dynamically, and then open the selected one in dired.

;; open recent directory, requires ivy (part of swiper)
;; borrows from
(defun bjm/ivy-dired-recent-dirs ()
  "Present a list of recently used directories and open the selected one in dired"
  (let ((recent-dirs
          (mapcar (lambda (file)
                    (if (file-directory-p file) file (file-name-directory file)))

    (let ((dir (ivy-read "Directory: "
                         :re-builder #'ivy--regex
                         :sort nil
                         :initial-input nil)))
      (dired dir))))

(global-set-key (kbd "C-x C-d") 'bjm/ivy-dired-recent-dirs)

Open recent directories in dired

I find myself doing more and more of my file system tasks in emacs with dired. The package dired+ adds some extra features to dired, one of which I discovered today.

The command diredp-dired-recent-dirs, bound to C-x R by default, presents you with a list of recent directories that you can then choose to open in dired. I have found to be a really quick way to find the directory I want to open, especially when combined with ivy-mode (or one of the other completion packages).

Dired+ can be installed from the normal package repositories.


This post is superseded by this one.

Double dired with sunrise commander

I’ve written several times about managing files in emacs with dired. However, if I am copying or moving files between two directories, I have found that I like a two-paned file browser showing the two directories side by side. The package sunrise commander provides this very nicely, giving a great interface for managing files and even copying files between remote and local directories.

It is a tiny bit fiddly to install as it is not in one of the standard package archives. I would suggest evaluating the following code snippet to add the required repository:

(add-to-list 'package-archives '("SC" . "") t)

You can then install sunrise-commander using M-x package-list-packages as normal. The repository will be forgotten next time you restart emacs, which is fine as sunrise-commander is stable and rarely updated, and the repository can be slow to respond sometimes, which can affect the package listing.

While you are at it, also install sunrise-x-buttons and sunrise-x-modeline from the same place.

Once you have done this, use M-x sunrise to start sunrise-commander. This will open a two-paned dired style file browser as illustrated in this screen shot:


The top left and right panes are two different directory listings, each of which behave very much like dired. You can switch between them with TAB, and if you try to copy or move files, it will default to copying them to the opposite pane, which is just what you want.

This works particularly well when using emacs to manage remote files, indeed in the screenshot above, the left pane is a directory on a remote machine, so it is easy to copy files back and forth between the local and remote machines.

The bottom panel is a set of buttons to perform common tasks (provided by the sunrise-x-buttons extension); I don’t use the buttons but I find them a useful reminder of the keys for those tasks.

The sunrise-x-modeline extension updates the modeline of each directory pane to show a clickable path to the current directory.

There are several other extensions available, as described on the wiki page, and there is a second useful wiki page of tips for sunrise commander.

I have a couple of tweaks that I make:

;; sunrise commander                                                      ;;
(require 'sunrise-commander)
;; disable mouse
(setq sr-cursor-follows-mouse nil)
(define-key sr-mode-map [mouse-1] nil)
(define-key sr-mode-map [mouse-movement] nil)

;;tweak faces for paths
(set-face-attribute 'sr-active-path-face nil
                    :background "black")
(set-face-attribute 'sr-passive-path-face nil
                    :background "black")

;;advise sunrise to save frame arrangement
;;requires frame-cmds package
(defun bjm-sc-save-frame ()
  "Save frame configuration and then maximise frame for sunrise commander."
(advice-add 'sunrise :before #'bjm-sc-save-frame)

(defun bjm-sc-restore-frame ()
  "Restore frame configuration saved prior to launching sunrise commander."
(advice-add 'sr-quit :after #'bjm-sc-restore-frame)

This code disables mouse interaction, and changes the background colour of the directory paths.

More interestingly, I want sunrise commander to run full screen, but then I want my original frame size back when I finish with it. To do this I wrote two simple functions above, that use the frame-cmds library mentioned recently. The first saves the current frame configuration and then maximises the current frame – sunrise commander is advised to call this function when it starts. The second restores the saved frame configuration, and sunrise commander is advised to call this when it quits.

Editing and managing files remotely

Emacs supports editing files remotely, as a nice alternative to opening a new emacs session on your remote machine and sending the window over X11. This feature is called tramp.

It works seamlessly – just open a file as usual with C-x C-f and then give the name of the remote file, including the host address – e.g.

C-x C-f /

Note the syntax, that the remote machine name is opened at the top level directory “/”.

You can then edit and save as normal.

It is useful to note that you can also do exactly the same thing to open remote directories in dired to browse, copy, rename and otherwise manage files on a remote machine.


As commenter Nagora points out, if your username is different on the remote machine, you should specify it like

C-x C-f /