aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Tom Willemse2022-04-01 18:37:10 -0700
committerGravatar Tom Willemse2022-04-01 18:37:10 -0700
commit641f7364785a19327195251595634b32827ef1df (patch)
tree8b96a219b8927e0e2ceb85f0a70c44be345d7afe
parent2dd841ffc3a1b8870559845dea49a78ae1eb014c (diff)
downloademacs-config-641f7364785a19327195251595634b32827ef1df.tar.gz
emacs-config-641f7364785a19327195251595634b32827ef1df.zip
[oni-org] Add dynamic block for org for linking together projects
This is similar to my backlinks dynamic block, but it supports links by id and will print them as a checkbox so that the project can track progress by using the progress cookies.
-rw-r--r--oni-org/oni-org.el44
1 files changed, 44 insertions, 0 deletions
diff --git a/oni-org/oni-org.el b/oni-org/oni-org.el
index b6d9105..6bdf04c 100644
--- a/oni-org/oni-org.el
+++ b/oni-org/oni-org.el
@@ -810,5 +810,49 @@ This is an around advice for ‘org-html--svg-image’ as FUN."
(add-to-list 'org-duration-units `("p" . ,oni-org-pomodoro-duration))
(org-duration-set-regexps))
+;;; Projects
+
+(defun oni-org-pick-project (property)
+ (when (string= property "PROJECT")
+ (org-map-entries (lambda () (concat (buffer-name) ":" (mapconcat (lambda (x) x) (org-get-outline-path t) ":"))) "CATEGORY=\"project\"")))
+
+(defun oni-org-link-project (value)
+ (let* ((split-value (split-string value ":"))
+ (marker (org-find-olp split-value)))
+ (save-excursion
+ (goto-char marker)
+ (format "[[id:%s][%s]]" (org-id-get-create) (car (last split-value))))))
+
+(add-to-list 'org-properties-postprocess-alist '("PROJECT" . oni-org-link-project))
+
+(add-hook 'org-property-allowed-value-functions #'oni-org-pick-project)
+
+(defun oni-org-dblock-write-project-steps (_params)
+ "Generate backlinks to org headings."
+ (let ((current-heading (nth 4 (org-heading-components)))
+ (current-heading-id
+ (let ((properties (org-entry-properties)))
+ (or (alist-get "CUSTOM_ID" properties nil nil #'string=)
+ (org-id-get-create))))
+ backlinks)
+ (when (not (null current-heading-id))
+ (save-excursion
+ (goto-char (point-min))
+ (while (re-search-forward (rx-to-string `(or (seq "[[id:" ,current-heading-id "]")
+ (seq "#" ,current-heading-id "]"))) nil t)
+ (unless (or (oni-org-in-dblock-p)
+ (oni-org-at-origin-property-p))
+ (let ((components (org-heading-components)))
+ (push (list (org-entry-is-done-p) (point) (nth 4 components)) backlinks))))))
+ (insert (string-join
+ (mapcar (lambda (link)
+ (concat "- " (if (car link) "[X]" "[ ]") " [[*" (caddr link) "][" (caddr link) "]]"))
+ (sort (seq-uniq backlinks (lambda (a b) (= (cadr a) (cadr b))))
+ (lambda (a b) (< (cadr a) (cadr b)))))
+ "\n"))
+ (org-update-statistics-cookies nil)))
+
+(defalias 'org-dblock-write:oni-project-steps 'oni-org-dblock-write-project-steps)
+
(provide 'oni-org)
;;; oni-org.el ends here