changelog shortlog graph tags branches files raw help

Mercurial > core / changeset: inbox compaction

changeset 631: 0b82a2893d26
parent 630: f4a464cc1628
child 632: bbd9024f2fe2
author: Richard Westhaver <ellis@rwest.io>
date: Fri, 30 Aug 2024 21:29:55 -0400
files: emacs/lib/inbox.el emacs/lib/ulang.el lisp/user.asd
description: inbox compaction
     1.1--- a/emacs/lib/inbox.el	Wed Aug 28 22:08:42 2024 -0400
     1.2+++ b/emacs/lib/inbox.el	Fri Aug 30 21:29:55 2024 -0400
     1.3@@ -89,22 +89,12 @@
     1.4         ("s" "secret" table-line (file+function "krypt" org-ask-location) "| %^{key} | %^{val} |" :immediate-finish t :kill-buffer t)
     1.5         ("N" "note-item" plain (file+function "notes.org" org-ask-location) "%?")))
     1.6 
     1.7-(defun org-insert-logbook-drawer () (org-log-beginning t))
     1.8-
     1.9-;; (add-hook 'org-capture-mode-hook
    1.10-;;           #'org-insert-logbook-drawer)
    1.11-
    1.12 (add-hook 'org-after-todo-state-change-hook #'org-id-get-create)
    1.13 (add-hook 'org-after-todo-state-change-hook #'org-expiry-insert-created)
    1.14 
    1.15-(add-hook 'org-capture-mode-hook
    1.16-  #'org-id-get-create)
    1.17-
    1.18-(add-hook 'org-capture-mode-hook
    1.19-          #'org-expiry-insert-created)
    1.20-
    1.21 (setq org-default-notes-file (join-paths org-directory "inbox.org")
    1.22-      org-capture-use-agenda-date t)
    1.23+      org-capture-use-agenda-date t
    1.24+      org-archive-location "archive.org::")
    1.25 
    1.26 ;;; Utils
    1.27 ;; `org-archive-all-done' doesn't work the way we want. This function
    1.28@@ -128,120 +118,36 @@
    1.29      (org-todo "DONE"))
    1.30    nil 'tree)))
    1.31 
    1.32-(defun org-inbox-migrate ()
    1.33-  "Migrate all sub-headings to the current week heading, archive
    1.34-DONE tasks, and delete the empty previous week heading."
    1.35-  (interactive)
    1.36-  (let ((scope 'tree)
    1.37-        (cur (org-inbox-current-week-heading))
    1.38-        ;; (prev (format-iso-week-number
    1.39-        ;; (float-time (time-subtract (current-time) (days-to-time 7)))))
    1.40-        (pos (save-excursion
    1.41-               (find-file-noselect org-inbox-file)
    1.42-               (org-find-exact-headline-in-buffer
    1.43-                (org-inbox-current-week-heading) nil t))))
    1.44-    (org-archive-done)
    1.45-    (org-map-entries
    1.46-     (lambda ()
    1.47-       (org-refile nil nil (list cur org-inbox-file nil pos))
    1.48-       (setq org-map-continue-from (org-element-property :begin (org-element-at-point)))
    1.49-       (setq pos (org-find-exact-headline-in-buffer cur nil t)))
    1.50-     "LEVEL=2" scope)
    1.51-    (org-inbox-delete-week-heading)))
    1.52-
    1.53-(defun org-inbox-week-heading-p ()
    1.54-  "Check if the heading at point is an org-inbox week heading."
    1.55-  (let ((hd (org-heading-components)))
    1.56-    (when (and (eq (car hd) 1)
    1.57-               (null (caddr hd))
    1.58-               (null (cadddr hd))
    1.59-               (string-match "^w[0-9][0-9]$" (nth 4 hd))
    1.60-               (string-match "^:\\([0-9]\\)\\{4\\}:[A-Z]\\([a-z]\\)\\{2\\}:$" (nth 5 hd)))
    1.61-      t)))
    1.62-
    1.63-(defun org-inbox-current-week-p ()
    1.64-  "Check if the inbox has a heading for current week."
    1.65-  (let ((buf (find-buffer-visiting org-inbox-file)))
    1.66-    (unless buf
    1.67-      (setq buf (find-file-noselect org-inbox-file)))
    1.68-    (save-excursion
    1.69-      (with-current-buffer buf
    1.70-        (goto-char (point-max))
    1.71-        (if (re-search-backward (concat "^* " (format-iso-week-number)) nil t) t)))))
    1.72-
    1.73-(defun org-inbox-delete-week-heading ()
    1.74-  "Delete the week heading at point."
    1.75-  (interactive)
    1.76-  (if (not (org-inbox-week-heading-p))
    1.77-      (if (= (org-current-level) 1)
    1.78-          (message "Failed to find a week heading at point")
    1.79-        (progn (org-up-heading-safe)
    1.80-               (org-inbox-delete-week-heading)))
    1.81-    (progn (org-mark-subtree)
    1.82-           (delete-region (region-beginning) (region-end)))))
    1.83-
    1.84-(defun org-inbox-insert-week-heading ()
    1.85-  "Insert a new heading for the current week.
    1.86-Format:
    1.87-* w01 :2023:Jan:
    1.88-  SCHEDULED: <2023-01-02 Mon>--<2023-01-09 Sun>
    1.89-"
    1.90-  (interactive)
    1.91-  (let ((buf (find-buffer-visiting org-inbox-file)))
    1.92-    (unless buf
    1.93-      (setq buf (find-file-noselect org-inbox-file)))
    1.94-    (save-excursion
    1.95-      (with-current-buffer buf
    1.96-        (goto-char (point-max))
    1.97-        (org-previous-visible-heading 1)
    1.98-        (while (> (org-outline-level) 1)
    1.99-          (outline-up-heading 1))
   1.100-        (let* ((fmt org-inbox-date-start-format)
   1.101-               (date-start
   1.102-                (time-add
   1.103-                 (org-timestamp-to-time
   1.104-                  (org-timestamp-from-string
   1.105-                   (plist-get
   1.106-                    (cadr (org-element-at-point))
   1.107-                    :DATE_START)))
   1.108-                 (days-to-time 7)))
   1.109-               (date-end (format-time-string fmt (last-day-of-week date-start)))
   1.110-               (title (format-iso-week-number date-start))
   1.111-               (elt (org-element-interpret-data
   1.112-                     `(headline
   1.113-                       (:title ,title :level 1 :tags (,(format-time-string "%Y:%b" date-start)))
   1.114-                       (property-drawer nil
   1.115-                                        ((node-property
   1.116-                                          (:key "DATE_START" :value ,(format-time-string fmt date-start)))))))))
   1.117-          (goto-char (point-max))
   1.118-          (newline)
   1.119-          (insert elt)
   1.120-          title)))))
   1.121-
   1.122-(defun org-inbox-current-week-heading ()
   1.123-  "Find the location of the current week heading in
   1.124-  `org-inbox-file'. Create it if it doesn't exist."
   1.125-  (if (org-inbox-current-week-p)
   1.126-      (format-iso-week-number)
   1.127-    (org-inbox-insert-week-heading)))
   1.128+(defmacro with-inbox-buffer (&rest body)
   1.129+  `(save-excursion
   1.130+     (with-current-buffer (find-file org-inbox-file)
   1.131+       ,@body)))
   1.132 
   1.133 (defun org-sort-todo-priority ()
   1.134   "Sorting function used by `org-sort' to sort by todo order
   1.135     followed by priority. Returns a pair of numbers (TODO . PRIO)."
   1.136   (let* ((elt (cadr (org-element-at-point)))
   1.137-         (todo (substring-no-properties (plist-get elt :todo-keyword)))
   1.138-         (prio (plist-get elt :priority))
   1.139+         (todo (when-let ((kw (plist-get elt :todo-keyword)))
   1.140+                 (when (stringp kw)
   1.141+                   (substring-no-properties kw))))
   1.142+         (prio (pcase (plist-get elt :priority)
   1.143+                 ("A" 1)
   1.144+                 ("B" 2)
   1.145+                 ("C" 3)
   1.146+                 (t 2)))
   1.147          (res))
   1.148-    (message "%s %s" todo prio)
   1.149-    (unless prio (setq prio 5))
   1.150     ;; FIXME todo states shouldn't be hardcoded
   1.151     (cond
   1.152-     ((string= todo "GOTO") (setq res (cons 1 prio)))
   1.153+     ((null todo) (setq res (cons 3 prio)))
   1.154+     ((string= todo "WATCH") (setq res (cons 3 prio)))
   1.155+     ((string= todo "WAIT") (setq res (cons 1 prio)))
   1.156+     ((string= todo "HOLD") (setq res (cons 1 prio)))
   1.157+     ((string= todo "WIP") (setq res (cons 1 prio)))
   1.158+     ((string= todo "GOTO") (setq res (cons 2 prio)))
   1.159      ((string= todo "TODO") (setq res (cons 2 prio)))
   1.160-     ((string= todo "WAIT") (setq res (cons 3 prio)))
   1.161-     ((string= todo "HOLD") (setq res (cons 4 prio)))
   1.162-     ((string= todo "DONE") (setq res (cons 5 prio)))
   1.163-     ((string= todo "NOPE") (setq res (cons 6 prio))))
   1.164+     ((string= todo "RESEARCH") (setq res (cons 3 prio)))
   1.165+     ((string= todo "DONE") (setq res (cons 4 prio)))
   1.166+     ((string= todo "NOPE") (setq res (cons 4 prio))))
   1.167     (unless res (setq res (cons 0 prio)))
   1.168     res))
   1.169 
   1.170@@ -255,14 +161,24 @@
   1.171    ((= (car a) (car b))
   1.172     (cond
   1.173      ((< (cdr a) (cdr b)) t)
   1.174-     ((> (cdr a) (cdr b)) nil)
   1.175-     ;; nil ommitted since cond defaults to it
   1.176-     ))))
   1.177+     ((> (cdr a) (cdr b)) nil)))))
   1.178+     
   1.179 
   1.180 (defun org-inbox-sort ()
   1.181   "Sort the current heading by todo order followed by priority."
   1.182   (interactive)
   1.183-  (org-sort-entries nil ?f #'org-sort-todo-priority #'org-sort-compare-todo-priority))
   1.184+  (with-inbox-buffer
   1.185+   (org-sort-entries nil ?f #'org-sort-todo-priority #'org-sort-compare-todo-priority)))
   1.186+
   1.187+(defun org-inbox-compact ()
   1.188+  "Assign missing IDs and creation dates, archive DONE tasks."
   1.189+  (interactive)
   1.190+  (with-inbox-buffer
   1.191+   (org-id-update-id-locations)
   1.192+   (org-id-add-to-headlines-in-file)
   1.193+   (org-archive-done)
   1.194+   (org-map-entries #'org-expiry-insert-created)
   1.195+   (org-inbox-sort)))
   1.196 
   1.197 (defun org-inbox-open ()
   1.198   "Open `org-inbox-file' or switch to its buffer if already open."
     2.1--- a/emacs/lib/ulang.el	Wed Aug 28 22:08:42 2024 -0400
     2.2+++ b/emacs/lib/ulang.el	Fri Aug 30 21:29:55 2024 -0400
     2.3@@ -33,13 +33,14 @@
     2.4 (defvar ulang-link-history nil)
     2.5 (defvar ulang-file-history nil)
     2.6 
     2.7-(defvar ulang-extra-properties
     2.8+;; see org-special-properties
     2.9+(defvar ulang-special-properties
    2.10   '("VERSION"))
    2.11 
    2.12 ;;;###autoload
    2.13 (defun dblock-insert-links (regexp)
    2.14   "Create dblock to insert links matching REGEXP."
    2.15-  (interactive (list (read-regexp "Insert links matching: " nil ulang-links-history)))
    2.16+  (interactive (list (read-regexp "Insert links matching: " nil ulang-link-history)))
    2.17   (org-create-dblock (list :name "links"
    2.18                            :regexp regexp
    2.19                            :id-only nil))
    2.20@@ -143,4 +144,18 @@
    2.21 (message "Initialized ULANG.")
    2.22 
    2.23 (provide 'ulang)
    2.24+;;; Commands
    2.25+
    2.26+;; (org-property-inherit-p "LOCATION")
    2.27+(defun org-follow-location ()
    2.28+  "Open the location specified by the LOCATION property of the org heading
    2.29+or file at point."
    2.30+  (interactive)
    2.31+  (let ((loc (or (org-entry-get-with-inheritance "LOCATION")
    2.32+                 (caadar (org-collect-keywords '("LOCATION") nil '("LOCATION"))))))
    2.33+    (cond
    2.34+     ((string-match-p org-link-any-re loc) (org-link-open-from-string loc))
    2.35+     ;; TODO 2024-08-29: handle other location types (physical, etc)
    2.36+     (t (find-file loc t)))))
    2.37+
    2.38 ;;; ulang.el ends here
     3.1--- a/lisp/user.asd	Wed Aug 28 22:08:42 2024 -0400
     3.2+++ b/lisp/user.asd	Fri Aug 30 21:29:55 2024 -0400
     3.3@@ -3,7 +3,9 @@
     3.4   :depends-on (:std :cli :doc :nlp
     3.5                :obj :skel :syn :organ
     3.6                :packy :parse :pod :rdb
     3.7-               :krypt :gui :aud)
     3.8+               :krypt :gui :aud :net
     3.9+               :krypt :rt :vc :dat
    3.10+               :q :box :log :gui)
    3.11   :components ((:file "user"))
    3.12   :build-operation monolithic-compile-bundle-op
    3.13   :build-pathname "user")