rewrite project status checking logic

This commit is contained in:
petrucci4prez 2018-04-27 09:58:08 -04:00
parent 316844f512
commit 0ef5fe8dd1
2 changed files with 116 additions and 57 deletions

87
conf.el
View File

@ -230,7 +230,7 @@
(load "ess-site") (load "ess-site")
(setq ess-history-file "session.Rhistory") (setq ess-history-file "session.Rhistory")
(setq ess-history-directory (setq ess-history-directory
(substitute-in-file-name "${XDG_CONFIG_HOME}/r/")) (substitute-in-file-name "${XDG_CONFIG_HOME}/r/"))
(setq org-log-done t) (setq org-log-done t)
(setq org-src-window-setup 'current-window) (setq org-src-window-setup 'current-window)
@ -437,11 +437,8 @@ that in turn are children of todoitems (discontinous project)"
:active :active
:done-incomplete :done-incomplete
:undone-complete :undone-complete
:undone-closed
:done-unclosed
:invalid-todostate :invalid-todostate
:scheduled-project :scheduled-project)
:discontinous)
"list of statuscodes to be used in assessing projects "list of statuscodes to be used in assessing projects
Note they are listed in order of priority (eg items further Note they are listed in order of priority (eg items further
down the list override higher items") down the list override higher items")
@ -512,33 +509,65 @@ down the list override higher items")
(org-forward-heading-same-level 1 t))) (org-forward-heading-same-level 1 t)))
project-state)) project-state))
(defmacro nd/is-project-keyword-status-p (top-keyword operator statuscode)
"tests if a project has toplevel heading of top-keyword and
child status equal to status code and returns keyword if
both are true"
`(if (and (equal ,keyword ,top-keyword)
(nd/compare-statuscodes ,operator (nd/descend-into-project) statuscode))
,keyword))
(defun nd/is-project-status-p (statuscode) (defun nd/is-project-status-p (statuscode)
(let ((keyword (nd/is-project-p))) (let ((keyword (nd/is-project-p)))
(if keyword (if keyword
(cond ((member keyword nd/project-invalid-todostates) (case statuscode
(if (nd/status= statuscode :invalid-todostate) keyword)) ;; projects closed more than 30 days ago
((equal keyword "HOLD") (if (nd/status= statuscode :held) keyword)) ;; note CANCELLED overrides all subtasks/projects
((equal keyword "CANCELLED") (if (nd/is-archivable-heading-p) (:archivable
(if (nd/status= statuscode :archivable) keyword) (if (nd/is-archivable-heading-p)
(if (nd/status= statuscode :complete) keyword))) (cond ((equal keyword "CANCELLED") keyword)
(t (let ((child-statuscode (nd/descend-into-project))) (t (nd/is-project-keyword-status-p "DONE" = :archivable)))))
(cond ((equal keyword "DONE")
(if (nd/is-archivable-heading-p) ;; projects closed less than 30 days ago
;; TODO make my statuscode condition checker handle multiples ;; note CANCELLED overrides all subtasks/projects
(if (and (nd/status= statuscode :archivable) (:complete
(nd/status= child-statuscode :archivable)) (if (not (nd/is-archivable-heading-p))
keyword) (cond ((equal keyword "CANCELLED") keyword)
(if (and (nd/status= statuscode :complete) (t (nd/is-project-keyword-status-p "DONE" = :complete)))))
(nd/status= child-statuscode :complete))
keyword ;; projects with no waiting, held, or active components
(if (and (nd/status> child-statuscode :complete) (:stuck
(nd/status= statuscode :done-incomplete)) (nd/is-project-keyword-status-p "TODO" = :stuck))
keyword))))
((equal keyword "TODO") ;; held projects
(if (nd/status> child-statuscode :complete) ;; note toplevel HOLD overrides all subtasks/projects
(if (nd/status= statuscode child-statuscode) keyword) (:held
(if (nd/status= statuscode :undone-complete) keyword))) (cond ((equal keyword "HOLD") keyword)
(t (if (nd/status= statuscode child-statuscode) keyword))))))))) (t (nd/is-project-keyword-status-p "TODO" = :stuck))))
;; projects with at least one waiting component
(:waiting
(nd/is-project-keyword-status-p "TODO" = :waiting))
;; projects with at least one active component
(:active
(nd/is-project-keyword-status-p "TODO" = :active))
;; projects marked DONE but still have undone subtasks
(:done-incomplete
(nd/is-project-keyword-status-p "DONE" > :complete))
;; projects not marked DONE but all subtasks are done
(:undone-complete
(nd/is-project-keyword-status-p "TODO" < :stuck))
;; projects with invalid todo keywords
(:invalid-todostate
(if (member keyword nd/project-invalid-todostates) keyword))
;; projects with scheduled heading (only subtasks should be scheduled)
(:scheduled-project
(if (nd/is-scheduled-heading-p) keyword))))))
;; TODO we could clean this up with macros ;; TODO we could clean this up with macros
(defun nd/skip-non-atomic-tasks () (defun nd/skip-non-atomic-tasks ()

View File

@ -605,11 +605,8 @@ These are the building blocks for skip functions.
:active :active
:done-incomplete :done-incomplete
:undone-complete :undone-complete
:undone-closed
:done-unclosed
:invalid-todostate :invalid-todostate
:scheduled-project :scheduled-project)
:discontinous)
"list of statuscodes to be used in assessing projects "list of statuscodes to be used in assessing projects
Note they are listed in order of priority (eg items further Note they are listed in order of priority (eg items further
down the list override higher items") down the list override higher items")
@ -680,33 +677,66 @@ These are the building blocks for skip functions.
(org-forward-heading-same-level 1 t))) (org-forward-heading-same-level 1 t)))
project-state)) project-state))
(defmacro nd/is-project-keyword-status-p (top-keyword operator statuscode)
"tests if a project has toplevel heading of top-keyword and
child status equal to status code and returns keyword if
both are true"
`(if (and (equal ,keyword ,top-keyword)
(nd/compare-statuscodes ,operator (nd/descend-into-project) statuscode))
,keyword))
(defun nd/is-project-status-p (statuscode) (defun nd/is-project-status-p (statuscode)
(let ((keyword (nd/is-project-p))) (let ((keyword (nd/is-project-p)))
(if keyword (if keyword
(cond ((member keyword nd/project-invalid-todostates) (case statuscode
(if (nd/status= statuscode :invalid-todostate) keyword)) ;; projects closed more than 30 days ago
((equal keyword "HOLD") (if (nd/status= statuscode :held) keyword)) ;; note CANCELLED overrides all subtasks/projects
((equal keyword "CANCELLED") (if (nd/is-archivable-heading-p) (:archivable
(if (nd/status= statuscode :archivable) keyword) (if (nd/is-archivable-heading-p)
(if (nd/status= statuscode :complete) keyword))) (cond ((equal keyword "CANCELLED") keyword)
(t (let ((child-statuscode (nd/descend-into-project))) (t (nd/is-project-keyword-status-p "DONE" = :archivable)))))
(cond ((equal keyword "DONE")
(if (nd/is-archivable-heading-p) ;; projects closed less than 30 days ago
;; TODO make my statuscode condition checker handle multiples ;; note CANCELLED overrides all subtasks/projects
(if (and (nd/status= statuscode :archivable) (:complete
(nd/status= child-statuscode :archivable)) (if (not (nd/is-archivable-heading-p))
keyword) (cond ((equal keyword "CANCELLED") keyword)
(if (and (nd/status= statuscode :complete) (t (nd/is-project-keyword-status-p "DONE" = :complete)))))
(nd/status= child-statuscode :complete))
keyword ;; projects with no waiting, held, or active components
(if (and (nd/status> child-statuscode :complete) (:stuck
(nd/status= statuscode :done-incomplete)) (nd/is-project-keyword-status-p "TODO" = :stuck))
keyword))))
((equal keyword "TODO") ;; held projects
(if (nd/status> child-statuscode :complete) ;; note toplevel HOLD overrides all subtasks/projects
(if (nd/status= statuscode child-statuscode) keyword) (:held
(if (nd/status= statuscode :undone-complete) keyword))) (cond ((equal keyword "HOLD") keyword)
(t (if (nd/status= statuscode child-statuscode) keyword))))))))) (t (nd/is-project-keyword-status-p "TODO" = :stuck))))
;; projects with at least one waiting component
(:waiting
(nd/is-project-keyword-status-p "TODO" = :waiting))
;; projects with at least one active component
(:active
(nd/is-project-keyword-status-p "TODO" = :active))
;; projects marked DONE but still have undone subtasks
(:done-incomplete
(nd/is-project-keyword-status-p "DONE" > :complete))
;; projects not marked DONE but all subtasks are done
(:undone-complete
(nd/is-project-keyword-status-p "TODO" < :stuck))
;; projects with invalid todo keywords
(:invalid-todostate
(if (member keyword nd/project-invalid-todostates) keyword))
;; projects with scheduled heading (only subtasks should be scheduled)
(:scheduled-project
(if (nd/is-scheduled-heading-p) keyword))))))
#+END_SRC #+END_SRC
*** skip functions *** skip functions
These are the primary means we use to sort through tasks. Note that we could do this with These are the primary means we use to sort through tasks. Note that we could do this with