ENH track ancestry for buffer status functions

This commit is contained in:
Nathan Dwarshuis 2022-04-26 18:53:34 -04:00
parent e63f83b2a7
commit a4b78d226e
1 changed files with 136 additions and 83 deletions

View File

@ -651,19 +651,15 @@ used for optimization."
(cl-flet* (cl-flet*
((wrap-ancestry ((wrap-ancestry
(form) (form)
`(list :ancestry ,ancestry :status ,form)) `(list :ancestry ,ancestry :local ,form))
(lift-form (lift-form
(form) (form)
;; `(let ((r ,form))
;; (unless r
;; (print 'hi))
;; (either<$> ,form (list :ancestry ancestry :status it)))))
`(either<$> ,form ,(wrap-ancestry 'it)))) `(either<$> ,form ,(wrap-ancestry 'it))))
(let ((canc-bs-form* (wrap-ancestry canc-bs-form)) (let ((canc-bs-form* (wrap-ancestry canc-bs-form))
(done-form* (lift-form done-form)) (done-form* (lift-form done-form))
(open-form* (lift-form open-form))) (open-form* (lift-form open-form)))
`(-let ((it-children (--map (either>>= it `(-let ((it-children (--map (either>>= it
(->> (plist-get it :status) (->> (plist-get it :local)
(either :right))) (either :right)))
,child-bss))) ,child-bss)))
;; (print "----") ;; (print "----")
@ -1042,8 +1038,8 @@ used for optimization."
#'org-x-dag-bs-action-subiter #'org-x-dag-bs-action-subiter
(lambda (node-data ancestry child-bss) (lambda (node-data ancestry child-bss)
(either<$> (org-x-dag-bs-action-iter-inner node-data ancestry child-bss) (either<$> (org-x-dag-bs-action-iter-inner node-data ancestry child-bss)
(-let (((&plist :ancestry a :status s) it)) (-let (((&plist :ancestry a :local l) it))
(list :ancestry a :status (cons :sp-iter s))))))) (list :ancestry a :local (cons :sp-iter l)))))))
(defun org-x-dag-bs-action-project (tree ancestry) (defun org-x-dag-bs-action-project (tree ancestry)
(if (org-x-dag-node-is-iterator-p (car tree)) (if (org-x-dag-node-is-iterator-p (car tree))
@ -1056,16 +1052,24 @@ used for optimization."
#'org-x-dag-bs-action-project #'org-x-dag-bs-action-project
#'org-x-dag-bs-action-project-inner))) #'org-x-dag-bs-action-project-inner)))
(defun org-x-dag-bs-prefix (key nodes)
(--map (org-x-dag-node-fmap it (either<$> it `(,key ,@it))) nodes))
(defun org-x-dag-bs-action (node-tree) (defun org-x-dag-bs-action (node-tree)
(cl-flet (cl-flet
((lift-subiter ((lift-subiter
(node) (node)
(org-x-dag-node-fmap node (org-x-dag-node-fmap node
(either<$> it (cons :sp-subiter it))))) (either<$> it
(-let (((&plist :ancestry a :local l) it))
(list :ancestry a :local (cons :sp-subiter l)))))))
;; (org-x-dag-node-fmap node
;; (either<$> it (cons :sp-subiter it)))))
(-let (((p (ps is)) (->> (list :canceled-parent-p nil (-let (((p (ps is)) (->> (list :canceled-parent-p nil
:held-parent-p nil) :held-parent-p nil)
(org-x-dag-bs-action-project node-tree)))) (org-x-dag-bs-action-project node-tree))))
`(,p ,@ps ,@(-map #'lift-subiter is))))) (->> `(,p ,@ps ,@(-map #'lift-subiter is))
(org-x-dag-bs-prefix :action)))))
(defun org-x-dag-bs-epg-outer (tree ancestry) (defun org-x-dag-bs-epg-outer (tree ancestry)
(org-x-dag-bs-with-children-1 (org-x-dag-bs-with-children-1
@ -1075,9 +1079,6 @@ used for optimization."
#'org-x-dag-bs-epg-outer #'org-x-dag-bs-epg-outer
#'org-x-dag-bs-epg-inner)) #'org-x-dag-bs-epg-inner))
(defun org-x-dag-bs-prefix (key nodes)
(--map (org-x-dag-node-fmap it (either<$> it `(,key ,@it))) nodes))
(defun org-x-dag-bs-epg (tree) (defun org-x-dag-bs-epg (tree)
(-let (((n ns) (org-x-dag-bs-epg-outer tree '(:canceled-parent-p nil)))) (-let (((n ns) (org-x-dag-bs-epg-outer tree '(:canceled-parent-p nil))))
(org-x-dag-bs-prefix :endpoint `(,n ,@ns)))) (org-x-dag-bs-prefix :endpoint `(,n ,@ns))))
@ -1946,6 +1947,14 @@ If FORCE is non-nil, sync no matter what."
(-> (org-x-dag-id->node-meta id) (-> (org-x-dag-id->node-meta id)
(plist-get :buffer-status))) (plist-get :buffer-status)))
(defun org-x-dag-id->bs-local (id)
(-> (org-x-dag-id->bs id)
(plist-get :local)))
(defun org-x-dag-id->bs-ancestry (id)
(-> (org-x-dag-id->bs id)
(plist-get :ancestry)))
(defun org-x-dag-id->hl-meta-prop (id prop) (defun org-x-dag-id->hl-meta-prop (id prop)
(-> (org-x-dag-id->hl-meta id) (-> (org-x-dag-id->hl-meta id)
(plist-get prop))) (plist-get prop)))
@ -2630,6 +2639,16 @@ FUTURE-LIMIT in a list."
(org-mode) (org-mode)
(--mapcat ,id-form (org-x-dag-files->ids ,files)))) (--mapcat ,id-form (org-x-dag-files->ids ,files))))
(defmacro org-x-dag-with-unmasked-action-ids (files id-form)
(declare (indent 1))
`(org-x-dag-with-ids files
(pcase (either-from-right (org-x-dag-id->bs it) nil)
(`(:action . ,bs)
(-let (((&plist :local it-local :ancestry a) bs))
(unless (or (plist-get a :canceled-parent-p)
(plist-get a :held-parent-p))
,id-form))))))
(defmacro org-x-dag-with-files (files pre-form form) (defmacro org-x-dag-with-files (files pre-form form)
(declare (indent 2)) (declare (indent 2))
(let* ((lookup-form '(ht-get file->ids it-file)) (let* ((lookup-form '(ht-get file->ids it-file))
@ -2651,10 +2670,9 @@ FUTURE-LIMIT in a list."
;; tasks/projects ;; tasks/projects
;; TODO this includes tasks underneath cancelled headlines
(defun org-x-dag-itemize-tasks (files) (defun org-x-dag-itemize-tasks (files)
(org-x-dag-with-ids files (org-x-dag-with-unmasked-action-ids files
(pcase (either-from-right (org-x-dag-id->bs it) nil) (pcase it-local
(`(:sp-task :task-active ,s) (`(:sp-task :task-active ,s)
(-let (((&plist :sched :dead) s)) (-let (((&plist :sched :dead) s))
(-let (((&plist :committed c) (-when-let (ns (org-x-dag-id->ns it)) (-let (((&plist :committed c) (-when-let (ns (org-x-dag-id->ns it))
@ -2669,8 +2687,8 @@ FUTURE-LIMIT in a list."
(list)))))))))) (list))))))))))
(defun org-x-dag-itemize-projects (files) (defun org-x-dag-itemize-projects (files)
(org-x-dag-with-ids files (org-x-dag-with-unmasked-action-ids files
(pcase (either-from-right (org-x-dag-id->bs it) nil) (pcase it-local
(`(:sp-proj . ,status-data) (`(:sp-proj . ,status-data)
;; NOTE in the future there might be more than just the car to this ;; NOTE in the future there might be more than just the car to this
(let ((status (car status-data))) (let ((status (car status-data)))
@ -2690,8 +2708,8 @@ FUTURE-LIMIT in a list."
(list)))))))))) (list))))))))))
(defun org-x-dag-itemize-iterators (files) (defun org-x-dag-itemize-iterators (files)
(org-x-dag-with-ids files (org-x-dag-with-unmasked-action-ids files
(pcase (either-from-right (org-x-dag-id->bs it) nil) (pcase it-local
(`(:sp-proj . ,status-data) (`(:sp-proj . ,status-data)
(let ((status (car status-data))) (let ((status (car status-data)))
(when (memq status '(:iter-empty :iter-active)) (when (memq status '(:iter-empty :iter-active))
@ -2702,8 +2720,8 @@ FUTURE-LIMIT in a list."
(list))))))))) (list)))))))))
(defun org-x-dag-itemize-incubated (files) (defun org-x-dag-itemize-incubated (files)
(org-x-dag-with-ids files (org-x-dag-with-unmasked-action-ids files
(-when-let (type (pcase (either-from-right (org-x-dag-id->bs it) nil) (-when-let (type (pcase it-local
(`(:sp-proj :proj-complete ,_) nil) (`(:sp-proj :proj-complete ,_) nil)
(`(:sp-task :task-complete ,_) nil) (`(:sp-task :task-complete ,_) nil)
(`(:sp-iter :iter-complete ,_) nil) (`(:sp-iter :iter-complete ,_) nil)
@ -2747,17 +2765,21 @@ FUTURE-LIMIT in a list."
(list))))) (list)))))
(org-x-dag-with-ids files (org-x-dag-with-ids files
(pcase (either-from-right (org-x-dag-id->bs it) nil) (pcase (either-from-right (org-x-dag-id->bs it) nil)
(`(:lifetime :active) (`(:lifetime . ,bs)
(-when-let (ns (org-x-dag-id->ns it)) (-let (((&plist-get :ancestry a :local l) bs))
(-let (((&plist :planned p :fulfilled f) (when (and (not (plist-get a :canceled-parent-p)) (eq l :active))
(either-from-right ns nil))) (-when-let (ns (org-x-dag-id->ns it))
(mk-item it :lifetime p f nil)))) (-let (((&plist :planned p :fulfilled f)
(either-from-right ns nil)))
(mk-item it :lifetime p f nil))))))
;; TODO need to grab deadlines from the network status (when done) ;; TODO need to grab deadlines from the network status (when done)
(`(:endpoint :active) (`(:endpoint . ,bs)
(-when-let (ns (org-x-dag-id->ns it)) (-let (((&plist-get :ancestry a :local l) bs))
(-let (((&plist :planned p :fulfilled f :committed c) (when (and (not (plist-get a :canceled-parent-p)) (eq l :active))
(either-from-right ns nil))) (-when-let (ns (org-x-dag-id->ns it))
(mk-item it :endpoint p f c))))))))) (-let (((&plist :planned p :fulfilled f :committed c)
(either-from-right ns nil)))
(mk-item it :endpoint p f c)))))))))))
(defun org-x-dag-itemize-qtp (files) (defun org-x-dag-itemize-qtp (files)
(let* ((wkp-ids (org-x-dag->current-wkp-ids)) (let* ((wkp-ids (org-x-dag->current-wkp-ids))
@ -2818,8 +2840,8 @@ FUTURE-LIMIT in a list."
(list (org-add-props item nil 'x-goal-id nil)))) (list (org-add-props item nil 'x-goal-id nil))))
(defun org-x-dag-itemize-tasks-with-goals (files) (defun org-x-dag-itemize-tasks-with-goals (files)
(org-x-dag-with-ids files (org-x-dag-with-unmasked-action-ids files
(pcase (either-from-right (org-x-dag-id->bs it) nil) (pcase it-local
(`(:sp-task :task-active ,_) (`(:sp-task :task-active ,_)
(-let ((goal-ids (-when-let (ns (org-x-dag-id->ns it)) (-let ((goal-ids (-when-let (ns (org-x-dag-id->ns it))
(either-from* ns (either-from* ns
@ -2835,8 +2857,8 @@ FUTURE-LIMIT in a list."
(org-x-dag--item-add-goal-ids goal-ids))))))) (org-x-dag--item-add-goal-ids goal-ids)))))))
(defun org-x-dag-itemize-projects-with-goals (files) (defun org-x-dag-itemize-projects-with-goals (files)
(org-x-dag-with-ids files (org-x-dag-with-unmasked-action-ids files
(pcase (either-from-right (org-x-dag-id->bs it) nil) (pcase it-local
(`(:sp-proj . ,s) (`(:sp-proj . ,s)
(unless (eq (car s) :proj-complete) (unless (eq (car s) :proj-complete)
(let ((goal-ids (-when-let (ns (org-x-dag-id->ns it)) (let ((goal-ids (-when-let (ns (org-x-dag-id->ns it))
@ -2849,9 +2871,9 @@ FUTURE-LIMIT in a list."
(org-x-dag--item-add-goal-ids goal-ids)))))))) (org-x-dag--item-add-goal-ids goal-ids))))))))
(defun org-x-dag-itemize-archived (files) (defun org-x-dag-itemize-archived (files)
(org-x-dag-with-ids files (org-x-dag-with-unmasked-action-ids files
(-let (((comptime type) (-let (((comptime type)
(pcase (either-from-right (org-x-dag-id->bs it) nil) (pcase it-local
(`(:sp-proj :proj-complete ,c) `(,c :proj)) (`(:sp-proj :proj-complete ,c) `(,c :proj))
(`(:sp-task :task-complete ,c) `(,c :task)) (`(:sp-task :task-complete ,c) `(,c :task))
(`(:sp-iter :iter-complete ,c) `(,c :iter)) (`(:sp-iter :iter-complete ,c) `(,c :iter))
@ -2937,14 +2959,21 @@ FUTURE-LIMIT in a list."
(add-sched acc id nil)))) (add-sched acc id nil))))
(`(:daily :complete ,_) (`(:daily :complete ,_)
(add-sched acc id t)) (add-sched acc id t))
(`(:sp-task :task-active ,_) (`(:action . ,bs)
(add-dead-sched acc id nil)) (-let (((&plist :ancestry a :local l) bs))
(`(:sp-task :task-complete ,_) (if (or (plist-get a :canceled-parent-p)
(add-dead-sched acc id t)) (plist-get a :held-parent-p))
(`(:sp-subiter :si-active ,_) acc
(add-dead-sched acc id nil)) (pcase l
(`(:sp-subiter :si-complete ,_) (`(:sp-task :task-active ,_)
(add-dead-sched acc id t)) (add-dead-sched acc id nil))
(`(:sp-task :task-complete ,_)
(add-dead-sched acc id t))
(`(:sp-subiter :si-active ,_)
(add-dead-sched acc id nil))
(`(:sp-subiter :si-complete ,_)
(add-dead-sched acc id t))
(_ acc)))))
(_ acc))) (_ acc)))
(get-interval (get-interval
(x) (x)
@ -3951,55 +3980,79 @@ FUTURE-LIMIT in a list."
(format "%s %s on %d-%d-%d at %02d:%02d" verb what y m d H M)))) (format "%s %s on %d-%d-%d at %02d:%02d" verb what y m d H M))))
;; TODO this could show more detail if I wanted ;; TODO this could show more detail if I wanted
(pcase bs-data (pcase bs-data
;; action (`(:action . ,d)
(`(:sp-proj :proj-active ,_) (-let* (((&plist :ancestry a :local l) d)
"Active Project") (local-status
(`(:sp-proj :proj-wait ,_) (pcase l
"Waiting Project") (`(:sp-proj :proj-active)
(`(:sp-proj :proj-hold ,_) "Active Project")
"Held Project") (`(:sp-proj :proj-wait)
(`(:sp-proj :proj-stuck ,_) "Waiting Project")
"Stuck Project") (`(:sp-proj :proj-hold)
(`(:sp-proj :proj-complete ,comptime) "Held Project")
(format-comptime "project" comptime)) (`(:sp-proj :proj-stuck)
(`(:sp-task :task-complete ,comptime) "Stuck Project")
(format-comptime "task" comptime)) (`(:sp-proj :proj-complete ,comptime)
(`(:sp-task :task-active ,_) (format-comptime "project" comptime))
"Active Task") (`(:sp-task :task-complete ,comptime)
(`(:endpoint :active) (format-comptime "task" comptime))
"Active Endpoint Goal") (`(:sp-task :task-active ,_)
(`(:sp-iter :iter-active ,_) "Active Task")
"Active Iterator") (`(:sp-iter :iter-active ,_)
(`(:sp-iter :iter-empty) "Active Iterator")
"Empty Iterator") (`(:sp-iter :iter-empty)
(`(:sp-iter :iter-complete ,comptime) "Empty Iterator")
(format-comptime "iterator" comptime)) (`(:sp-iter :iter-complete ,comptime)
(`(:sp-subiter :si-active ,_) (format-comptime "iterator" comptime))
"Active sub-iterator") (`(:sp-subiter :si-active ,_)
(`(:sp-subiter :si-complete ,comptime) "Active sub-iterator")
(format-comptime "sub-iterator" comptime)) (`(:sp-subiter :si-complete ,comptime)
(format-comptime "sub-iterator" comptime))
(e (error "Unmatched pattern: %s" e))))
((&plist :canceled-parent-p c :held-parent-p h) a)
(ancestry-status (cond
((and c h) "Held/Canceled")
(c "Canceled")
(h "Held")
(t "Unmasked"))))
(list (format "Action status: %s" local-status)
(format "Mask status: %s" ancestry-status))))
(`(:endpoint . ,d)
(-let* (((&plist :ancestry a :local l) d)
(local-status (pcase l
(`(:active)
"Active Endpoint Goal")
(`(:complete ,comptime)
(format-comptime "EPG" comptime))))
(ancestry-status (if (plist-get a :canceled-parent-p)
"Canceled"
"Unmasked")))
(list (format "Goal status: %s" local-status)
(format "Mask status: %s" ancestry-status))))
;; TODO I currently don't allow either of these to be anything other than
;; "TODO"
(`(,(or :lifetime :survival) . ,d)
(-let* (((&plist :ancestry a :local _) d)
(ancestry-status (if (plist-get a :canceled-parent-p))))
(list "Active" (format "Mask Status: %s" ancestry-status))))
;; everything else
(`(:endpoint :complete ,comptime)
(format-comptime "EPG" comptime))
(`(,(or :survival :lifetime) :active)
"Active")
(`(:quarterly :active ,dead) (`(:quarterly :active ,dead)
(->> (if dead (->> (org-ml-to-trimmed-string dead) (->> (if dead (->> (org-ml-to-trimmed-string dead)
(format "deadline: %s")) (format "deadline: %s"))
"no deadline") "no deadline")
(format "Active with %s"))) (format "Active with %s")))
(`(:quarterly :complete ,comptime) (`(:quarterly :complete ,comptime)
(format-comptime "quarterly plan" comptime)) (list (format-comptime "quarterly plan" comptime)))
(`(:weekly :active) (`(:weekly :active)
"Active") "Active")
(`(:weekly :complete ,comptime) (`(:weekly :complete ,comptime)
(format-comptime "weekly plan" comptime)) (list (format-comptime "weekly plan" comptime)))
(`(:daily :active (:sched ,sched)) (`(:daily :active (:sched ,sched))
(-let (((y m d H M) (org-ml-timestamp-get-start-time sched))) (-let (((y m d H M) (org-ml-timestamp-get-start-time sched)))
(format "Open and scheduled on %d-%d-%d at %02d:%02d" y m d H M))) (list (format "Open and scheduled on %d-%d-%d at %02d:%02d" y m d H M))))
(`(:daily :complete ,comptime) (`(:daily :complete ,comptime)
(format-comptime "daily metablock" comptime))))) (list (format-comptime "daily metablock" comptime))))))
(defun org-x-dag--format-title-with-group (id) (defun org-x-dag--format-title-with-group (id)
(let ((title (org-x-dag-id->title id)) (let ((title (org-x-dag-id->title id))
@ -4117,7 +4170,7 @@ FUTURE-LIMIT in a list."
(either-from e (lambda (e) (list (format "Error: %s" e))) right)) (either-from e (lambda (e) (list (format "Error: %s" e))) right))
(format-bs (format-bs
(bs) (bs)
(->> (format-either bs (lambda (b) (list (org-x-dag--format-bs b)))) (->> (format-either bs (lambda (b) (org-x-dag--format-bs b)))
(format-header "Buffer Status"))) (format-header "Buffer Status")))
(format-ns-either (format-ns-either
(id ns-either) (id ns-either)