Browse Source

helper functions to automate agenda files update for org-roam files

master
Marc 1 year ago
parent
commit
dd0060b8c0
1 changed files with 132 additions and 11 deletions
  1. 143
      config.org

143
config.org

@ -818,7 +818,17 @@ If the property is already set, replace its value."
; (add-hook 'org-mode-hook 'org-indent-mode) ; (add-hook 'org-mode-hook 'org-indent-mode)
:bind (:map org-mode-map ("S-<right>" . org-shiftright) :bind (:map org-mode-map ("S-<right>" . org-shiftright)
("S-<left>" . org-shiftleft)) ("S-<left>" . org-shiftleft))
:init
(defun my--org-agenda-files-set ()
"Sets default agenda files.
Necessary when updating roam agenda todos."
(setq org-agenda-files (list (concat MY--PATH_ORG_FILES "notes.org")
(concat MY--PATH_ORG_FILES "projects.org")
(concat MY--PATH_ORG_FILES "tasks.org")))
(when *sys/linux*
(nconc org-agenda-files
(directory-files-recursively MY--PATH_ORG_FILES_MOBILE "\\.org$"))))
(my--org-agenda-files-set)
:config :config
(defun my--org-company () (defun my--org-company ()
(set (make-local-variable 'company-backends) (set (make-local-variable 'company-backends)
@ -829,14 +839,7 @@ If the property is already set, replace its value."
org-habit org-habit
org-tempo ;; easy templates org-tempo ;; easy templates
))) )))
(setq org-default-notes-file (concat MY--PATH_ORG_FILES "notes.org")
org-agenda-files (list (concat MY--PATH_ORG_FILES "notes.org")
(concat MY--PATH_ORG_FILES "projects.org")
(concat MY--PATH_ORG_FILES "tasks.org")))
(when *sys/linux*
(nconc org-agenda-files
(directory-files-recursively MY--PATH_ORG_FILES_MOBILE "\\.org$")))
(setq org-default-notes-file (concat MY--PATH_ORG_FILES "notes.org"))
(setq org-id-locations-file (concat MY--PATH_USER_LOCAL ".org-id-locations") (setq org-id-locations-file (concat MY--PATH_USER_LOCAL ".org-id-locations")
org-log-into-drawer "LOGBOOK") org-log-into-drawer "LOGBOOK")
@ -1066,7 +1069,118 @@ org-roam-db-sync
:after org :after org
:init :init
(setq org-roam-v2-ack t) (setq org-roam-v2-ack t)
(defun my--project-p ()
"Return non-nil if current buffer has any todo entry.
TODO entries marked as done are ignored, meaning this function
returns nil if current buffer contains only completed tasks."
(seq-find
(lambda (type)
(eq type 'todo))
(org-element-map
(org-element-parse-buffer 'headline)
'headline
(lambda (h)
(org-element-property :todo-type h)))))
(defun my--project-update-tag ()
"Update PROJECT tag in the current buffer."
(when (and (not (active-minibuffer-window))
(my--buffer-roam-note-p))
(save-excursion
(goto-char (point-min))
(let* ((tags (my--buffer-tags-get))
(original-tags tags))
(if (my--project-p)
(setq tags (cons "project" tags))
(setq tags (remove "project" tags)))
;;cleanup duplicates
(when (or (seq-difference tags original-tags)
(seq-difference original-tags tags))
(apply #'my--buffer-tags-set tags))))))
(defun my--buffer-tags-get ()
"Return filetags value in current buffer."
(my--buffer-prop-get-list "filetags" "[ :]"))
(defun my--buffer-tags-set (&rest tags)
"Set TAGS in current buffer.
If filetags value is already set, replace it."
(if tags
(my--buffer-prop-set
"filetags" (concat ":" (string-join tags ":") ":"))
(my--buffer-prop-remove "filetags")))
(defun my--buffer-tags-add (tag)
"Add a TAG to filetags in current buffer."
(let* ((tags (my--buffer-tags-get))
(tags (append tags (list tag))))
(apply #'my--buffer-tags-set tags)))
(defun my--buffer-tags-remove (tag)
"Remove a TAG from filetags in current buffer."
(let* ((tags (my--buffer-tags-get))
(tags (delete tag tags)))
(apply #'my--buffer-tags-set tags)))
(defun my--buffer-prop-set (name value)
"Set a file property called NAME to VALUE in buffer file.
If the property is already set, replace its value."
(setq name (downcase name))
(org-with-point-at 1
(let ((case-fold-search t))
(if (re-search-forward (concat "^#\\+" name ":\\(.*\\)")
(point-max) t)
(replace-match (concat "#+" name ": " value) 'fixedcase)
(while (and (not (eobp))
(looking-at "^[#:]"))
(if (save-excursion (end-of-line) (eobp))
(progn
(end-of-line)
(insert "\n"))
(forward-line)
(beginning-of-line)))
(insert "#+" name ": " value "\n")))))
(defun my--buffer-prop-set-list (name values &optional separators)
"Set a file property called NAME to VALUES in current buffer.
VALUES are quoted and combined into single string using
`combine-and-quote-strings'.
If SEPARATORS is non-nil, it should be a regular expression
matching text that separates, but is not part of, the substrings.
If nil it defaults to `split-string-and-unquote', normally
\"[ \f\t\n\r\v]+\", and OMIT-NULLS is forced to t.
If the property is already set, replace its value."
(my--buffer-prop-set
name (combine-and-quote-strings values separators)))
(defun my--buffer-prop-get (name)
"Get a buffer property called NAME as a string."
(org-with-point-at 1
(when (re-search-forward (concat "^#\\+" name ": \\(.*\\)")
(point-max) t)
(buffer-substring-no-properties
(match-beginning 1)
(match-end 1)))))
(defun my--buffer-prop-get-list (name &optional separators)
"Get a buffer property NAME as a list using SEPARATORS.
If SEPARATORS is non-nil, it should be a regular expression
matching text that separates, but is not part of, the substrings.
If nil it defaults to `split-string-default-separators', normally
\"[ \f\t\n\r\v]+\", and OMIT-NULLS is forced to t."
(let ((value (my--buffer-prop-get name)))
(when (and value (not (string-empty-p value)))
(split-string-and-unquote value separators))))
(defun my--buffer-prop-remove (name)
"Remove a buffer property called NAME."
(org-with-point-at 1
(when (re-search-forward (concat "\\(^#\\+" name ":.*\n?\\)")
(point-max) t)
(replace-match ""))))
(defun my--buffer-roam-note-p () (defun my--buffer-roam-note-p ()
"Return non-nil if the currently visited buffer is a note." "Return non-nil if the currently visited buffer is a note."
(and buffer-file-name (and buffer-file-name
@ -1085,11 +1199,18 @@ org-roam-db-sync
(org-roam-node-list)))) (org-roam-node-list))))
(defun my/org-roam-refresh-agenda-list () (defun my/org-roam-refresh-agenda-list ()
"Add all org roam files with #+filetags: Project"
"Add all org roam files with #+filetags: project"
(interactive) (interactive)
(my--org-agenda-files-set)
(nconc org-agenda-files (nconc org-agenda-files
(my--org-roam-list-notes-by-tag "Project"))
(my--org-roam-list-notes-by-tag "project"))
(setq org-agenda-files (delete-dups org-agenda-files))) (setq org-agenda-files (delete-dups org-agenda-files)))
(add-hook 'find-file-hook #'my--project-update-tag)
(add-hook 'before-save-hook #'my--project-update-tag)
(advice-add 'org-agenda :before #'my/org-roam-refresh-agenda-list)
(advice-add 'org-todo-list :before #'my/org-roam-refresh-agenda-list)
:config :config
(require 'org-roam-dailies) ;; ensure the keymap is available (require 'org-roam-dailies) ;; ensure the keymap is available
(org-roam-db-autosync-mode) (org-roam-db-autosync-mode)

Loading…
Cancel
Save