lang/org: add +org-attach/sync (attachment management)

lang/org now supports the attach:* link abbreviation. Running
+org/attach-sync will index all such links across org files in +org-dir
and delete any files in org-attach-directory that aren't referenced.

TODO: have a separate directory for attach:* attachments and vanilla
attachments?
This commit is contained in:
Henrik Lissner 2018-02-18 04:30:49 -05:00
parent f4a0311834
commit e50d8b8733
No known key found for this signature in database
GPG key ID: 5F6C0EA160557395
2 changed files with 72 additions and 32 deletions

View file

@ -14,35 +14,58 @@
((or "zip" "gz" "tar" "7z" "rar") ?)
(_ ?))))
;; (defun +org-attach-cleanup ()
;; ;; "Deletes any attachments that are no longer present in the org-mode buffer."
;; (let* ((attachments-local (+org-attachments))
;; (attachments (directory-files org-attach-directory t "^[^.]" t))
;; (to-delete (cl-set-difference attachments-local attachments)))
;; ;; TODO
;; to-delete))
;; (defun +org-attachments ()
;; "List all attachments in the current buffer."
;; (unless (eq major-mode 'org-mode)
;; (user-error "Not an org buffer"))
;; (org-save-outline-visibility nil
;; (let ((attachments '())
;; element)
;; (when (and (file-directory-p org-attach-directory)
;; (> (length (file-expand-wildcards (expand-file-name "*" org-attach-directory))) 0))
;; (save-excursion
;; (goto-char (point-min))
;; (while (progn (org-next-link) (not org-link-search-failed))
;; (setq element (org-element-context))
;; (when-let* (file (and (eq (org-element-type element) 'link)
;; (expand-file-name (org-element-property :path element))))
;; (when (and (string= (org-element-property :type element) "file")
;; (string= (concat (file-name-base (directory-file-name (file-name-directory file))) "/")
;; org-attach-directory)
;; (file-exists-p file))
;; (push file attachments))))))
;; (cl-remove-duplicates attachments))))
;;
(defvar +org-attachments nil
"A list of all indexed attachments in `+org-dir'.")
(defvar +org-attachments-files value
"A list of all attachments in `org-attach-directory'.")
(defun +org-attachments--list (&optional beg end)
"Return a list of all attachment file names in the current buffer between BEG
and END (defaults to `point-min' and `point-max')."
(let ((case-fold-search t)
attachments)
(or end (setq end (point-max)))
(org-save-outline-visibility nil
(org-with-wide-buffer
(goto-char (or beg (point-min)))
(while (search-forward "[[attach:" end t)
(let* ((context (save-match-data (org-element-context)))
(link (expand-file-name (org-link-unescape (org-element-property :path context))
org-attach-directory)))
(when (and (equal "file" (org-element-property :type context))
(file-in-directory-p link org-attach-directory))
(push (file-name-nondirectory link) attachments))))))
(cl-delete-duplicates attachments :test #'string=)))
;;;###autoload
(defun +org-attach/sync (arg)
"Reindex all attachments in `+org-dir' and delete orphaned attachments in
`org-attach-directory'. If ARG (universal arg), conduct a dry run."
(declare (interactive-only t))
(interactive "P")
(message "Reloading")
(setq +org-attachments-files (directory-files org-attach-directory nil "^[^.]" t))
(with-temp-buffer
(delay-mode-hooks (org-mode))
(dolist (org-file (directory-files-recursively +org-dir "\\.org$"))
(insert-file-contents-literally org-file))
(setq +org-attachments (+org-attachments--list)))
;; clean up
(dolist (file (cl-set-difference +org-attachments-files +org-attachments
:test #'string=))
(message "Deleting orphaned attachment: %s" file)
(unless arg
(delete-file (expand-file-name file org-attach-directory))))
(message "Buffer's attachments synced"))
;;;###autoload
(defun +org-attach/find-file ()
"Open a file from `org-attach-directory'."
(interactive)
(doom-project-browse org-attach-directory))
;;;###autoload
(defun +org-attach/file (path)
@ -84,6 +107,11 @@ the cursor."
(copy-alist dnd-protocol-alist))))
(dnd-handle-one-url nil action uri))))
;;
;; Advice
;;
;;;###autoload
(defun +org-attach*insert-link (_link filename)
"Produces and inserts a link to FILENAME into the document.