lang/org: use org-attach instead of custom system
- Adds more keys under `<localleader> a` - Reconfigures org-download to use org-attach system - Make org-id-track-globally = t a global default now (not just for org-brain) - Renamed +org-init-centralized-attachments-h to +org-init-attachments-h - org-attach-store-link-p = t (stores a link to an attachment when it is attached) - org-attach-use-inheritance = t (inherit attachment properties from parent nodes)
This commit is contained in:
parent
54f42fef23
commit
14cf97e594
4 changed files with 62 additions and 119 deletions
|
@ -1,30 +1,5 @@
|
||||||
;;; lang/org/autoload/org-attach.el -*- lexical-binding: t; -*-
|
;;; lang/org/autoload/org-attach.el -*- lexical-binding: t; -*-
|
||||||
|
|
||||||
;;
|
|
||||||
(defvar +org-attachments nil
|
|
||||||
"A list of all indexed attachments in `org-directory'.")
|
|
||||||
|
|
||||||
(defvar +org-attachments-files nil
|
|
||||||
"A list of all attachments in `org-attach-id-dir'.")
|
|
||||||
|
|
||||||
(defun +org-list-attachments (&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-id-dir)))
|
|
||||||
(when (and (equal "file" (org-element-property :type context))
|
|
||||||
(file-in-directory-p link org-attach-id-dir))
|
|
||||||
(push (file-name-nondirectory link) attachments))))))
|
|
||||||
(cl-delete-duplicates attachments :test #'string=)))
|
|
||||||
|
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(defun +org-attach-icon-for (path)
|
(defun +org-attach-icon-for (path)
|
||||||
(char-to-string
|
(char-to-string
|
||||||
|
@ -39,63 +14,46 @@ and END (defaults to `point-min' and `point-max')."
|
||||||
((or "zip" "gz" "tar" "7z" "rar") ?)
|
((or "zip" "gz" "tar" "7z" "rar") ?)
|
||||||
(_ ?))))
|
(_ ?))))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun +org/open-gallery-from-attachments ()
|
||||||
|
"TODO"
|
||||||
|
(interactive)
|
||||||
|
(require 'org-attach)
|
||||||
|
(if-let (dir (org-attach-dir))
|
||||||
|
(pop-to-buffer
|
||||||
|
;; Rather than opening dired *and* image-dired windows, suppress them
|
||||||
|
;; both and open only the image-dired window.
|
||||||
|
(save-window-excursion
|
||||||
|
(image-dired dir)
|
||||||
|
(current-buffer)))
|
||||||
|
(user-error "No attachments for this node")))
|
||||||
|
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(defun +org-attach/sync (arg)
|
(defun +org/find-file-in-attachments ()
|
||||||
"Reindex all attachments in `org-directory' and delete orphaned attachments in
|
|
||||||
`org-attach-id-dir'. If ARG (universal arg), conduct a dry run."
|
|
||||||
(declare (interactive-only t))
|
|
||||||
(interactive "P")
|
|
||||||
(message "Reloading")
|
|
||||||
(setq +org-attachments-files (directory-files org-attach-id-dir nil "^[^.]" t))
|
|
||||||
(with-temp-buffer
|
|
||||||
(delay-mode-hooks (org-mode))
|
|
||||||
(dolist (org-file (directory-files-recursively org-directory "\\.org$"))
|
|
||||||
(insert-file-contents-literally org-file))
|
|
||||||
(setq +org-attachments (+org-list-attachments)))
|
|
||||||
;; clean up
|
|
||||||
(let ((deleted 0))
|
|
||||||
(dolist (file (cl-set-difference +org-attachments-files +org-attachments
|
|
||||||
:test #'string=))
|
|
||||||
(message "Deleting orphaned attachment: %s" file)
|
|
||||||
(cl-incf deleted)
|
|
||||||
(unless arg
|
|
||||||
(delete-file (expand-file-name file org-attach-id-dir))))
|
|
||||||
(message "Buffer's attachments synced (%d deleted)" deleted)))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun +org-attach/find-file ()
|
|
||||||
"Open a file from `org-attach-id-dir'."
|
"Open a file from `org-attach-id-dir'."
|
||||||
(interactive)
|
(interactive)
|
||||||
(doom-project-browse org-attach-id-dir))
|
(doom-project-browse org-attach-id-dir))
|
||||||
|
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(defun +org-attach/file (path)
|
(defun +org/attach-file-and-insert-link (path)
|
||||||
"Copies the file at PATH to `+org-attach-dir' and places an org link to it at
|
"Downloads the file at PATH and insert an org link at point.
|
||||||
the cursor."
|
PATH (a string) can be an url, a local file path, or a base64 encoded datauri."
|
||||||
(interactive "fAttach file: ")
|
|
||||||
(+org-attach/uri path))
|
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun +org-attach/uri (uri)
|
|
||||||
"Downloads the file at URL and place an org link to it at the cursor."
|
|
||||||
(interactive "sUri/file: ")
|
(interactive "sUri/file: ")
|
||||||
(unless (eq major-mode 'org-mode)
|
(unless (eq major-mode 'org-mode)
|
||||||
(user-error "Not in an org buffer"))
|
(user-error "Not in an org buffer"))
|
||||||
(require 'org-download)
|
(require 'org-download)
|
||||||
(let ((raw-uri (url-unhex-string uri)))
|
(condition-case ex
|
||||||
(condition-case ex
|
(let ((raw-uri (url-unhex-string path)))
|
||||||
(cond ((string-match-p "^data:image/png;base64," uri)
|
(cond ((string-match-p "^data:image/png;base64," path)
|
||||||
(org-download-dnd-base64 uri nil))
|
(org-download-dnd-base64 path nil))
|
||||||
((image-type-from-file-name raw-uri)
|
((image-type-from-file-name raw-uri)
|
||||||
(org-download-image raw-uri))
|
(org-download-image raw-uri))
|
||||||
(t
|
((let ((new-path (expand-file-name (org-download--fullname raw-uri))))
|
||||||
(let ((new-path (expand-file-name (org-download--fullname raw-uri))))
|
|
||||||
;; Download the file
|
;; Download the file
|
||||||
(if (string-match-p (concat "^" (regexp-opt '("http" "https" "nfs" "ftp" "file")) ":/") uri)
|
(if (string-match-p (concat "^" (regexp-opt '("http" "https" "nfs" "ftp" "file")) ":/") path)
|
||||||
(url-copy-file raw-uri new-path)
|
(url-copy-file raw-uri new-path)
|
||||||
(copy-file uri new-path))
|
(copy-file path new-path))
|
||||||
;; insert the link
|
;; insert the link
|
||||||
(org-download-insert-link raw-uri new-path))))
|
(org-download-insert-link raw-uri new-path)))))
|
||||||
(error
|
(error
|
||||||
(user-error "Failed to attach file: %s" (error-message-string ex))))))
|
(user-error "Failed to attach file: %s" (error-message-string ex)))))
|
||||||
|
|
|
@ -355,42 +355,14 @@ underlying, modified buffer. This fixes that."
|
||||||
(add-hook '+doom-dashboard-inhibit-functions #'+org-capture-frame-p)))
|
(add-hook '+doom-dashboard-inhibit-functions #'+org-capture-frame-p)))
|
||||||
|
|
||||||
|
|
||||||
(defun +org-init-centralized-attachments-h ()
|
(defun +org-init-attachments-h ()
|
||||||
"I believe Org's native attachment system is over-complicated and litters
|
"Sets up org's attachment system."
|
||||||
files with metadata I don't want. So I wrote my own, which:
|
;; Centralized attachments directory
|
||||||
|
(setq org-attach-id-dir (doom-path org-directory org-attach-id-dir)
|
||||||
+ Places attachments in a centralized location (`org-attach-id-dir' in
|
;; Store a link to attachments when they are attached
|
||||||
`org-directory').
|
org-attach-store-link-p t
|
||||||
+ Adds attach:* link abbreviation for quick links to these files from anywhere.
|
;; Inherit attachment properties from parent nodes
|
||||||
+ Use `+org-attach/sync' to index all attachments in `org-directory' that use
|
org-attach-use-inheritance t)
|
||||||
the attach:* abbreviation and delete orphaned ones that are no longer
|
|
||||||
referenced.
|
|
||||||
+ This compliments the +dragndrop flag which provides drag'n'drop support for
|
|
||||||
images (with preview) and media files.
|
|
||||||
|
|
||||||
Some commands of interest:
|
|
||||||
+ `org-download-screenshot'
|
|
||||||
+ `+org-attach/file'
|
|
||||||
+ `+org-attach/url'
|
|
||||||
+ `+org-attach/sync'"
|
|
||||||
(setq org-attach-id-dir (doom-path org-directory org-attach-id-dir))
|
|
||||||
|
|
||||||
;; A shorter link to attachments
|
|
||||||
(add-to-list 'org-link-abbrev-alist
|
|
||||||
(cons "attach"
|
|
||||||
(abbreviate-file-name org-attach-id-dir)))
|
|
||||||
|
|
||||||
(org-link-set-parameters
|
|
||||||
"attach"
|
|
||||||
:follow (lambda (link) (find-file (doom-path org-attach-id-dir link)))
|
|
||||||
:complete (lambda (&optional _arg)
|
|
||||||
(+org--relpath (+org-link-read-file "attach" org-attach-id-dir)
|
|
||||||
org-attach-id-dir))
|
|
||||||
:face (lambda (link)
|
|
||||||
(if (file-exists-p (expand-file-name link org-attach-id-dir))
|
|
||||||
'org-link
|
|
||||||
'error)))
|
|
||||||
|
|
||||||
(after! projectile
|
(after! projectile
|
||||||
(add-to-list 'projectile-globally-ignored-directories org-attach-id-dir)))
|
(add-to-list 'projectile-globally-ignored-directories org-attach-id-dir)))
|
||||||
|
|
||||||
|
@ -650,10 +622,21 @@ between the two."
|
||||||
"t" #'org-todo
|
"t" #'org-todo
|
||||||
"T" #'org-todo-list
|
"T" #'org-todo-list
|
||||||
(:prefix ("a" . "attachments")
|
(:prefix ("a" . "attachments")
|
||||||
"a" #'+org-attach/file
|
"a" #'org-attach
|
||||||
"u" #'+org-attach/uri
|
"d" #'org-attach-delete-one
|
||||||
"f" #'+org-attach/find-file
|
"D" #'org-attach-delete-all
|
||||||
"s" #'+org-attach/sync)
|
"f" #'+org/find-file-in-attachments
|
||||||
|
"l" #'+org/attach-file-and-insert-link
|
||||||
|
"n" #'org-attach-new
|
||||||
|
"o" #'org-attach-open
|
||||||
|
"O" #'org-attach-open-in-emacs
|
||||||
|
"r" #'org-attach-reveal
|
||||||
|
"R" #'org-attach-reveal-in-emacs
|
||||||
|
"u" #'org-attach-url
|
||||||
|
"s" #'org-attach-set-directory
|
||||||
|
"S" #'org-attach-sync
|
||||||
|
(:when (featurep! +dragndrop)
|
||||||
|
"y" #'org-download-yank))
|
||||||
(:prefix ("b" . "tables")
|
(:prefix ("b" . "tables")
|
||||||
"-" #'org-table-insert-hline
|
"-" #'org-table-insert-hline
|
||||||
"a" #'org-table-align
|
"a" #'org-table-align
|
||||||
|
@ -944,11 +927,14 @@ compelling reason, so..."
|
||||||
org-capture
|
org-capture
|
||||||
:preface
|
:preface
|
||||||
;; Change org defaults (should be set before org loads)
|
;; Change org defaults (should be set before org loads)
|
||||||
(defvar org-directory "~/org/")
|
(setq org-directory "~/org/"
|
||||||
(defvar org-attach-id-dir ".attach/")
|
org-attach-id-dir ".attach/"
|
||||||
|
org-publish-timestamp-directory (concat doom-cache-dir "org-timestamps/")
|
||||||
(setq org-publish-timestamp-directory (concat doom-cache-dir "org-timestamps/")
|
org-preview-latex-image-directory (concat doom-cache-dir "org-latex/")
|
||||||
org-preview-latex-image-directory (concat doom-cache-dir "org-latex/"))
|
org-id-locations-file (concat doom-etc-dir "org-id-locations")
|
||||||
|
;; Global ID state means we can have ID links anywhere (required by
|
||||||
|
;; `org-brain')
|
||||||
|
org-id-track-globally t)
|
||||||
|
|
||||||
(defvar org-modules
|
(defvar org-modules
|
||||||
'(;; ol-w3m
|
'(;; ol-w3m
|
||||||
|
@ -978,11 +964,11 @@ compelling reason, so..."
|
||||||
(add-hook! 'org-load-hook
|
(add-hook! 'org-load-hook
|
||||||
#'+org-init-appearance-h
|
#'+org-init-appearance-h
|
||||||
#'+org-init-agenda-h
|
#'+org-init-agenda-h
|
||||||
|
#'+org-init-attachments-h
|
||||||
#'+org-init-babel-h
|
#'+org-init-babel-h
|
||||||
#'+org-init-babel-lazy-loader-h
|
#'+org-init-babel-lazy-loader-h
|
||||||
#'+org-init-capture-defaults-h
|
#'+org-init-capture-defaults-h
|
||||||
#'+org-init-capture-frame-h
|
#'+org-init-capture-frame-h
|
||||||
#'+org-init-centralized-attachments-h
|
|
||||||
#'+org-init-centralized-exports-h
|
#'+org-init-centralized-exports-h
|
||||||
#'+org-init-custom-links-h
|
#'+org-init-custom-links-h
|
||||||
#'+org-init-export-h
|
#'+org-init-export-h
|
||||||
|
|
|
@ -4,9 +4,7 @@
|
||||||
(use-package! org-brain
|
(use-package! org-brain
|
||||||
:defer t
|
:defer t
|
||||||
:init
|
:init
|
||||||
(setq org-id-track-globally t
|
(setq org-brain-visualize-default-choices 'all
|
||||||
org-id-locations-file (concat doom-etc-dir "org-id-locations")
|
|
||||||
org-brain-visualize-default-choices 'all
|
|
||||||
org-brain-title-max-length 24
|
org-brain-title-max-length 24
|
||||||
org-brain-include-file-entries nil
|
org-brain-include-file-entries nil
|
||||||
org-brain-file-entries-use-title nil)
|
org-brain-file-entries-use-title nil)
|
||||||
|
|
|
@ -10,7 +10,8 @@
|
||||||
'("^data:" . org-download-dnd-base64))
|
'("^data:" . org-download-dnd-base64))
|
||||||
(advice-add #'org-download-enable :override #'ignore)
|
(advice-add #'org-download-enable :override #'ignore)
|
||||||
:config
|
:config
|
||||||
(setq org-download-image-dir org-attach-directory
|
(setq org-download-image-dir org-attach-id-dir
|
||||||
|
org-download-method 'attach
|
||||||
org-download-heading-lvl nil
|
org-download-heading-lvl nil
|
||||||
org-download-timestamp "_%Y%m%d_%H%M%S"
|
org-download-timestamp "_%Y%m%d_%H%M%S"
|
||||||
org-download-screenshot-method
|
org-download-screenshot-method
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue