Emacs: Categorize Files to Directories (Move File to Dir) 🚀

By Xah Lee. Date: . Last updated: .

Here's a command that moves the current file (e.g. image file) to a choice dir. This is very useful when you have lots images, photos, screenshots, that you want to sort them out into different dirs such as food, travel, family, etc.

(defvar xah-move-to-target-dirs
  '(
    ;;
    ("Documents" . "~/Documents/")
    ("Pictures" . "~/Pictures/")
    ("Desktop" . "~/Desktop/")
    ("Downloads" . "~/Downloads/")
    )
 "An alist of dirs for `xah-move-file-to-dir' to move file to.
Keys are strings, values are dir paths.
Dir path must end in a slash.
Useful is to create a bunch of dir, named family, travel, papers, work, etc, to sort photos into.")

(defun xah-move-file-to-dir (TargetDir)
  "Move current file to a dir in `xah-move-to-target-dirs'.
If in `dired', move currnet file or marked files.

The target dir is added to `xah-recently-closed-buffers'.

If file, the file is killed after move, and its new location is added to `xah-recently-closed-buffers'.

After this command, if the buffer is dired, it is refreshed.

URL `http://xahlee.info/emacs/emacs/move_file_to_dir.html'
Version 2023-03-09 2023-07-04 2023-08-24"
  (interactive
   (list
    (file-name-as-directory
     (cdr
      (assoc
       (completing-read "move file to dir:" xah-move-to-target-dirs nil t)
       xah-move-to-target-dirs)))))
  (let (xfiles)
    (setq
     xfiles
     (cond
      ((eq major-mode 'dired-mode) (dired-get-marked-files))
      (buffer-file-name (list buffer-file-name))
      (t (user-error "Current buffer is not a file nor `dired'"))))
    (mapc
     (lambda (xx)
       (let ((xnewPath (format "%s%s" TargetDir (file-name-nondirectory xx))))
         (rename-file xx xnewPath)))
     xfiles)
    (message "
Files
%s
moved to
%s"
             (mapconcat 'identity xfiles "\n")
             TargetDir)
    (when (boundp 'xah-recently-closed-buffers)
      (push (cons nil TargetDir) xah-recently-closed-buffers))
    (cond
     ((eq major-mode 'dired-mode) (revert-buffer t t t))
     (buffer-file-name
      (progn
        (when (boundp 'xah-recently-closed-buffers)
          (push (cons (buffer-name) buffer-file-name) xah-recently-closed-buffers))
        (kill-buffer)))
     (t nil))))