3

I scan all the mail (not email, but good ol' mail) I receive and have these saved as PDF files into a directory, which we think of as an inbox. I would like to find a workflow to quickly refile these PDF files by moving them to one of several pre-defined directories. From a user perspective, the closest thing I can think of is org-capture and capture templates, where I can have a couple of custom defined destinations that have a simple one key shortcuts. I want the same thing but for refiling actual files, using dired or similar, so when I have the list of files I can go just press two quick keys and have it moved to one of my predefined directories.

To further illustrate my wanted workflow, imagine org-capture-templates, which can look like this;

  (setq org-capture-templates
        '(
          ("t" "Todo Work" entry (file+headline "~/org/work.org" "Tasks") "* TODO %?\n  %i\n  %a")
          ("p" "Todo Personal" entry (file+headline "~/org/personal.org" "Tasks") "* TODO %?\n  %i\n  %a")
  ...

So after bringing up the capture menu, I can press t or p to choose either a work related todo or a personal todo. Similarly for my PDF refiling operation, I want to define some "templates" with a shortcut for each, so after selecting a file and bringing up my "quick-refile" menu, I can press a single letter, like 'p' for personal files or perhaps 'w' for work related files, which will then move the file.

I'm open both to configuration suggestions on how to achieve this as well as plugins or suggestions on workflows for doing this. I concocted this workflow for myself but otherwise try to follow BASB (building a second brain) and PARA for filing stuff. If anyone has broader workflow suggestions I'm listening.

Many of these files are closely associated with tasks I have in org, so it's nice to have en Emacs centric workflow to handle all aspects of refiling. Extra points for an answer that can update references to these files from within org, when the actual file is moved. I imagine that I will always refile the file first, then reference it, but perhaps sometimes it is useful to be able to refile later as well, in which case I don't want my org mode references to the file to break.

5
  • It's not too clear to me what you're looking for. If you just want to move files then you can mark them in Dired and use R to move them to another directory (anywhere). You can mark files according to any number of characteristics, including dates, file types, file-name patterns, and even file attributes.
    – Drew
    Sep 13, 2018 at 21:54
  • Using R will let me then pick a folder. I want to have a couple of quick selections, so I can do say R a to move to one directory (the one 'a' is mapped to) or R b to move it to a different directory. I guess it would actually have to be something besides R, otherwise it would conflict, but I think you get the point.
    – kll
    Sep 14, 2018 at 17:09
  • I'm not really looking for batch moving based on patterns because the way I work with this is opening a file, inspecting the content, then deciding where to move it to so it's not very batchy in nature.
    – kll
    Sep 14, 2018 at 17:10
  • Got it. Added an answer that I think corresponds to what you describe. If you're open to a command instead of just a keyboard macro, consider changing the question title to allow for that.
    – Drew
    Sep 14, 2018 at 22:20
  • Thanks @Drew! I didn't mean to limit the possible solutions to just Emacs macros, I used the word in the generic meaning, not Emacs specific one. Title updated! I also improved wording and added an example that I think better illustrates my idea!
    – kll
    Sep 17, 2018 at 7:56

3 Answers 3

2

Have a look at http://pragmaticemacs.com/emacs/quickly-move-a-file-to-the-current-directory/.

It describes a solution to a problem very similar to yours. You have files arriving to a directory, in this case the download directory, and you want to move them to an other. This script moves them to the same directory with the current buffer.

I have added these lines before the last line:

  ;; copy short filename to clipboard
  (kill-new start-file)
  (gui-set-selection 'PRIMARY start-file)

I am usually in an org file and after running the amended function I can paste in the filename and write further annotation on the moved file. If you paste the name in front of a "file:" string, org mode creates a link to the file.

In its current form, the function moves files one by one, so for the initial bulk move you might want to use the standard dired R moves.

The function can easily be extended to do more complex file moves.

1

There's an interesting article by Piotr Limanowski about the way he reads scientific and computer science papers. I am using this same system for manuals in pdf format, as it is done in org mode and easy to file and have bookmarks and notes. Article in CodeArsonist here

I use pdf-tools.

  • Start a new org file, say.. "papers.org"
  • Add #+INTERLEAVE_PDF: /the/path/to/some.pdf in the org header section.

with M-x interleave-mode will open the pdf file. you can create a sub tree (a new header) for each paper. in the sub tree create a :INTERLEAVE_PDF: property

the paper is the linked to the org file so you can split vertically, add a note in location using i,

An example excerpt from my papers.org:

* paper6 - Some Paper
:PROPERTIES:
:INTERLEAVE_PDF: ~/notes/ref/lib/some_paper.pdf
:END:

** Notes for page 15
:PROPERTIES:
:interleave_page_note: 15
:END:

*** some sub-tree:
- some text....

*** another subtree:
- some more text

interleave here

pdf-tools here

2
  • Wow, cool. Not was I was looking for right now to actually move the files on disk but I'm sure I could use something like this in further tying together those files with the data I have in org related to those files, so thanks! :)
    – kll
    Sep 14, 2018 at 17:07
  • no problem. I thought that was a very interesting idea and I jumped on the opportunity to share it ;-) Sep 14, 2018 at 17:24
1

Here's a command that should do what you're looking for, together with a user option for specifying your associations between files and the directories you want to move them to.

To move a file whose name is not in the list of associations you are prompted for the target directory. A prefix arg means ignore the associations and prompt for the target directory anyway.

(defcustom my-move-file-dirs ()
  "Alist of names of files and directories to move them to.
File name should be relative (no directory component).
Directory name should be absolute."
  :group 'files :type '(alist :key-type file :value-type directory))

(defun my-move-file (file &optional prompt-anyway)
  "Move FILE to associated directory in `my-move-file-dirs'.
If no association, or if you use a prefix arg, prompt for directory."
  (interactive (list (dired-get-filename) current-prefix-arg))
  (unless file (error "No file specified"))
  (let* ((file-sans  (file-name-nondirectory file))
         (dir        (file-name-as-directory
                      (or (and (not prompt-anyway)
                               (cdr (assoc file-sans my-move-file-dirs)))
                          (read-directory-name "Move to: ")))))
    (when (file-equal-p dir (file-name-directory file))
      (error "Cannot move to same directory: " dir))
    (dired-rename-file file dir nil)
    (dired-add-file (expand-file-name file-sans dir))
    (message "Moved `%s' to `%s'" file-sans dir)))

Should work fine. But as always, try it first on files and directories you don't care about, or back up your data before trying it.


The question seems like a reasonable convenience request, so I've added this to Dired+.

2
  • Looking at this it appears I would define a mapping of filenames to directories. I didn't want automatic move - I wanted to define a list of directories with one-key shortcuts, so I could quickly choose which of these directories the file should be moved to. Apologies for not describing clearly enough what I was looking for. I did update my question (with a clearer example) after you answered though - now sure if it's better!? Also, pardon the delay, sometimes difficult to find time for Emacs between family time and work ;)
    – kll
    Sep 29, 2018 at 22:03
  • 1
    If that's all you want, why don't you just define a command for each such move? The code bodies can all share a helper function. The command names can be similar but easily distinguished. Either bind a different key to each or use M-x and complete to the command name. If you want to easily be able to change the target directories without changing the commands, have them use an alist variable that you can customize.
    – Drew
    Sep 30, 2018 at 1:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.