The Complete Computer

Dynamic and fast agenda

LifeTechEmacsArcology
emacs-lisp source: 
(provide 'cce/dynamic-fast-agenda)

Archive of this blog post about keeping the size of the org-agenda-files list as light as it can be

In my experience, once I reached 1200 note files, org-agenda constantly took more than 50 seconds to build, rendering this tool completely useless. But then I realised that only 3% of those files actually contain any TODO entries, so there is no need to traverse whole org-roam-directory!

This is a clever use of the org-roam APIs and database to automatically populate the Org-mode Agendas file list, and has some really neat ideas which I'll integrate in to the CCE I think. Without migrating out of Projects , I have files which are Project and Agendize tagged.

I use this to keep track of todo items in my org day-journal, to split out work that needs to be done in my Agendas, and not to lose track of long-term or low priority projects

It works by having a save-hook that adds or removes a Project filetag if there are any TODO items on the page, and then there is a hook in the org-agenda functionality to use the org-roam database

org-element search and update

I might turn this off.

There is some really sharp code in here to use the roam:Org Element API to search for TODO headlines and add a Project tag to the ROAM_TAGS org-roam metadata keyword:

emacs-lisp source: 
(defun +org-notes-project-p () "Return non-nil if current buffer has any todo entry. TODO entries marked as done are ignored, meaning the 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))))) (add-hook 'before-save-hook #'+org-notes-project-update-tag) (defun +org-notes-project-update-tag () "Update PROJECT tag in the current buffer." (when (eq major-mode 'org-mode) (save-excursion (goto-char (point-min)) (when (and (not (active-minibuffer-window)) (+org-notes-buffer-p)) (if (+org-notes-project-p) (org-roam-tag-add '("Project")) (org-roam-tag-remove '("Project"))))))) (defun +org-notes-buffer-p () "Return non-nil if the currently visited buffer is a note." (and buffer-file-name (string-prefix-p (expand-file-name (file-name-as-directory org-roam-directory)) (file-name-directory buffer-file-name))))

DONE Evaluate turning this off.

  • Note taken on [2021-04-06 Tue 17:24]
    i think this works pretty well, now that i have it working...

  • State "DONE" from "NEXT" [2021-04-06 Tue 17:24]

I'm not sure I want this on by default, but it seems nice and great to have documented lying around.

org-agenda-list updating

a query against the org-roam tags table is unfortunately un-normalized. I want to add Agendize roam tag to it as well, and since it's non-normal and I think unsorted in the DB i need to be careful about it. Finally, remove files tagged Icebox. it basically works though:

emacs-lisp source: :results none
(defun cce/org-roam-tags-for-file (file) (org-roam-db-query [:select [tag] :from tags :inner :join nodes :on (= node-id id) :where (= file $s1)] file)) (defun cce/org-roam-files-with-tags (&optional tags exclusion) "Return a list of note files containing Project tag." (let ((tags (or tags '("Project" "Agendize"))) (exclusion (or exclusion '("Icebox"))) (filter-fn (lambda (file) (not (-intersection (apply #'append (cce/org-roam-tags-for-file file)) exclusion))))) (thread-last tags (mapcar #'arcology-files-by-tag) (apply #'append) (seq-filter filter-fn))))

and an advice function to update the DB before showing the agenda:

emacs-lisp source: :results none
(defun cce/agenda-files-update (&rest _) "Update the value of `org-agenda-files'." (setq org-agenda-files (cce/org-roam-files-with-tags))) (advice-add 'org-agenda :before #'cce/agenda-files-update)

Tasks

DONE extend this to include Journal tasks!

  • State "DONE" from "NEXT" [2021-03-01 Mon 22:33]

  • Note taken on [2021-03-01 Mon 16:52]
    those should have a ROAMTAG anyways.......