6

In a Microsoft-centric workplace, I use task attachments heavily to store emails, design documents, and the like. Especially with email attachments, I'll usually open up the task's attachment folder (C-c C-a f) and simply drag the relevant emails to the folder (which conveniently also copies all of its attachments :)).

Since Org isn't the one adding attachments, the ATTACH tag is often missing. As I move around attachments and tasks, I'll also move their attachments appropriately, sometimes emptying the folder. This causes ATTACH to become a false-positive.

Is there any way I can synchronize the presence of the ATTACH tag with the presence of actual attachments? As an added bonus, can I also update the :Attachments: property with the appropriate file list? (It helps with searching.)

2
  • 1
    There's a function org-attach-sync that sounds like it would do what you want. I get an error when I try it. It seems to expect your attachments to be in a git repository.
    – erikstokes
    Commented Apr 13, 2015 at 1:49
  • @erikstokes Now why on earth would someone make that assumption? :( I'll look into the function, thanks. Commented Apr 13, 2015 at 2:15

2 Answers 2

5

There is a function org-attach-sync that claims to do this, but it seems to be expecting you to keep your attachments in a git repository, which you may not be doing (I don't).

So, here's a function that uses org-attach-file-list to look at the list of attachments and change things appropriately. The :ATTACH: tag will be toggled and the Attachments property will be updated or deleted.

(defun org-sync-attachments ()
  "Update the current entry's attachment metadata."
  (interactive)
  (let* ((attachments (if (org-attach-dir)
                         (org-attach-file-list (org-attach-dir)))
                     )
        (tag-state (if attachments 'on 'off)))

    (if attachments 
        (org-set-property org-attach-file-list-property
                          (mapconcat #'url-encode-url
                                     attachments " "))
      (org-delete-property org-attach-file-list-property))
    (org-toggle-tag org-attach-auto-tag tag-state)
    ))
4
  • Works like a charm :) Commented Apr 13, 2015 at 4:21
  • To sync all items in a buffer, it's a simple (defun org-sync-attachments-all () (interactive) (save-excursion (goto-char 0) (while (search-forward-regexp "^\\*" nil t) (*-org-sync-attachments)))) Commented Apr 13, 2015 at 15:02
  • 1
    and a small note -- if your attachments have spaces in the file name, it's better to use #'url-encode-url instead of '#identity. Commented Apr 13, 2015 at 15:08
  • @SeanAllred Good catch on the file names with spaces. That would have bitten me eventually.
    – erikstokes
    Commented Apr 13, 2015 at 20:55
1

I figured out an alternative solution:

step 1: list all file attached in the current node

     M-x org-attach-reveal

step 2: in dired window: mark files you want to create link

    In dired window:  
       M-x dired-mark
       M-x org-attach-dired-to-subtree-store-links
https://emacs.stackexchange.com/questions/60359/is-there-a-quicker-way-to-create-links-to-attachments
The function org-attach-dired-to-subtree-store-links below is almost exactly a copy of org-attach-dired-to-subtree, except that instead of making attachments, it creates links that can be inserted into the Org mode buffer using org-insert-link (usually bound to C-C C-l if you follow the convention in the Org mode manual).

(defun org-attach-dired-to-subtree-store-links (files)
    "run in dired, push all file marked to org link store"
    (interactive
     (list (dired-get-marked-files)))
    (unless (eq major-mode 'dired-mode)
      (user-error "This command must be triggered in a dired buffer"))
    (let ((start-win (selected-window))
          (other-win
           (get-window-with-predicate
            (lambda (window)
              (with-current-buffer (window-buffer window)
                (eq major-mode 'org-mode))))))
      (unless other-win
        (user-error
         "Can't attach to subtree.  No window displaying an Org buffer"))
      (select-window other-win)
      (dolist (file files)
        (let* ((fname (file-name-nondirectory file))
               (link (format "attachment:%s" fname))
               (desc fname))
          (push (list link desc) org-stored-links)))
      (select-window start-win)))

step3: insert link of attachment file (you marked above) into org file

     M-x org-insert-all-links  "insert all links in org-stored-links"

Your Answer

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

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