Compare commits

..

No commits in common. "master" and "propagate_scheduled" have entirely different histories.

27 changed files with 1361 additions and 2099 deletions

6
.gitignore vendored
View File

@ -2,9 +2,7 @@
!.gitignore !.gitignore
!README.org !README.org
!init.el !init.el
!straight-boot.el !install_deps
!runtime_pkgs
!bin
# track versions of installed packages # track versions of installed packages
!straight !straight
@ -25,4 +23,4 @@ local/*
!.github !.github
*.elc *.elc

View File

@ -1,21 +0,0 @@
#!/bin/sh
### Add org file changes to git repo
for REPO in $1
do
echo "repository: $REPO"
eval "cd $REPO"
# check for errors
if ! git fsck --strict > /dev/null 2>&1; then
notify-send "Org git commit failed."
fi
# remove deleted files
git ls-files --deleted -z | xargs -0 git rm >/dev/null 2>&1
# add new files
git add . >/dev/null 2>&1
git commit -m "$(date)"
# push
git push origin master
done
echo Done

View File

@ -1,5 +0,0 @@
#! /bin/bash
# start the emacs daemon
emacs --fg-daemon > /dev/null 2>&1

View File

@ -1,5 +0,0 @@
#! /bin/bash
# stop the emacs daemon
emacsclient --eval "(kill-emacs)"

View File

@ -1,76 +0,0 @@
#!/bin/bash
state=/tmp/emacs-use-dark-mode
start_daemon () {
emacs --fg-daemon > /dev/null 2>&1
}
stop_daemon () {
emacsclient --eval "(kill-emacs)" 2> /dev/null
}
kill_daemon () {
killall emacsclient 2> /dev/null
killall emacs 2> /dev/null
}
restart_daemon () {
stop_daemon
start_daemon
}
hard_restart_daemon () {
kill_daemon
start_daemon
}
set_light () {
echo 0 > "$state"
}
set_dark () {
echo 1 > "$state"
}
if [[ -z "$1" ]]; then
echo "Need a command to perform"
exit 1
elif [[ "$1" == "start" ]]; then
start_daemon &
elif [[ "$1" == "stop" ]]; then
stop_daemon
elif [[ "$1" == "kill" ]]; then
kill_daemon
elif [[ "$1" == "restart" ]]; then
restart_daemon &
elif [[ "$1" == "hard_restart" ]]; then
hard_restart_daemon &
elif [[ "$1" == "theme" ]]; then
if [[ "$2" == "toggle" ]]; then
# if no state file assume light theme
if [[ ! -f "$state" ]]; then
set_light
elif [[ "$(cat $state)" == 0 ]]; then
set_dark
else
set_light
fi
elif [[ "$2" == "light" ]]; then
set_light
elif [[ "$2" == "dark" ]]; then
set_dark
else
echo 'Invlalid theme command'
exit 1
fi
if [ "$3" == "restart" ]; then
restart_daemon &
elif [ "$3" == "hard_restart" ]; then
hard_restart_daemon &
fi
else
echo 'Invalid command'
exit 1
fi

View File

@ -1,10 +0,0 @@
#! /bin/sh
rcpath=$XDG_CONFIG_HOME/emacs/local/lib/mu4e/mbsyncrc
if [ ! -f $rcpath ]; then
echo "mbsyncrc does not exist"
exit 1
fi
/usr/bin/mbsync -c "$rcpath" "$@"

View File

@ -1,12 +0,0 @@
#! /bin/sh
## indexes mu depending on whether emacs mu4e is running
## assume the mu server is only started by mu4e
if pgrep -fx '/usr/bin/mu server' > /dev/null; then
echo indexing mu through emacs
emacsclient -e '(mu4e-update-index)' > /dev/null
else
echo indexing mu natively
mu index
fi

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 31 KiB

38
init.el
View File

@ -1,6 +1,42 @@
;;;; init the straight package manager ;;;; init the straight package manager
(load-file (expand-file-name "straight-boot.el" user-emacs-directory)) ;; disable automatic package updates
(setq straight-check-for-modifications nil)
;; watch for repo modifications if we have python3 and watchexec
;; otherwise just use a save hook
;; (setq straight-check-for-modifications
;; (if (and (executable-find "python3")
;; (executable-find "watchexec"))
;; '(watch-files find-when-checking)
;; '(check-on-save find-when-checking)))
;; add pinned packages to straight
;; (setq straight-profiles
;; '((nil . "default.el")
;; ;; Packages which are pinned to a specific commit.
;; (pinned . "pinned.el")))
;; bootstrap straight
(defvar bootstrap-version)
(let ((bootstrap-file
(expand-file-name "straight/repos/straight.el/bootstrap.el" user-emacs-directory))
(bootstrap-version 5))
(unless (file-exists-p bootstrap-file)
(with-current-buffer
(url-retrieve-synchronously
"https://raw.githubusercontent.com/raxod502/straight.el/develop/install.el"
'silent 'inhibit-cookies)
(goto-char (point-max))
(eval-print-last-sexp)))
(load bootstrap-file nil 'nomessage))
;; load experimental straight functions for pinning
;; (autoload #'straight-x-pull-all "straight-x")
;; (autoload #'straight-x-freeze-versions "straight-x")
;; install use-package itself
(straight-use-package 'use-package)
;; configure all config paths before anything else is loaded ;; configure all config paths before anything else is loaded
(use-package no-littering :straight t) (use-package no-littering :straight t)

18
install_deps Executable file
View File

@ -0,0 +1,18 @@
#!/bin/bash
## Install all dependencies for emacs to run at full capacity
if emacs -batch -l "init.el"; then
IFS=' ' read -r -a emacs_pkgs \
< <(emacs -batch -l "init.el" --eval \
'(print (format "pkgs: %s" (s-join " " (nd/get-dependencies (list :pacman :aur)))))' \
2>/dev/null | \
sed -n -e 's/"pkgs: \(.*\)"/\1/p')
echo "Emacs requires the following system pkgs: ${emacs_pkgs[*]}"
else
echo "Could not get list of emacs dependencies."
emacs_pkgs=()
fi
MAKEFLAGS="-j$(nproc)" \
yay --needed --noconfirm --norebuild --removemake -S "${emacs_pkgs[@]}"

View File

@ -1 +0,0 @@
mu4e

View File

@ -36,20 +36,16 @@ left/right slot."
;; monad-y things ;; monad-y things
(defmacro either-as>>= (sym either form) (defmacro either>>= (either form)
"Bind EITHER to FORM where the right slot is bound to SYM." "Bind EITHER to FORM where the right slot is bound to 'it'."
(declare (indent 2)) (declare (indent 1))
(let ((e (make-symbol "--either"))) (let ((e (make-symbol "--either")))
`(let ((,e ,either)) `(let ((,e ,either))
(pcase ,e (pcase ,e
(`(:left ,_) ,e) (`(:left ,_) ,e)
(`(:right ,,sym) ,form) (`(:right ,it) ,form)
(e (error "Learn to use monads, dummy; this isn't one: %s" e)))))) (e (error "Learn to use monads, dummy; this isn't one: %s" e))))))
(defmacro either>>= (either form)
"Bind EITHER to FORM where the right slot is bound to 'it'."
`(either-as>>= it ,either ,form))
(defun either-foldM (fun init xs) (defun either-foldM (fun init xs)
"Mondically apply FUN to XS (a list). "Mondically apply FUN to XS (a list).

View File

@ -88,22 +88,14 @@
;; datetime operations ;; datetime operations
(defun org-x-dag-datetimes-same-length-p (datetime0 datetime1) (defmacro org-x-dag-with-times (datetime0 datetime1 form)
;; ASSUME all digits in this comparison are on the calendar/clock (eg day 32 ;; ASSUME all digits in this comparison are on the calendar/clock (eg day 32
;; does not 'rollover' to day 1 on the next month) ;; does not 'rollover' to day 1 on the next month)
(not (xor (org-ml-time-is-long datetime0) (org-ml-time-is-long datetime1))))
;; TODO some of this is redundant because I'm checking the length twice
;; Maybe a -> Maybe a -> (a -> a -> b) -> b -> Maybe b
(defun org-x-dag-with-datetimes (a b fun alt)
(when (and a b)
(if (org-x-dag-datetimes-same-length-p a b)
(funcall fun a b)
(funcall alt))))
(defmacro org-x-dag-with-times (datetime0 datetime1 form)
(declare (indent 2)) (declare (indent 2))
`(if (org-x-dag-datetimes-same-length-p datetime0 datetime1) `(if (or (and (org-ml-time-is-long ,datetime0)
(org-ml-time-is-long ,datetime1))
(not (or (org-ml-time-is-long ,datetime0)
(org-ml-time-is-long ,datetime1))))
,form ,form
(error "Datetimes are invalid lengths: %S and %S" ,datetime0 ,datetime1))) (error "Datetimes are invalid lengths: %S and %S" ,datetime0 ,datetime1)))
@ -134,12 +126,6 @@
(--drop-while (= (car it) (cdr it))) (--drop-while (= (car it) (cdr it)))
(not)))) (not))))
(defun org-x-dag-datetime-compare (a b)
(cond
((org-x-dag-datetime= a b) 'eq)
((org-x-dag-datetime< a b) 'gt)
(t 'lt)))
(defun org-x-dag-date< (datetime0 datetime1) (defun org-x-dag-date< (datetime0 datetime1)
(org-x-dag-datetime< (org-x-dag-datetime-to-date datetime0) (org-x-dag-datetime< (org-x-dag-datetime-to-date datetime0)
(org-x-dag-datetime-to-date datetime1))) (org-x-dag-datetime-to-date datetime1)))
@ -155,12 +141,6 @@
(org-x-dag-datetime= (org-x-dag-datetime-to-date datetime0) (org-x-dag-datetime= (org-x-dag-datetime-to-date datetime0)
(org-x-dag-datetime-to-date datetime1))) (org-x-dag-datetime-to-date datetime1)))
(defun org-x-dag-datetime-max (datetimes)
(-max-by #'org-x-dag-datetime> datetimes))
(defun org-x-dag-date-max (datetimes)
(-max-by #'org-x-dag-date< datetimes))
(defun org-x-dag-datetime-shift (datetime shift unit) (defun org-x-dag-datetime-shift (datetime shift unit)
(cl-flet* (cl-flet*
((enc-dec-long ((enc-dec-long
@ -193,10 +173,6 @@
;; date <-> epoch ;; date <-> epoch
(defun org-x-dag-datetime-to-epoch (date)
(-let (((y m d H M) date))
(float-time (encode-time (list 0 (or M 0) (or H 0) d m y nil -1 nil)))))
(defun org-x-dag-date-to-epoch (date) (defun org-x-dag-date-to-epoch (date)
(float-time (encode-time `(0 0 0 ,@(reverse date) nil -1 nil)))) (float-time (encode-time `(0 0 0 ,@(reverse date) nil -1 nil))))
@ -399,40 +375,6 @@ relative shift in days from ABS."
;; (org-x-dag-format-month-tag m) ;; (org-x-dag-format-month-tag m)
;; (org-x-dag-format-day-tag d)))) ;; (org-x-dag-format-day-tag d))))
;; timestamps <-> datetime
(defun org-x-dag-partition-timestamp (ts)
(list :datetime (org-ml-timestamp-get-start-time ts)
:length (org-ml-timestamp-get-range ts)
:pos (org-ml-get-property :begin ts)
:repeater (org-ml-timestamp-extract-modulus 'repeater ts)
:warning (org-ml-timestamp-extract-modulus 'warning ts)))
(defun org-x--dag-pts-compare (fun a b)
(funcall (-on fun (lambda (ts) (plist-get ts :datetime))) a b))
(defun org-x-dag-pts-compare (a b)
(org-x--dag-pts-compare #'org-x-dag-datetime-compare a b))
(defun org-x-dag-pts= (a b)
(org-x--dag-pts-compare #'org-x-dag-datetime= a b))
(defun org-x-dag-pts< (a b)
(org-x--dag-pts-compare #'org-x-dag-datetime< a b))
(defun org-x-dag-pts> (a b)
(org-x--dag-pts-compare #'org-x-dag-datetime> a b))
(defun org-x-dag-pts-max (ps)
(-max-by #'org-x-dag-pts> ps))
(defun org-x-dag-pts-is-long-p (pts)
(org-ml-time-is-long (plist-get pts :datetime)))
(defun org-x-dag-pts-to-epoch (pts)
(->> (plist-get pts :datetime)
(org-x-dag-datetime-to-epoch)))
;; allocation ;; allocation
(pcase-defmacro regexp (capture regexp) (pcase-defmacro regexp (capture regexp)
@ -648,10 +590,10 @@ used for optimization."
;; its parent is a node or none of its parents are nodes ;; its parent is a node or none of its parents are nodes
(cond (cond
((and this-todo ((and this-todo
(when (setq this-pblock (org-x-dag-property-block next-pos)) (setq this-pblock (org-x-dag-property-block next-pos)
(setq pbeg (nth 1 this-pblock) pbeg (nth 1 this-pblock)
pend (nth 2 this-pblock) pend (nth 2 this-pblock)
this-id (org-x-dag-get-local-property pbeg pend id-prop)))) this-id (org-x-dag-get-local-property pbeg pend id-prop)))
(setq bury-level nil (setq bury-level nil
this-buffer-parent (nth 2 (car node-stack)) this-buffer-parent (nth 2 (car node-stack))
this-links (or (org-x-dag-get-parent-links (nth 3 this-pblock) this-links (or (org-x-dag-get-parent-links (nth 3 this-pblock)
@ -740,7 +682,7 @@ used for optimization."
(`(:right ,r) (`(:right ,r)
(-let (((cur as) acc)) (-let (((cur as) acc))
(either>>= (funcall rank-fun cur r) (either>>= (funcall rank-fun cur r)
(let ((as* (append (funcall acc-fun r) as))) (let ((as* (append (funcall acc-fun it) as)))
(if (not it) (fold-rank `(,cur ,as*) rest) (if (not it) (fold-rank `(,cur ,as*) rest)
(if (funcall stop-fun r) (if (funcall stop-fun r)
;; if we encounter the stop condition, apply the ;; if we encounter the stop condition, apply the
@ -757,8 +699,8 @@ used for optimization."
(pcase (car bss) (pcase (car bss)
(`(:right ,r) (`(:right ,r)
(if (funcall stop-fun r) (if (funcall stop-fun r)
(->> (either-rights bss) (->> (funcall acc-fun r)
(--mapcat (funcall acc-fun it)) (list)
(funcall trans-fun r)) (funcall trans-fun r))
(either>>= (fold-rank (list r nil) (cdr bss)) (either>>= (fold-rank (list r nil) (cdr bss))
(-let (((cur as) it)) (-let (((cur as) it))
@ -767,15 +709,12 @@ used for optimization."
(defun org-x-dag-bs-action-rankfold-children (bss default rank-fun stop-fun (defun org-x-dag-bs-action-rankfold-children (bss default rank-fun stop-fun
acc-fun trans-fun) acc-fun trans-fun)
(declare (indent 2)) (cl-flet ((get-local (x) (plist-get x :local)))
(cl-flet (declare (indent 2))
((get-local
(x)
(plist-get x :local)))
(org-x-dag-bs-rankfold-children bss default (org-x-dag-bs-rankfold-children bss default
(-on rank-fun #'get-local) (-on rank-fun #'get-local)
(-compose stop-fun #'get-local) (-compose stop-fun #'get-local)
(-compose acc-fun #'get-local) acc-fun
(lambda (x as) (lambda (x as)
(funcall trans-fun (get-local x) as))))) (funcall trans-fun (get-local x) as)))))
@ -856,7 +795,7 @@ deadline (eg via epoch time) or if it has a repeater."
(< parent-epoch this-epoch)))))) (< parent-epoch this-epoch))))))
(defun org-x-dag-bs-action-project-inner (node-data ancestry child-bss) (defun org-x-dag-bs-action-project-inner (node-data ancestry child-bss)
(cl-flet* (cl-flet
((new-proj ((new-proj
(status) (status)
(either :right `(:sp-proj ,status))) (either :right `(:sp-proj ,status)))
@ -866,39 +805,41 @@ deadline (eg via epoch time) or if it has a repeater."
(is-next (is-next
(task-data) (task-data)
(-let (((&plist :todo :sched) task-data)) (-let (((&plist :todo :sched) task-data))
(or sched (equal todo org-x-kw-next)))) (or sched (equal todo org-x-kw-next)))))
(check-sched ;; rankings
(planning) ;; *-active > proj-wait > proj-held > (proj-stuck == iter-empty) > *-complete
(if-let (sched (-some->> planning (org-ml-get-property :scheduled))) (org-x-dag-bs-action-with-closed node-data ancestry "projects"
(if child-bss (either :left "Projects cannot be scheduled") (if child-bss
(let ((sp (org-x-dag-partition-timestamp sched))) `(:sp-proj :proj-complete ,it-comptime)
(if (< 0 (plist-get sp :length)) `(:sp-task :task-complete ,it-comptime))
(->> "Tasks cannot have ranged scheduled timestamps"
(either :left)) (org-x-dag-bs-action-check-children child-bss
(either :right sp)))) (either :left "Completed projects cannot have active children")
(either :right nil))) (either :right `(:sp-proj :proj-complete ,it-comptime))
(check-dead `(:sp-task :task-complete ,it-comptime)
(planning) (lambda (local)
(if-let (dead (-some->> planning (org-ml-get-property :deadline))) (pcase local
(let ((dp (org-x-dag-partition-timestamp dead))) (`(:sp-proj :proj-complete ,_) t)
(cond (`(:sp-iter :iter-complete ,_) t)
((< 0 (plist-get dp :length)) (`(:sp-task :task-complete ,_) t)
(either :left "Actions cannot have ranged deadlines")) (_ nil))))
((and child-bss (plist-get dp :repeater))
(either :left "Projects cannot have repeated deadlines")) (-let* (((sched dead) (-some->> it-planning
((org-x-dag-action-dead-after-parent-p ancestry dead) (org-ml-get-properties '(:scheduled :deadline))))
(either :left "Action deadline cannot end after parent deadline")) (task-default (->> (list :todo it-todo
(t :sched sched
(either :right dp)))) :dead dead)
(either :right nil))) (list :sp-task :task-active))))
(check-todo
(todo task-default)
(cond (cond
((and child-bss (equal it-todo org-x-kw-hold))
(new-proj :proj-held))
((and child-bss sched)
(either :left "Projects cannot be scheduled"))
((and child-bss (plist-get node-data :effort)) ((and child-bss (plist-get node-data :effort))
(either :left "Projects cannot have effort")) (either :left "Projects cannot have effort"))
((and child-bss (equal todo org-x-kw-hold)) ((org-x-dag-action-dead-after-parent-p ancestry dead)
(new-proj :proj-held)) (either :left "Action deadline cannot end after parent deadline"))
((equal todo org-x-kw-todo) ((equal it-todo org-x-kw-todo)
(org-x-dag-bs-action-rankfold-children child-bss task-default (org-x-dag-bs-action-rankfold-children child-bss task-default
(lambda (acc next) (lambda (acc next)
(->> (pcase `(,acc ,next) (->> (pcase `(,acc ,next)
@ -942,8 +883,8 @@ deadline (eg via epoch time) or if it has a repeater."
(`(,_ (:sp-task :task-active ,_)) t) (`(,_ (:sp-task :task-active ,_)) t)
;; any pair that makes it this far is completed in both, ;; any pair that makes it this far is completed in both,
;; which means neither takes precedence, which means ;; which means neither takes precedence, which means choose
;; choose the left one ;; the left one
(`(,_ ,_) nil)) (`(,_ ,_) nil))
(either :right))) (either :right)))
@ -957,7 +898,7 @@ deadline (eg via epoch time) or if it has a repeater."
(lambda (next) (lambda (next)
(pcase next (pcase next
(`(:sp-iter :iter-active ,d) (plist-get d :child-scheds)) (`(:sp-iter :iter-active ,d) (plist-get d :child-scheds))
(`(:sp-task :task-active ,d) (-some-> (plist-get d :sched) (list))) (`(:sp-task :task-active ,d) (list (plist-get d :sched)))
(`(:sp-proj :proj-active ,d) (plist-get d :child-scheds)) (`(:sp-proj :proj-active ,d) (plist-get d :child-scheds))
(_ nil))) (_ nil)))
@ -967,7 +908,7 @@ deadline (eg via epoch time) or if it has a repeater."
`(:sp-task :task-complete ,_) `(:sp-task :task-complete ,_)
`(:sp-iter :iter-complete ,_)) `(:sp-iter :iter-complete ,_))
(->> "Active projects must have at least one active child" (->> "Active projects must have at least one active child"
(either :left))) (either :left )))
(`(:sp-proj :proj-active ,_) (new-active-proj cs)) (`(:sp-proj :proj-active ,_) (new-active-proj cs))
(`(:sp-proj ,s) (new-proj s)) (`(:sp-proj ,s) (new-proj s))
(`(:sp-iter :iter-active ,_) (new-active-proj cs)) (`(:sp-iter :iter-active ,_) (new-active-proj cs))
@ -983,36 +924,9 @@ deadline (eg via epoch time) or if it has a repeater."
(t (org-x-dag-bs-error-kw "Task action" o))))) (t (org-x-dag-bs-error-kw "Task action" o)))))
(e (error "Pattern fail: %s" e)))))) (e (error "Pattern fail: %s" e))))))
(child-bss (child-bss
(org-x-dag-bs-error-kw "Project action" todo)) (org-x-dag-bs-error-kw "Project action" it-todo))
(t (t
(either :right task-default))))) (either :right task-default)))))))
;; rankings
;; *-active > proj-wait > proj-held > (proj-stuck == iter-empty) > *-complete
(org-x-dag-bs-action-with-closed node-data ancestry "projects"
(if child-bss
`(:sp-proj :proj-complete ,it-comptime)
`(:sp-task :task-complete ,it-comptime))
(org-x-dag-bs-action-check-children child-bss
(either :left "Completed projects cannot have active children")
(either :right `(:sp-proj :proj-complete ,it-comptime))
`(:sp-task :task-complete ,it-comptime)
(lambda (local)
(pcase local
(`(:sp-proj :proj-complete ,_) t)
(`(:sp-iter :iter-complete ,_) t)
(`(:sp-task :task-complete ,_) t)
(_ nil))))
(either-as>>= sp (check-sched it-planning)
(either-as>>= dp (check-dead it-planning)
;; TODO it seems a bit odd that the only reason I need sp and dp here
;; is to seed the sub-project task form; idk why this is weird but it
;; smells like something could be optimized somewhere
(->> (list :todo it-todo :sched sp :dead dp)
(list :sp-task :task-active)
(check-todo it-todo)))))))
(defun org-x-dag-node-data-is-iterator-p (node-data) (defun org-x-dag-node-data-is-iterator-p (node-data)
(-let (((&plist :props) node-data)) (-let (((&plist :props) node-data))
@ -1032,171 +946,136 @@ deadline (eg via epoch time) or if it has a repeater."
((or `(:si-task :task-complete ,_) `(:si-proj :proj-complete ,_)) t) ((or `(:si-task :task-complete ,_) `(:si-proj :proj-complete ,_)) t)
(_ nil))))) (_ nil)))))
(defun org-x-dag-bs-action-subiter-todo-fold (defun org-x-dag-bs-action-subiter-todo-fold (child-bss default trans-fun)
(child-bss default complete-default new-active-fun)
(declare (indent 2)) (declare (indent 2))
(cl-flet* (org-x-dag-bs-action-rankfold-children child-bss default
((fmt-left (lambda (acc next)
(sched? wrong) (pcase `(,acc ,next)
(let ((what (if sched? "scheduled" "deadlined"))) ;; for active tasks, the furthest in the future is ranked the highest
(org-x-dag-left "Sub-iter %s timestamps %s" what wrong))) (`((:si-task :task-active ,a) (:si-task :task-active ,b))
(fmt-left-both (-let (((&plist :sched as :dead ad) a)
(wrong) ((&plist :sched bs :dead bd) b))
(org-x-dag-left "Sub-iter scheduled/deadlined timestamps %s" wrong)) (cond
(fmt-left-2 ((or (xor as bs) (xor ad bd))
(sched-wrong dead-wrong) (->> "All sub-iters must have the same planning configuration"
(org-x-dag-left (either :left)))
"Sub-iter scheduled timestamps %s and deadlined timestamps %s" ((and as bs (xor (org-ml-time-is-long as) (org-ml-time-is-long bs)))
sched-wrong dead-wrong)) (->> "Sub-iters must have scheduled timestamp with same length"
(compare (either :left)))
(a b) ((and ad bd (xor (org-ml-time-is-long ad) (org-ml-time-is-long bd)))
(cond (->> "Sub-iters must have deadline timestamp with same length"
((not (or a b)) (either :left nil)) (either :left)))
((xor a b) (either :left 'presence)) ;; ASSUME this won't fail since the datetimes are assumed to be the
(t ;; same length as per rules above
(org-x-dag-with-datetimes ((and ad bd)
a b (->> (org-x-dag-datetime< (org-ml-timestamp-get-start-time ad)
(lambda (a b) (org-ml-timestamp-get-start-time bd))
(either :right (org-x-dag-pts-compare a b))) (either :right)))
(-const (either :left 'length)))))) (t
(comp2right (->> (org-x-dag-datetime< (org-ml-timestamp-get-start-time as)
(sched? comp) (org-ml-timestamp-get-start-time bs))
(if (eq comp 'eq) (fmt-left sched? "should be different") (either :right))))))
(either :right (eq comp 'gt)))) ((or `((:si-task . ,_) (:si-proj . ,_))
(left2err `((:si-proj . ,_) (:si-task . ,_)))
(sym) (either :left "Sub-iterators must have same project structure"))
(pcase sym (`(,(or `(:si-task :task-active ,_) `(:si-proj :proj-active ,_)) ,_)
(`presence "should be on all or none") (either :right nil))
(`length "must have same length"))) (`(,_ ,(or `(:si-task :task-active ,_) `(:si-proj :proj-active ,_)))
(sym-left (either :right t))
(sched? sym) (`(,_ ,_) (either :right nil))))
(fmt-left sched? (left2err sym))) (lambda (next)
(sym-left-2 (pcase next
(sched-sym dead-sym) ((or `(:si-task :task-active ,_) `(:si-proj :proj-active ,_)) t)
(if (eq sched-sym dead-sym) (fmt-left-both (left2err sched-sym)) (_ nil)))
(fmt-left-2 (left2err sched-sym) (left2err dead-sym)))) (lambda (next)
(new-active (pcase next
(ts-data child-scheds) (`(:si-proj :proj-active ,d) (plist-get d :child-scheds))
(->> (list :dead (plist-get ts-data :dead) (`(:si-task :task-active ,d) (list (plist-get d :sched)))
:child-scheds child-scheds (_ nil)))
;; TODO this can be an epoch and not a datetime trans-fun))
:leading-sched-dt (-> (org-x-dag-pts-max child-scheds)
(plist-get :datetime)))
(funcall new-active-fun))))
(org-x-dag-bs-action-rankfold-children child-bss default
(lambda (acc next)
(pcase `(,acc ,next)
;; for active tasks, the furthest in the future is ranked the highest
(`((:si-task :task-active ,a) (:si-task :task-active ,b))
(-let (((&plist :sched as :dead ad) a)
((&plist :sched bs :dead bd) b))
(pcase `(,(compare as bs) ,(compare ad bd))
(`((:left ,s) (:right ,d)) (if s (sym-left t s) (comp2right nil d)))
(`((:right ,s) (:left ,d)) (if d (sym-left nil d) (comp2right t s)))
(`((:right ,s) (:right ,d))
(pcase `(,s ,d)
(`(gt gt) (either :right t))
(`(lt lt) (either :right nil))
((or `(gt lt) `(lt gt)) (fmt-left-both "should not cross"))
(`(eq eq) (fmt-left-both "should be different"))
(`(eq ,_) (fmt-left t "should be different"))
(`(,_ eq) (fmt-left nil "should be different"))))
(`((:left ,s) (:left ,d))
(cond
((and s d) (sym-left-2 s d))
(s (sym-left t s))
(d (sym-left nil d)))))))
((or `((:si-task . ,_) (:si-proj . ,_))
`((:si-proj . ,_) (:si-task . ,_)))
(either :left "Sub-iterators must have same project structure"))
(`(,(or `(:si-task :task-active ,_) `(:si-proj :proj-active ,_)) ,_)
(either :right nil))
(`(,_ ,(or `(:si-task :task-active ,_) `(:si-proj :proj-active ,_)))
(either :right t))
(`(,_ ,_) (either :right nil))))
(lambda (next)
(pcase next
((or `(:si-task :task-active ,_) `(:si-proj :proj-active ,_)) t)
(_ nil)))
(lambda (next)
(pcase next
(`(:si-proj :proj-active ,d) (plist-get d :child-scheds))
(`(:si-task :task-active ,d) (-some-> (plist-get d :sched) (list)))
(_ nil)))
(lambda (acc cs)
(pcase acc
((or `(:si-task :task-complete ,_) `(:si-proj :proj-complete ,_))
complete-default)
(`(:si-proj :proj-active ,ts-data)
(new-active ts-data cs))
(`(:si-task :task-active ,ts-data)
(new-active ts-data cs))
(e (error "Invalid pattern: %s" e)))))))
(defun org-x-dag-node-is-iterator-p (node) (defun org-x-dag-node-is-iterator-p (node)
(org-x-dag-node-data-is-iterator-p (plist-get node :node-meta))) (org-x-dag-node-data-is-iterator-p (plist-get node :node-meta)))
(defun org-x-dag-bs-action-subiter-inner (node-data ancestry child-bss) (defun org-x-dag-bs-action-subiter-inner (node-data ancestry child-bss)
(org-x-dag-bs-action-with-closed node-data ancestry "sub-iterators" (cl-flet
(if child-bss ((new-active-proj
`(:si-proj :proj-complete ,it-comptime) (d s cs)
`(:si-task :task-complete ,it-comptime)) (->> (list :dead d :child-scheds cs :leading-sched s)
(list :si-proj :proj-active)
(either :right))))
(org-x-dag-bs-action-with-closed node-data ancestry "sub-iterators"
(if child-bss
`(:si-proj :proj-complete ,it-comptime)
`(:si-task :task-complete ,it-comptime))
(org-x-dag-bs-action-subiter-complete-fold child-bss it-comptime (org-x-dag-bs-action-subiter-complete-fold child-bss it-comptime
"sub-iterators" "sub-iterators"
(lambda (c) `(:si-proj :proj-complete ,c)) (lambda (c) `(:si-proj :proj-complete ,c))
(lambda (c) `(:si-task :task-complete ,c))) (lambda (c) `(:si-task :task-complete ,c)))
(-let* (((sched dead) (-some->> it-planning (-let (((sched dead) (-some->> it-planning
(org-ml-get-properties '(:scheduled :deadline)))) (org-ml-get-properties '(:scheduled :deadline)))))
(sp (-some-> sched (org-x-dag-partition-timestamp))) (cond
(dp (-some-> dead (org-x-dag-partition-timestamp)))) ((and sched child-bss)
(cond (either :left "Project sub-iterators cannot be scheduled"))
((and sp child-bss) ((and dead child-bss)
(either :left "Project sub-iterators cannot be scheduled")) (either :left "Project sub-iterators cannot be deadlined"))
((and dp child-bss) ((org-x-dag-node-data-is-iterator-p node-data)
(either :left "Project sub-iterators cannot be deadlined")) (either :left "Iterators cannot be nested"))
((org-x-dag-node-data-is-iterator-p node-data) ((org-x-dag-action-dead-after-parent-p ancestry dead)
(either :left "Iterators cannot be nested")) (either :left "Sub-iterator deadline must not start after parent"))
((org-x-dag-action-dead-after-parent-p ancestry dead) ((equal it-todo org-x-kw-todo)
(either :left "Sub-iterator deadline must not start after parent")) (org-x-dag-bs-action-subiter-todo-fold child-bss
((and sp (plist-get sp :repeater)) `(:si-task :task-active (:sched ,sched :dead ,dead))
(either :left "Scheduled sub-iterators cannot repeat")) (lambda (acc cs)
((and dp (plist-get dp :repeater)) (pcase acc
(either :left "Deadlined sub-iterators cannot repeat")) ((or `(:si-proj :proj-complete ,_)
((and sp (< 0 (plist-get sp :length))) `(:si-task :task-complete ,_))
(either :left "Scheduled sub-iterators cannot be ranged")) (-> "Active sub-iterator must have at least one active child"
((and dp (< 0 (plist-get dp :length))) (org-x-dag-left)))
(either :left "Deadlined sub-iterators cannot be ranged")) (`(:si-proj :proj-active ,ts-data)
((member it-todo (list org-x-kw-todo org-x-kw-wait)) (-let (((&plist :dead d :leading-sched s) ts-data))
(org-x-dag-bs-action-subiter-todo-fold child-bss (new-active-proj d s cs)))
(->> (list :sched sp :dead dp) (`(:si-task :task-active ,ts-data)
(list :si-task :task-active)) (-let (((&plist :dead d :sched s) ts-data))
(->> "Active sub-iterator must have at least one active child" (new-active-proj d s cs)))
(either :left)) (e (error "Invalid pattern: %s" e))))))
(lambda (data) (t
(either :right `(:si-proj :proj-active ,data))))) (org-x-dag-bs-error-kw "Sub-iterator" it-todo)))))))
(t
(org-x-dag-bs-error-kw "Sub-iterator" it-todo))))))
(defun org-x-dag-bs-action-iter-inner (node-data ancestry child-bss) (defun org-x-dag-bs-action-iter-inner (node-data ancestry child-bss)
(org-x-dag-bs-action-with-closed node-data ancestry "iterators" (cl-flet
`(:iter-empty :empty-complete ,it-comptime) ((new-active-iter
(org-x-dag-bs-action-subiter-complete-fold child-bss it-comptime "iterators" (d s cs)
(lambda (c) `(:iter-nonempty :nonempty-complete ,c)) (->> (list :dead d :child-scheds cs :leading-sched s)
(lambda (c) `(:iter-empty :empty-complete ,c))) (list :iter-nonempty :nonempty-active)
(cond (either :right))))
(it-planning (org-x-dag-bs-action-with-closed node-data ancestry "iterators"
(either :left "Iterators cannot be scheduled or deadlined")) `(:iter-empty :empty-complete ,it-comptime)
;; TODO also check for timeshift and archive props (org-x-dag-bs-action-subiter-complete-fold child-bss it-comptime "iterators"
((equal it-todo org-x-kw-todo) (lambda (c) `(:iter-nonempty :nonempty-complete ,c))
(org-x-dag-bs-action-subiter-todo-fold child-bss (lambda (c) `(:iter-empty :empty-complete ,c)))
'(:iter-empty :empty-active) (cond
(either :right '(:iter-nonempty :nonempty-complete)) (it-planning
(lambda (data) (either :left "Iterators cannot be scheduled or deadlined"))
(either :right `(:iter-nonempty :nonempty-active ,data))))) ;; TODO also check for timeshift and archive props
(t ((equal it-todo org-x-kw-todo)
(org-x-dag-bs-error-kw "Iterator" it-todo))))) (org-x-dag-bs-action-subiter-todo-fold child-bss '(:iter-empty :empty-active)
(lambda (acc cs)
(pcase acc
((or `(:si-task :task-complete ,_)
`(:si-proj :proj-complete ,_))
(either :right '(:iter-nonempty :nonempty-complete)))
(`(:si-task :task-active ,ts-data)
(-let (((&plist :dead d :sched s) ts-data))
(new-active-iter d s cs)))
(`(:si-proj :proj-active ,ts-data)
(-let (((&plist :dead d :leading-sched s) ts-data))
(new-active-iter d s cs)))
(e (error "Invalid pattern: %s" e))))))
(t
(org-x-dag-bs-error-kw "Iterator" it-todo))))))
(defun org-x-dag-bs-epg-inner (node ancestry child-bss) (defun org-x-dag-bs-epg-inner (node ancestry child-bss)
(let ((is-complete (let ((is-complete
@ -1349,8 +1228,7 @@ deadline (eg via epoch time) or if it has a repeater."
(-let (((&plist :ancestry a :local l) it)) (-let (((&plist :ancestry a :local l) it))
(list :ancestry a :local (cons :sp-subiter l))))))) (list :ancestry a :local (cons :sp-subiter l)))))))
(-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)
:parent-deadline 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))))) (org-x-dag-bs-prefix :action)))))
@ -1371,7 +1249,6 @@ deadline (eg via epoch time) or if it has a repeater."
(org-x-dag-bs-prefix :endpoint `(,n ,@ns)))) (org-x-dag-bs-prefix :endpoint `(,n ,@ns))))
(defun org-x-dag-bs-toplevel-goal-inner (type-name node-data child-bss) (defun org-x-dag-bs-toplevel-goal-inner (type-name node-data child-bss)
;; TODO allow these to be canceled
(org-x-dag-bs-check-created node-data (org-x-dag-bs-check-created node-data
(-let (((&plist :planning :todo) node-data)) (-let (((&plist :planning :todo) node-data))
(cond (cond
@ -1605,7 +1482,7 @@ deadline (eg via epoch time) or if it has a repeater."
(defun org-x-dag-plist-map (plist key fun) (defun org-x-dag-plist-map (plist key fun)
(declare (indent 2)) (declare (indent 2))
(plist-put (-copy plist) key (funcall fun (plist-get plist key)))) (plist-put plist key (funcall fun (plist-get plist key))))
(defun org-x-dag-plist-cons (plist key x) (defun org-x-dag-plist-cons (plist key x)
(declare (indent 2)) (declare (indent 2))
@ -1626,7 +1503,8 @@ deadline (eg via epoch time) or if it has a repeater."
(let (r) (let (r)
(--each targets (--each targets
(->> (if (setq r (ht-get htbl it)) (->> (if (setq r (ht-get htbl it))
(either<$> r (org-x-dag-plist-cons it key id)) (either<$> r
(org-x-dag-plist-cons it key id))
(either :right `(,key (,id)))) (either :right `(,key (,id))))
(ht-set htbl it))))) (ht-set htbl it)))))
@ -1657,7 +1535,7 @@ deadline (eg via epoch time) or if it has a repeater."
(defun org-x-dag-adjlist-id-all-sched (adjlist id) (defun org-x-dag-adjlist-id-all-sched (adjlist id)
(-when-let (bs (-> (org-x-dag-adjlist-id-bs adjlist id) (-when-let (bs (-> (org-x-dag-adjlist-id-bs adjlist id)
(either-from-right nil))) (either-from-right nil)))
(pcase (plist-get (cdr bs) :local) (pcase bs
(`(:sp-task :task-active ,d) (`(:sp-task :task-active ,d)
(-some-> (plist-get d :sched) (list))) (-some-> (plist-get d :sched) (list)))
(`(:sp-subiter :si-task :task-active ,d) (`(:sp-subiter :si-task :task-active ,d)
@ -2023,8 +1901,8 @@ DEF-FUN and the output from GET-FUN (type :: a -> NS)."
(lambda (h id) (lambda (h id)
(org-x-dag-ht-get-maybe h id s-key)) (org-x-dag-ht-get-maybe h id s-key))
(lambda (plist to-set) (lambda (plist to-set)
(->> (org-x-dag-plist-map plist s-key (->> (org-x-dag-plist-map (-copy plist) s-key
(lambda (x) (append x (-copy to-set)))) (lambda (x) (append x to-set)))
(either :right))) (either :right)))
(lambda (to-set) (lambda (to-set)
(list s-key (-copy to-set))))) (list s-key (-copy to-set)))))
@ -2055,7 +1933,7 @@ DEF-FUN and the output from GET-FUN (type :: a -> NS)."
(either :right plist))))) (either :right plist)))))
(either :right plist)) (either :right plist))
(lambda (to-set) (lambda (to-set)
`(:deadline ,(-copy to-set))))) `(:deadline ,to-set))))
(defun org-x-dag-ht-propagate-action-down (adjlist ns) (defun org-x-dag-ht-propagate-action-down (adjlist ns)
(org-x-dag-ht-map-down adjlist :action ns (org-x-dag-ht-map-down adjlist :action ns
@ -2068,14 +1946,14 @@ DEF-FUN and the output from GET-FUN (type :: a -> NS)."
(lambda (plist to-set) (lambda (plist to-set)
;; copy is needed here for some reason, otherwise other parts of the ;; copy is needed here for some reason, otherwise other parts of the
;; hash table are affected ;; hash table are affected
(-let* (((committed survivalp) (-copy to-set)) (-let* (((committed survivalp) to-set)
(new (-> (-copy plist) (new (-> (-copy plist)
(plist-put :survivalp survivalp) (plist-put :survivalp survivalp)
(org-x-dag-plist-map :committed (org-x-dag-plist-map :committed
(lambda (x) (append x committed)))))) (lambda (x) (append x committed))))))
(either :right new))) (either :right new)))
(lambda (to-set) (lambda (to-set)
(-let (((committed survivalp) (-copy to-set))) (-let (((committed survivalp) to-set))
`(:committed ,committed :survivalp ,survivalp))))) `(:committed ,committed :survivalp ,survivalp)))))
(defun org-x-dag-ht-propagate-up (adjlist h-key s-key ns) (defun org-x-dag-ht-propagate-up (adjlist h-key s-key ns)
@ -2099,7 +1977,7 @@ DEF-FUN and the output from GET-FUN (type :: a -> NS)."
rs*))) rs*)))
(let ((h (alist-get h-key ns))) (let ((h (alist-get h-key ns)))
(--each (ht-keys h) (--each (ht-keys h)
(propagate h it))))) (propagate h it )))))
(defun org-x-dag-get-network-status (sel-date spans adjlist links) (defun org-x-dag-get-network-status (sel-date spans adjlist links)
(cl-flet (cl-flet
@ -2898,6 +2776,12 @@ encountered will be returned."
(u (convert-unit unit))) (u (convert-unit unit)))
`(,v ,u ,type)))))) `(,v ,u ,type))))))
(defun org-x-dag-partition-timestamp (ts)
(list :datetime (org-ml-timestamp-get-start-time ts)
:pos (org-ml-get-property :begin ts)
:repeater (org-ml-timestamp-extract-modulus 'repeater ts)
:warning (org-ml-timestamp-extract-modulus 'warning ts)))
(defun org-x-dag-repeater-get-next (sel-datetime datetime shift shifttype reptype) (defun org-x-dag-repeater-get-next (sel-datetime datetime shift shifttype reptype)
"Return the next timestamp repeater of DATETIME." "Return the next timestamp repeater of DATETIME."
(pcase reptype (pcase reptype
@ -3243,9 +3127,9 @@ FUTURE-LIMIT in a list."
(`(:iter-empty :empty-complete ,_) :complete) (`(:iter-empty :empty-complete ,_) :complete)
(`(:iter-empty :empty-active ,_) :empty) (`(:iter-empty :empty-active ,_) :empty)
(`(:iter-nonempty :nonempty-active ,data) (`(:iter-nonempty :nonempty-active ,data)
(-let* (((&plist :dead d :leading-sched-dt s) data) (-let* (((&plist :dead d :leading-sched s) data)
(d* (-some->> d (org-x-dag-pts-to-epoch))) (d* (-some->> d (org-x-dag-timestamp-to-epoch)))
(s* (-some->> s (org-x-dag-datetime-to-epoch)))) (s* (-some->> s (org-x-dag-timestamp-to-epoch))))
(-if-let (epoch (if (and d* s*) (min d* s*) (or s* d*))) (-if-let (epoch (if (and d* s*) (min d* s*) (or s* d*)))
(if (< (+ (float-time) org-x-iterator-active-future-offset) (if (< (+ (float-time) org-x-iterator-active-future-offset)
epoch) epoch)
@ -3312,17 +3196,16 @@ FUTURE-LIMIT in a 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 . ,bs) (`(:lifetime . ,bs)
(when (equal bs '(:active)) (-let (((&plist :ancestry a :local l) bs))
;; (-let (((&plist :ancestry a :local l) bs)) (when (and (not (plist-get a :canceled-parent-p)) (eq l :active))
;; (when (and (not (plist-get a :canceled-parent-p)) (eq l :active)) (-when-let (ns (org-x-dag-id->ns it))
(-when-let (ns (org-x-dag-id->ns it)) (-let (((&plist :planned p :fulfilled f)
(-let (((&plist :planned p :fulfilled f) (either-from-right ns nil)))
(either-from-right ns nil))) (mk-item it :lifetime p f 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 . ,bs) (`(:endpoint . ,bs)
(-let (((&plist :ancestry a :local l) bs)) (-let (((&plist :ancestry a :local l) bs))
(when (and (not (plist-get a :canceled-parent-p)) (equal l '(:active))) (when (and (not (plist-get a :canceled-parent-p)) (eq l :active))
(-when-let (ns (org-x-dag-id->ns it)) (-when-let (ns (org-x-dag-id->ns it))
(-let (((&plist :planned p :fulfilled f :committed c) (-let (((&plist :planned p :fulfilled f :committed c)
(either-from-right ns nil))) (either-from-right ns nil)))
@ -4399,30 +4282,23 @@ FUTURE-LIMIT in a list."
(either :right it))))) (either :right it)))))
;; child id functions ;; child id functions
(remove-done
(ids)
(--remove (member (org-x-dag-id->todo it) org-done-keywords) ids))
(action-qtp-getter (action-qtp-getter
() ()
(->> (org-x-dag->action-ids) (->> (org-x-dag->action-ids)
;; TODO could also remove DONE/CANC and things ;; TODO could also remove DONE/CANC and things
;; underneath these ;; underneath these
(--remove (org-x-dag-id->ns-key :survivalp it)) (--remove (org-x-dag-id->ns-key :survivalp it))
(remove-done)
(append (org-x-dag->current-qtp-ids)))) (append (org-x-dag->current-qtp-ids))))
(svg-action-getter (svg-action-getter
() ()
(->> (org-x-dag->action-ids) (->> (org-x-dag->action-ids)
;; TODO could also remove DONE/CANC and things ;; TODO could also remove DONE/CANC and things
;; underneath these ;; underneath these
(remove-done)
(--remove (and (org-x-dag-id->ns-key :committed it) (--remove (and (org-x-dag-id->ns-key :committed it)
(not (org-x-dag-id->ns-key :survivalp it)))))) (not (org-x-dag-id->ns-key :survivalp it))))))
(epg-action-qtp-getter (epg-action-qtp-getter
() ()
(->> `(,@(org-x-dag->epg-ids) ,@(action-qtp-getter)) `(,@(org-x-dag->epg-ids) ,@(action-qtp-getter)))
(remove-done)))
;; format functions ;; format functions
(dlp-formatter (dlp-formatter
@ -4560,27 +4436,16 @@ FUTURE-LIMIT in a list."
(either :right)) (either :right))
(parse-hl))) (parse-hl)))
(remove-done
(ids)
(--remove (member (org-x-dag-id->todo it) org-done-keywords) ids))
;; parent id getters ;; parent id getters
(tlg-getter (tlg-getter
() ()
(->> (append (org-x-dag->epg-ids) (org-x-dag->ltg-ids)) (append (org-x-dag->epg-ids) (org-x-dag->ltg-ids)))
(remove-done)))
(goal-getter (goal-getter
() ()
(->> (append (org-x-dag->svg-ids) (tlg-getter)) (append (org-x-dag->svg-ids) (tlg-getter)))
(remove-done)))
(dlp-getter (dlp-getter
() ()
(->> (append (org-x-dag->current-wkp-ids) (org-x-dag->action-ids)) (append (org-x-dag->current-wkp-ids) (org-x-dag->action-ids)))
(remove-done)))
(weekly-getter
()
(->> (org-x-dag->current-qtp-ids)
(remove-done)))
;; formatters ;; formatters
(goal-formatter (goal-formatter
@ -4590,7 +4455,7 @@ FUTURE-LIMIT in a list."
(org-x-dag-id->path nil id))))) (org-x-dag-id->path nil id)))))
(org-x-dag-sync) (org-x-dag-sync)
(let ((f (f-canonical (buffer-file-name)))) (let ((f (buffer-file-name)))
(cond (cond
((equal f (org-x-dag->goal-file :endpoint)) ((equal f (org-x-dag->goal-file :endpoint))
(org-x-dag--link-child-to-parent (org-x-dag--link-child-to-parent
@ -4610,7 +4475,7 @@ FUTURE-LIMIT in a list."
((equal f (org-x-dag->planning-file :weekly)) ((equal f (org-x-dag->planning-file :weekly))
(org-x-dag--link-child-to-parent (org-x-dag--link-child-to-parent
#'parse-hl #'parse-hl
#'weekly-getter #'org-x-dag->current-qtp-ids
#'org-x-dag-id->title)) #'org-x-dag-id->title))
((equal f (org-x-dag->planning-file :daily)) ((equal f (org-x-dag->planning-file :daily))
(org-x-dag--link-child-to-parent (org-x-dag--link-child-to-parent
@ -5144,7 +5009,7 @@ In the order of display
(if is-proj "Deadlined Projects" "Deadlined Tasks"))) (if is-proj "Deadlined Projects" "Deadlined Tasks")))
(format (if is-planned "%s (Planned)" "%s"))))))) (format (if is-planned "%s (Planned)" "%s")))))))
(org-x-dag-agenda-call-inner "Timeblock" 'agenda "" files (org-x-dag-agenda-call-inner "Timeblock" 'agenda "" files
`((org-agenda-sorting-strategy '(time-up deadline-up category-keep)) `((org-agenda-sorting-strategy '(time-up category-keep))
(org-super-agenda-groups (org-super-agenda-groups
'((:auto-map ,conflict-fun :order 4) '((:auto-map ,conflict-fun :order 4)
,(routine-form "Morning Routine" ,(routine-form "Morning Routine"

View File

@ -1965,7 +1965,7 @@ and slow."
(org-ml-to-string) (org-ml-to-string)
(org-ml-build-node-property org-x-prop-created)))) (org-ml-build-node-property org-x-prop-created))))
(org-ml-update-this-headline* (org-ml-update-this-headline*
(org-ml-headline-map-node-properties* (-snoc it np) it)))) (org-ml-headline-map-node-properties* (cons np it) it))))
(defun org-x-set-expired-time (&optional arg) (defun org-x-set-expired-time (&optional arg)
"Set the expired time of the current headline. "Set the expired time of the current headline.

View File

@ -1,223 +0,0 @@
* projects
** TODO this is an active project
:PROPERTIES:
:ID: a98df83f-bc98-4767-b2bc-f1054dbf89f9
:CREATED: [2022-06-07 Tue 22:41]
:END:
*** NEXT this is a project task
:PROPERTIES:
:ID: 2db32ed8-0a1f-488c-8e41-dd3549ac8b1b
:CREATED: [2022-06-07 Tue 22:41]
:END:
** TODO this is an active project (scheduled)
:PROPERTIES:
:ID: 3788c7bc-390e-4caf-af8e-06831ff3276b
:CREATED: [2022-06-10 Fri 19:29]
:END:
*** TODO this is a scheduled task
SCHEDULED: <2022-06-10 Fri>
:PROPERTIES:
:ID: 19a7d558-e087-47ec-b686-feee29d352a1
:CREATED: [2022-06-10 Fri 19:29]
:END:
** TODO this is a waiting project
:PROPERTIES:
:ID: 26586b4d-7fc7-4a9f-b86f-e3c26a83a507
:CREATED: [2022-06-10 Fri 19:18]
:END:
*** WAIT this is a waiting subtask
:PROPERTIES:
:ID: cf58280a-ac7c-4951-a3de-a3f79f92f2b0
:CREATED: [2022-06-10 Fri 19:18]
:END:
** HOLD this is a held project
:PROPERTIES:
:ID: d5065c21-b717-41fe-8232-22afbd6b2243
:CREATED: [2022-06-10 Fri 19:14]
:END:
*** TODO this is a subtask masked by a hold
:PROPERTIES:
:ID: ee9c6ec9-7626-40f5-9f06-3c91bc1338ed
:CREATED: [2022-06-10 Fri 19:14]
:END:
** TODO this is a project held by a subtask
:PROPERTIES:
:ID: a771dc18-0c5f-4196-903d-ada3c8a9d817
:CREATED: [2022-06-10 Fri 19:15]
:END:
*** HOLD this is a held subtask
:PROPERTIES:
:ID: 4f743d31-2df4-4e32-85de-cedae0cffeb2
:CREATED: [2022-06-10 Fri 19:15]
:END:
** TODO this is a stuck project
:PROPERTIES:
:CREATED: [2022-06-07 Tue 22:41]
:ID: c93fe96f-7130-4433-a960-98c07a3b21f4
:END:
*** TODO this is a subtask
:PROPERTIES:
:ID: 2def43a3-e814-4793-adc7-38ddbbf30411
:CREATED: [2022-06-10 Fri 19:08]
:END:
** DONE this is a completed project
CLOSED: [2022-06-10 Fri 19:10]
:PROPERTIES:
:ID: 87682ef6-cd4c-41a7-8f0d-6ac41e572b05
:CREATED: [2022-06-10 Fri 19:10]
:END:
*** DONE this is a completed subtask
CLOSED: [2022-06-10 Fri 19:26]
:PROPERTIES:
:ID: 61866e72-7153-44d1-ae0f-af527fe5f9f4
:CREATED: [2022-06-10 Fri 19:10]
:END:
*** CANC this is a cancelled task
CLOSED: [2022-06-10 Fri 19:26]
:PROPERTIES:
:ID: 322af50a-f431-4940-8caf-cc5acdf5a555
:CREATED: [2022-06-10 Fri 19:25]
:END:
** CANC this is a cancelled project
CLOSED: [2022-06-10 Fri 19:13]
:PROPERTIES:
:ID: eca77dea-4a40-4697-a69d-d1ec798fe9ba
:CREATED: [2022-06-10 Fri 19:13]
:END:
*** TODO this is a subtask masked by a cancel
:PROPERTIES:
:ID: a834a585-acd1-44e9-8e62-17793146d6ab
:CREATED: [2022-06-10 Fri 19:13]
:END:
** TODO this is a deadlined project
DEADLINE: <2022-06-12 Sun>
:PROPERTIES:
:ID: 51798071-f860-48fb-b3d8-e526ce270290
:CREATED: [2022-06-12 Sun 18:09]
:END:
*** NEXT subtask
:PROPERTIES:
:ID: fc1f3dda-a4b7-4b0d-b37c-fa67e112023a
:CREATED: [2022-06-12 Sun 18:10]
:END:
:LOGGING:
- State "NEXT" from "TODO" [2022-06-12 Sun 18:10]
:END:
* iterators
** TODO this is an iterator
:PROPERTIES:
:ID: 2711e9b9-f765-415d-930f-b7ff16b3140b
:CREATED: [2022-06-07 Tue 22:41]
:PARENT_TYPE: iterator
:ARCHIVE: archive.org_archive::* something
:TIME_SHIFT: +1w
:END:
*** TODO repeated thing
SCHEDULED: <2022-06-07 Tue>
:PROPERTIES:
:ID: b02619f6-b9da-4d78-acdd-409a4c5d747b
:CREATED: [2022-06-07 Tue 22:41]
:END:
*** TODO repeated thing
SCHEDULED: <2022-06-14 Tue>
:PROPERTIES:
:ID: d1576921-41b6-4ca9-b775-8f4997983bc4
:CREATED: [2022-06-07 Tue 22:43]
:END:
*** TODO repeated thing
SCHEDULED: <2022-06-21 Tue>
:PROPERTIES:
:ID: a3653d7d-fd29-422e-83ac-06df2594c747
:CREATED: [2022-06-07 Tue 22:43]
:END:
** TODO this is an empty iterator
:PROPERTIES:
:ID: 15cfb339-358a-49ce-8cb3-9bcfb1c5a126
:CREATED: [2022-06-12 Sun 16:40]
:PARENT_TYPE: iterator
:ARCHIVE: archive.org_archive::* something
:TIME_SHIFT: +1w
:END:
** DONE this is a complete iterator
CLOSED: [2022-06-10 Fri 19:13]
:PROPERTIES:
:ID: f2002c13-5ddd-46ec-9895-67182d89dd19
:CREATED: [2022-06-12 Sun 16:44]
:PARENT_TYPE: iterator
:ARCHIVE: archive.org_archive::* something
:TIME_SHIFT: +1w
:END:
*** DONE subiter 1
CLOSED: [2022-06-10 Fri 19:13]
:PROPERTIES:
:ID: fa290644-ba9a-42ac-a25a-a0cca5704d44
:CREATED: [2022-06-12 Sun 16:44]
:END:
*** DONE subiter 2
CLOSED: [2022-06-12 Sun 16:44]
:PROPERTIES:
:ID: 4ec18d87-dda9-43a6-b5e3-4a633160cfec
:CREATED: [2022-06-12 Sun 16:44]
:END:
*** DONE subiter 3
CLOSED: [2022-06-12 Sun 16:44]
:PROPERTIES:
:ID: 30dfcebe-33e8-4190-9460-9bb439cb75e1
:CREATED: [2022-06-12 Sun 16:44]
:END:
** DONE this is a complete empty iterator
CLOSED: [2022-06-10 Fri 19:13]
:PROPERTIES:
:ID: 6ac25533-ba98-4cce-b8a3-9dcf2ada5d77
:CREATED: [2022-06-12 Sun 17:01]
:PARENT_TYPE: iterator
:ARCHIVE: archive.org_archive::* something
:TIME_SHIFT: +1w
:END:
** TODO iterator with projects
:PROPERTIES:
:ID: 6b33c33b-2ce8-405d-b2bb-917305dfa840
:CREATED: [2022-06-12 Sun 17:10]
:PARENT_TYPE: iterator
:ARCHIVE: archive.org_archive::* something
:TIME_SHIFT: +1w
:END:
*** TODO subiter project
:PROPERTIES:
:ID: ed5ff869-2d98-457e-8718-ebb0ca9c1e72
:CREATED: [2022-06-12 Sun 17:10]
:END:
**** TODO subsubiter task
SCHEDULED: <2022-06-12 Sun>
:PROPERTIES:
:ID: b49556a8-0ec3-487d-84bd-78bd29c9eaef
:CREATED: [2022-06-12 Sun 17:10]
:END:
**** TODO subsubiter task
SCHEDULED: <2022-06-14 Tue>
:PROPERTIES:
:ID: f6c2b3ff-66d6-418e-90ec-0d0643bd16ea
:CREATED: [2022-06-12 Sun 17:10]
:END:
* tasks
** TODO this is a standalone task
:PROPERTIES:
:ID: cda28b1a-2b7d-48ea-b1df-e006be799c2f
:CREATED: [2022-06-07 Tue 22:43]
:END:
* metadata tests
** header with a nice tag :nice_tag:
:PROPERTIES:
:ID: c5d3083b-7079-4f76-b8f8-0d994879d8f7
:CREATED: [2022-06-07 Tue 22:43]
:END:
*** TODO task with nice parent tag
:PROPERTIES:
:ID: 3de25d74-b90e-4c77-9f7f-8190187e7ed0
:CREATED: [2022-06-07 Tue 22:43]
:END:
** TODO task with a random local tag :random_tag:
:PROPERTIES:
:ID: e4876e82-c8c8-4ff8-ad23-f78e3904b927
:CREATED: [2022-06-12 Sun 16:34]
:END:

View File

@ -1,10 +0,0 @@
* TODO this is a project all by itself with one goal
:PROPERTIES:
:ID: 49436f7a-629b-4686-b681-c70c7a116ce7
:CREATED: [2022-06-07 Tue 22:45]
:END:
** TODO project task
:PROPERTIES:
:ID: 2f507e50-78ba-4f81-83ce-988358b98200
:CREATED: [2022-06-07 Tue 22:45]
:END:

View File

@ -1,10 +0,0 @@
* 2022 :Y22:
** June :M06:
*** 2022-06-07 :D07:
**** TODO buy boatload of cement for bunker
SCHEDULED: <2022-06-07 Tue>
:PROPERTIES:
:ID: 25ffaad9-d996-48b7-a387-10aa1d46fba8
:CREATED: [2022-06-07 Tue 22:52]
:END:

View File

@ -1,18 +0,0 @@
* TODO this endpoint goal has a parent
:PROPERTIES:
:ID: c2289aeb-f1f4-4e26-8878-f64157d3f724
:CREATED: [2022-06-07 Tue 22:37]
:END:
:X_PARENT_LINKS:
- LTG :: [[id:d6e92244-b1a0-4161-83bc-5a1f0af5541d][/be good at something]]
:END:
** TODO this is a child goal
:PROPERTIES:
:ID: c90f3351-cee6-426f-98ab-d5e9518983ac
:CREATED: [2022-06-07 Tue 22:38]
:END:
* TODO this one doesn't
:PROPERTIES:
:ID: 48322fb9-27c1-455b-a514-d8a4b4da5c2e
:CREATED: [2022-06-07 Tue 22:38]
:END:

View File

@ -1,15 +0,0 @@
* TODO be good at something
:PROPERTIES:
:ID: d6e92244-b1a0-4161-83bc-5a1f0af5541d
:CREATED: [2022-06-07 Tue 22:36]
:END:
* TODO don't be a dick
:PROPERTIES:
:ID: 06592f95-9cf5-4d7e-8546-da7796d76813
:CREATED: [2022-06-07 Tue 22:36]
:END:
** TODO say nice things
:PROPERTIES:
:ID: adc08873-b9fa-423d-950d-db645db05fe5
:CREATED: [2022-06-07 Tue 22:36]
:END:

View File

@ -1,49 +0,0 @@
* 2022 :Y22:
** Quarter 2 :Q2:
*** environmental :_env:
**** TODO something good for the environment
:PROPERTIES:
:ID: aa3e549c-b309-40a2-a687-6d9791653a18
:CREATED: [2022-06-07 Tue 22:48]
:END:
*** financial :_fin:
*** intellectual :_int:
*** metaphysical :_met:
*** physical :_phy:
**** TODO something physically pleasing
:PROPERTIES:
:ID: d6d4dbd9-4d8c-4a1c-81a4-a26776b9627b
:CREATED: [2022-06-07 Tue 22:48]
:END:
*** professional :_pro:
*** recreational :_rec:
*** social :_soc:
** Quarter 3 :Q3:
*** environmental :_env:
*** financial :_fin:
**** TODO make it raaaaaaaain
:PROPERTIES:
:ID: a1a68f4f-1749-425b-afdc-ef79bbe10417
:CREATED: [2022-06-07 Tue 22:49]
:END:
*** intellectual :_int:
**** TODO something that tickles my brain
:PROPERTIES:
:ID: 63259156-ce5d-442a-b6e4-fd4053239db5
:CREATED: [2022-06-07 Tue 22:48]
:END:
*** metaphysical :_met:
*** physical :_phy:
*** professional :_pro:
**** TODO be a wall street bro
:PROPERTIES:
:ID: 9e63d6aa-f217-422b-a996-d9612c972855
:CREATED: [2022-06-07 Tue 22:49]
:END:
*** recreational :_rec:
*** social :_soc:
**** TODO get a life
:PROPERTIES:
:ID: e9c2474f-1c27-4ba4-b46e-5d4e40d560b8
:CREATED: [2022-06-07 Tue 22:49]
:END:

View File

@ -1,15 +0,0 @@
* TODO don't die of hunger
:PROPERTIES:
:ID: 4e7a934a-62ec-4ed5-ab84-e9e7e745b495
:CREATED: [2022-06-07 Tue 22:39]
:END:
* TODO don't get nuked
:PROPERTIES:
:ID: 26bbf72f-51cf-40ba-a7dd-ca689bcd1627
:CREATED: [2022-06-07 Tue 22:40]
:END:
** TODO make a bunker
:PROPERTIES:
:ID: e16514a0-626c-476f-b647-1eaf6580c57a
:CREATED: [2022-06-07 Tue 22:40]
:END:

View File

@ -1,71 +0,0 @@
* 2022 :Y22:
** June :M06:
*** TODO 2022-06-06
SCHEDULED: <2022-06-06 Mon>
:PROPERTIES:
:ID: 76534d4a-e516-495c-b083-5b053c44af1d
:X-WEEK-LEN: 7
:END:
**** TODO Monday
SCHEDULED: <2022-06-06 Mon>
:PROPERTIES:
:ID: 6b53ee41-b467-4bfb-a580-6218a3c78068
:END:
***** DONE be social
CLOSED: [2022-08-07 Sun 23:28]
:PROPERTIES:
:ID: f02504bd-45f8-4da6-936e-1b15e043f3d4
:CREATED: [2022-06-07 Tue 22:50]
:END:
:LOGGING:
- State "DONE" from "TODO" [2022-08-07 Sun 23:28]
:END:
**** TODO Tuesday
SCHEDULED: <2022-06-07 Tue>
:PROPERTIES:
:ID: 93955806-3b04-4ee5-8be5-fb8a9117c6b7
:END:
**** TODO Wednesday
SCHEDULED: <2022-06-08 Wed>
:PROPERTIES:
:ID: 8b0de76b-fff9-4890-9e85-8f4ccabf4f12
:END:
***** TODO learn about bitcoin
:PROPERTIES:
:ID: ed1406ad-1231-46de-b026-8067411133dc
:CREATED: [2022-06-07 Tue 22:51]
:END:
**** TODO Thursday
SCHEDULED: <2022-06-09 Thu>
:PROPERTIES:
:ID: f977dca9-c8e6-47d0-a9cd-eba8194fcb96
:END:
**** TODO Friday
SCHEDULED: <2022-06-10 Fri>
:PROPERTIES:
:ID: 1d926eef-94c9-4b57-8cb0-225a308711e9
:END:
***** CANC learn to gamble
CLOSED: [2022-08-07 Sun 23:28]
:PROPERTIES:
:ID: ab077745-4041-458f-90ec-02aaecb2729d
:CREATED: [2022-06-07 Tue 22:51]
:END:
:LOGGING:
- State "CANC" from "TODO" [2022-08-07 Sun 23:28]
:END:
**** TODO Saturday
SCHEDULED: <2022-06-11 Sat>
:PROPERTIES:
:ID: 24659f4b-1e0d-4022-a4cc-359a7bb15592
:END:
***** TODO build nuclear bunker
:PROPERTIES:
:ID: bfe5d3c1-3b7d-46f9-9c60-8a2bdec08d6d
:CREATED: [2022-06-07 Tue 22:51]
:END:
**** TODO Sunday
SCHEDULED: <2022-06-12 Sun>
:PROPERTIES:
:ID: 541245c4-e51d-48ae-ab51-e29325d5c9fe
:END:

View File

@ -1,442 +0,0 @@
;;; org-x-dag-test.el --- Smesh my API -*- lexical-binding: t -*-
;; Copyright (C) 2015 Free Software Foundation, Inc.
;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
;;; Commentary:
;; run tests with this (in the org-x directory above this one):
;; emacs -batch -l init.el -l local/lib/org-x/test/org-x-dag-test.el -f buttercup-run
;;; Code:
(require 's)
(require 'dash)
(require 'either)
(require 'org-x)
(defun setup ()
(setq org-directory (nd/expand-lib-directory "org-x/test/dag")
org-x-action-files (list "action1.org" "action2.org")
org-x-endpoint-goal-file "endpoint.org"
org-x-lifetime-goal-file "lifetime.org"
org-x-survival-goal-file "survival.org"
org-x-daily-plan-file "daily.org"
org-x-weekly-plan-file "weekly.org"
org-x-quarterly-plan-file "quarterly.org"))
(defun partition-timestamp (s)
(->> (org-ml-from-string 'timestamp s)
(org-x-dag-partition-timestamp)))
(defun timestamp-to-datetime (s)
(->> (org-ml-from-string 'timestamp s)
(org-ml-timestamp-get-start-time)))
(defun timestamp-to-epoch (s)
(->> (org-ml-from-string 'timestamp s)
(org-ml-timestamp-get-start-time)
(org-ml-time-to-unixtime)))
(buttercup-define-matcher :to-be-left-with (a x)
(cl-destructuring-bind
((a-expr . a) (x-expr . x))
(mapcar #'buttercup--expr-and-value (list a x))
(either-from a
(lambda (l)
(if (equal l x)
`(t . ,(format "Expected %s left with %s" a-expr x))
`(nil . ,(format "Expected %s left with %s, but got left with %s"
a-expr x l))))
(lambda ()
`(nil . ,(format "Expected %s to be a left, got a right" a-expr))))))
(buttercup-define-matcher :to-be-right-with (a x)
(cl-destructuring-bind
((a-expr . a) (x-expr . x))
(mapcar #'buttercup--expr-and-value (list a x))
(either-from a
(lambda ()
`(nil . ,(format "Expected %s to be a right, got a left" a-expr)))
(lambda (r)
(if (equal r x)
`(t . ,(format "Expected %s right with %s" a-expr x))
`(nil . ,(format "Expected %s right with %s, but got right with %s"
a-expr x r)))))))
(defun split-plists (eq-funs a b)
(cl-flet
((get-keys
(x)
(->> (-partition 2 x)
(-map #'car)))
(key-eq
(k)
(let ((av (plist-get a k))
(bv (plist-get b k))
(f (or (plist-get eq-funs k) #'equal)))
(funcall f av bv))))
(let* ((a* (get-keys a))
(b* (get-keys b))
(a- (-difference a* b*))
(b- (-difference b* a*))
(common (->> (-intersection a* b*)
(--reduce-from (if (key-eq it) acc
(cons (list it
(plist-get a it)
(plist-get b it))
acc))
nil))))
`(,a- ,b- ,common))))
(defun plists-equal-p (a b)
(equal (split-plists nil a b) '(nil nil nil)))
(defun element-equal-p (a b)
;; NOTE this does not compare children of elements/objects
(cl-flet
((get-useful-props
(node)
(->> (org-ml-get-all-properties node)
(-partition 2)
(--remove (memq (car it) '(:parent :begin :end :contents-begin :contents-end)))
(-flatten-n 1))))
(and (eq (org-ml-get-type a) (org-ml-get-type b))
(plists-equal-p (get-useful-props a) (get-useful-props b)))))
(defun pts-equal-p (a b)
(-let (((&plist :datetime da :repeater ra :warning wa :length la) a)
((&plist :datetime db :repeater rb :warning wb :length lb) b))
(and (equal da db)
(equal ra rb)
(equal wa wb)
(equal la lb))))
(defun plist-diff-msg (eq-funs expr a b)
(-let (((a-diff b-diff common-diffs) (split-plists eq-funs a b)))
(cond
((and a-diff b-diff)
(format "Expected %s to have keys '%s' and not to have keys '%s'"
expr b-diff a-diff))
(a-diff
(format "Expected %s not to have keys '%s'" expr a-diff))
(b-diff
(format "Expected %s to have keys '%s'" expr b-diff))
(common-diffs
(-let (((as bs)
(->> common-diffs
(--map `((,(car it) ,(nth 1 it)) (,(car it) ,(nth 2 it))))
(apply #'-zip-lists))))
(format "Expected %s to have key/value pairs '%s' but instead had '%s'"
expr as bs))))))
(defun status-diff-msg (eq-funs expr type subtype data to-test)
(-let* (((type* . rest) to-test)
((subtype* last) (-split-at (length subtype) rest))
(data* (car last)))
(cond
((not (eq type* type))
(format "Expected %s to have type '%s' but instead had type '%s'"
expr type type*))
((and subtype (not (equal subtype* subtype)))
(format "Expected %s to have subtype '%s' but instead had subtype '%s'"
expr subtype subtype*))
(t
(plist-diff-msg eq-funs expr data data*)))))
(defun ancestry-diff-msg (eq-funs expr ancestry inner-fun to-test)
(declare (indent 3))
(-let* (((&plist :ancestry A :local L) to-test))
(or (plist-diff-msg eq-funs expr A ancestry)
(funcall inner-fun L))))
(defun buffer-status-diff-msg (expr type inner-fun to-test)
(declare (indent 3))
(-let (((type* . rest) to-test))
(if (eq type type*) (funcall inner-fun rest)
(format "Expected buffer-status %s to be type '%s' but instead was type '%s'"
expr type type*))))
(defun right-diff-msg (expr inner-fun to-test)
(declare (indent 2))
(either-from to-test
(lambda ()
(format "Expected %s to be a right, got a left" expr))
inner-fun))
;; TODO this will eventually have canceled as part of it
(buttercup-define-matcher :id-to-be-tlg (to-test type status)
(cl-destructuring-bind
((test-expr . test) (_ . y) (_ . s))
(->> (list to-test type status)
(-map #'buttercup--expr-and-value))
(let ((f (->> (-partial #'status-diff-msg nil test-expr s nil nil)
(-partial #'buffer-status-diff-msg test-expr y)
(-partial #'right-diff-msg test-expr))))
(-if-let (m (funcall f (org-x-dag-id->bs test)))
(cons nil m)
(cons t (format "Expected '%s' not to be the indicated action" test-expr))))))
(buttercup-define-matcher :id-to-be-action (to-test canceled held deadline
type subtype data)
(cl-destructuring-bind
((test-expr . test) (_ . c) (_ . h) (_ . e) (_ . y) (_ . s) (_ . d))
(->> (list to-test canceled held deadline type subtype data)
(-map #'buttercup--expr-and-value))
(let* ((ancestry (list :canceled-parent-p c
:held-parent-p h
:parent-deadline e))
(ancestry-eq-funs nil)
(local-eq-funs (list :sched #'element-equal-p
:child-scheds #'pts-equal-p))
(f (->> (-partial #'status-diff-msg local-eq-funs test-expr y s d)
(-partial #'ancestry-diff-msg ancestry-eq-funs test-expr ancestry)
(-partial #'buffer-status-diff-msg test-expr :action)
(-partial #'right-diff-msg test-expr))))
(-if-let (m (funcall f (org-x-dag-id->bs test)))
(cons nil m)
(cons t (format "Expected '%s' not to be the indicated action" test-expr))))))
(buttercup-define-matcher :id-to-be-qtp (to-test status deadline date)
(cl-destructuring-bind
((test-expr . test) (_ . s) (_ . d) (_ . D))
(->> (list to-test status deadline date)
(-map #'buttercup--expr-and-value))
(let* ((local-eq-funs (list :deadline #'element-equal-p :date #'eq))
(abs-date (org-x-dag-date-to-absolute D))
(data (list :deadline d :date abs-date))
(f (->> (-partial #'status-diff-msg local-eq-funs test-expr s nil data)
(-partial #'buffer-status-diff-msg test-expr :quarterly)
(-partial #'right-diff-msg test-expr))))
(-if-let (m (funcall f (org-x-dag-id->bs test)))
(cons nil m)
(cons t (format "Expected '%s' not to be the indicated action" test-expr))))))
;; (buttercup-define-matcher :id-to-be-wkp (to-test status subtype date)
;; (cl-destructuring-bind
;; ((test-expr . test) (_ . s) (_ . y) (_ . d))
;; (->> (list to-test status subtype date)
;; (-map #'buttercup--expr-and-value))
;; (let* ((abs-date (org-x-dag-date-to-absolute d))
;; (f (->> (-partial #'status-diff-msg nil test-expr y `(,s) abs-date)
;; (-partial #'buffer-status-diff-msg test-expr :weekly)
;; (-partial #'right-diff-msg test-expr))))
;; (-if-let (m (funcall f (org-x-dag-id->bs test)))
;; (cons nil m)
;; (cons t (format "Expected '%s' not to be the indicated action" test-expr))))))
;; (buttercup-define-matcher :to-have-same-as-plist (a b)
;; (cl-destructuring-bind
;; ((a-expr . a) (b-expr . b))
;; (mapcar #'buttercup--expr-and-value (list a b))
;; (let* ((a* (-partition 2 a))
;; (b* (-partition 2 b))
;; (a-diff (->> (-difference a* b*) (--map (format "%S" it)) (s-join ", ")))
;; (b-diff (->> (-difference b* a*) (--map (format "%S" it)) (s-join ", "))))
;; (cond
;; ((and a-diff b-diff)
;; (cons nil (format "Expected %s to have pairs '%s' and not to have pairs '%s'"
;; a-expr b-diff a-diff)))
;; (a-diff
;; (cons nil (format "Expected %s not to have pairs '%s'" a-expr a-diff)))
;; (b-diff
;; (cons nil (format "Expected %s to have pairs '%s'" a-expr b-diff)))
;; (t
;; (cons t (format "Expected %s not to have same items as '%s'"
;; a-expr b-expr)))))))
(defmacro bs-ltg-active (id)
(declare (indent 1))
`(expect (org-x-dag-id->bs ,id) :to-be-right-with '(:lifetime :active)))
(describe "Sync DAG"
(before-all
(setup))
(it "Sync completes without error"
(expect (org-x-dag-sync t) :not :to-throw))
(describe "Lifetime buffer statuses"
(it "Active (toplevel)"
(expect "d6e92244-b1a0-4161-83bc-5a1f0af5541d" :id-to-be-tlg
:lifetime :active))
(it "Active (nested)"
(expect "adc08873-b9fa-423d-950d-db645db05fe5" :id-to-be-tlg
:lifetime :active)))
(describe "Survival buffer statuses"
(it "Active (toplevel)"
(expect "4e7a934a-62ec-4ed5-ab84-e9e7e745b495" :id-to-be-tlg
:survival :active))
(it "Active (nested)"
(expect "e16514a0-626c-476f-b647-1eaf6580c57a" :id-to-be-tlg
:survival :active)))
(describe "Action buffer statuses"
(describe "Projects"
(it "Active"
(expect "a98df83f-bc98-4767-b2bc-f1054dbf89f9" :id-to-be-action
nil nil nil :sp-proj '(:proj-active) '(:child-scheds nil)))
(it "Active (scheduled)"
(let ((sched (partition-timestamp "<2022-06-10 Fri>")))
(expect "3788c7bc-390e-4caf-af8e-06831ff3276b" :id-to-be-action
nil nil nil :sp-proj '(:proj-active)
`(:child-scheds (,sched)))))
(it "Wait"
(expect "26586b4d-7fc7-4a9f-b86f-e3c26a83a507" :id-to-be-action
nil nil nil :sp-proj '(:proj-wait) nil))
(it "Held (toplevel)"
(expect "d5065c21-b717-41fe-8232-22afbd6b2243" :id-to-be-action
nil nil nil :sp-proj '(:proj-held) nil))
(it "Held (subtask)"
(expect "a771dc18-0c5f-4196-903d-ada3c8a9d817" :id-to-be-action
nil nil nil :sp-proj '(:proj-held) nil))
(it "Stuck"
(expect "c93fe96f-7130-4433-a960-98c07a3b21f4" :id-to-be-action
nil nil nil :sp-proj '(:proj-stuck) nil))
(it "Completed"
(expect "87682ef6-cd4c-41a7-8f0d-6ac41e572b05" :id-to-be-action
nil nil nil :sp-proj '(:proj-complete)
'(:canceledp nil :epoch 1654902600)))
(it "Canceled"
(expect "eca77dea-4a40-4697-a69d-d1ec798fe9ba" :id-to-be-action
nil nil nil :sp-proj '(:proj-complete)
'(:canceledp t :epoch 1654902780))))
(describe "Project Tasks"
(it "Active"
(expect "2db32ed8-0a1f-488c-8e41-dd3549ac8b1b" :id-to-be-action
nil nil nil :sp-task '(:task-active)
'(:todo "NEXT" :sched nil :dead nil)))
(it "Waiting"
(expect "cf58280a-ac7c-4951-a3de-a3f79f92f2b0" :id-to-be-action
nil nil nil :sp-task '(:task-active)
'(:todo "WAIT" :sched nil :dead nil)))
(it "Held"
(expect "4f743d31-2df4-4e32-85de-cedae0cffeb2" :id-to-be-action
nil nil nil :sp-task '(:task-active)
'(:todo "HOLD" :sched nil :dead nil)))
(it "Completed"
(expect "61866e72-7153-44d1-ae0f-af527fe5f9f4" :id-to-be-action
nil nil nil :sp-task '(:task-complete)
'(:canceledp nil :epoch 1654903560)))
(it "Canceled"
(expect "322af50a-f431-4940-8caf-cc5acdf5a555" :id-to-be-action
nil nil nil :sp-task '(:task-complete)
'(:canceledp t :epoch 1654903560)))
(it "Deadlined"
(let ((d (timestamp-to-epoch "<2022-06-12 Sun>")))
(expect "fc1f3dda-a4b7-4b0d-b37c-fa67e112023a" :id-to-be-action
nil nil d :sp-task '(:task-active)
'(:todo "NEXT" :sched nil :dead nil)))))
(describe "Standalone Tasks"
(it "Active"
(expect "cda28b1a-2b7d-48ea-b1df-e006be799c2f" :id-to-be-action
nil nil nil :sp-task '(:task-active)
'(:sched nil :dead nil :todo "TODO"))))
(describe "Iterators"
(it "Active non-empty"
(let ((s0 (partition-timestamp "<2022-06-07 Tue>"))
(s1 (partition-timestamp "<2022-06-14 Tue>"))
(s2 (partition-timestamp "<2022-06-21 Tue>")))
(expect "2711e9b9-f765-415d-930f-b7ff16b3140b" :id-to-be-action
nil nil nil :sp-iter '(:iter-nonempty :nonempty-active)
(list :child-scheds `(,s0 ,s1 ,s2)
:leading-sched-dt (plist-get s2 :datetime)
:dead nil))))
(it "Active non-empty (with project)"
(let ((s0 (partition-timestamp "<2022-06-12 Tue>"))
(s1 (partition-timestamp "<2022-06-14 Tue>")))
(expect "6b33c33b-2ce8-405d-b2bb-917305dfa840" :id-to-be-action
nil nil nil :sp-iter '(:iter-nonempty :nonempty-active)
(list :child-scheds `(,s0 ,s1)
:leading-sched-dt (plist-get s1 :datetime)
:dead nil))))
(it "Active empty"
(expect "15cfb339-358a-49ce-8cb3-9bcfb1c5a126" :id-to-be-action
nil nil nil :sp-iter '(:iter-empty :empty-active) nil))
(it "Complete non-empty"
(expect "f2002c13-5ddd-46ec-9895-67182d89dd19" :id-to-be-action
nil nil nil :sp-iter '(:iter-nonempty :nonempty-complete)
'(:canceledp nil :epoch 1654902780)))
(it "Active empty"
(expect "6ac25533-ba98-4cce-b8a3-9dcf2ada5d77" :id-to-be-action
nil nil nil :sp-iter '(:iter-empty :empty-complete)
'(:canceledp nil :epoch 1654902780))))
(describe "Sub-iterators"
(it "Active task"
(let ((s (partition-timestamp "<2022-06-07 Tue>")))
(expect "b02619f6-b9da-4d78-acdd-409a4c5d747b" :id-to-be-action
nil nil nil :sp-subiter '(:si-task :task-active)
(list :sched s :dead nil))))
(it "Complete task"
(expect "fa290644-ba9a-42ac-a25a-a0cca5704d44" :id-to-be-action
nil nil nil :sp-subiter '(:si-task :task-complete)
'(:canceledp nil :epoch 1654902780)))
(it "Active project"
(let ((s0 (partition-timestamp "<2022-06-12 Sun>"))
(s1 (partition-timestamp "<2022-06-14 Sun>")))
(expect "ed5ff869-2d98-457e-8718-ebb0ca9c1e72" :id-to-be-action
nil nil nil :sp-subiter '(:si-proj :proj-active)
(list :dead nil
:child-scheds `(,s0 ,s1)
:leading-sched-dt (plist-get s1 :datetime)))))))
;; TODO add deadline to this (but in absolute form)
(describe "Quarterly buffer statuses"
(it "Active"
(expect "aa3e549c-b309-40a2-a687-6d9791653a18" :id-to-be-qtp
:active nil '(2022 4 1))))
;; (describe "Weekly buffer statuses"
;; (it "Active (leaf)"
;; (expect "ed1406ad-1231-46de-b026-8067411133dc" :id-to-be-wkp
;; :active :leaf '(2022 6 6))))
(describe "Metadata Tests"
(it "parent tag"
(expect (org-x-dag-id->tags "3de25d74-b90e-4c77-9f7f-8190187e7ed0")
:to-equal '("nice_tag")))
(it "local tag"
(expect (org-x-dag-id->local-tags "e4876e82-c8c8-4ff8-ad23-f78e3904b927")
:to-equal '("random_tag")))))
(provide 'org-x-dag-test)
;;; org-x-dag-test.el ends here

View File

@ -1,11 +0,0 @@
#!/bin/bash
# Print a list of all pacman packages required to run this emacs configuration
this_dir=$(dirname "$0")
emacs -batch \
-l "$this_dir/init.el" \
-f nd/dump-arch-dependencies \
2> /dev/null | \
sed 's/"//'

View File

@ -1,33 +0,0 @@
;; disable automatic package updates
(setq straight-check-for-modifications nil)
;; watch for repo modifications if we have python3 and watchexec
;; otherwise just use a save hook
;; (setq straight-check-for-modifications
;; (if (and (executable-find "python3")
;; (executable-find "watchexec"))
;; '(watch-files find-when-checking)
;; '(check-on-save find-when-checking)))
;; add pinned packages to straight
;; (setq straight-profiles
;; '((nil . "default.el")
;; ;; Packages which are pinned to a specific commit.
;; (pinned . "pinned.el")))
;; bootstrap straight
(defvar bootstrap-version)
(let ((bootstrap-file
(expand-file-name "straight/repos/straight.el/bootstrap.el" user-emacs-directory))
(bootstrap-version 5))
(unless (file-exists-p bootstrap-file)
(with-current-buffer
(url-retrieve-synchronously
"https://raw.githubusercontent.com/raxod502/straight.el/develop/install.el"
'silent 'inhibit-cookies)
(goto-char (point-max))
(eval-print-last-sexp)))
(load bootstrap-file nil 'nomessage))
;; install use-package itself
(straight-use-package 'use-package)

View File

@ -1,136 +1,139 @@
(("ESS" . "950bf61054bd96d2203ac0457792c0af8dfba721") (("ESS" . "e83ac622fe7e3cbfc848481a9257e5ed5c7b5afb")
("Highlight-Indentation-for-Emacs" . "d88db4248882da2d4316e76ed673b4ac1fa99ce3") ("Highlight-Indentation-for-Emacs" . "d88db4248882da2d4316e76ed673b4ac1fa99ce3")
("ace-window" . "77115afc1b0b9f633084cf7479c767988106c196") ("ace-window" . "0577c426a9833ab107bab46c60d1885c611b2fb9")
("anaconda-mode" . "f900bd7656a03aa24ef3295251f266736f7756eb") ("anaconda-mode" . "cbea0fb3182321d34ff93981c5a59f8dd72d82a5")
("annalist.el" . "e1ef5dad75fa502d761f70d9ddf1aeb1c423f41d") ("annalist.el" . "134fa3f0fb91a636a1c005c483516d4b64905a6d")
("auctex" . "ca8c9077c4c889cc11d150af9f0d9bd5914d702e") ("auctex" . "53b82804c9dd9dbea306876f3be84ebacbeb7e74")
("auth-source-xoauth2" . "5d1adfa649bb5a9df20a2fa89f235a55a64b52e4") ("auth-source-xoauth2" . "d3890eaa3a46dc89758ec6b789949e70ae782896")
("avy" . "be612110cb116a38b8603df367942e2bb3d9bdbe") ("avy" . "ba5f035be33693d1a136a5cbeedb24327f551a92")
("bats-mode" . "fa88930b1baba101ae6474f289a239a236a7d19f") ("beacon" . "bde78180c678b233c94321394f46a81dc6dce1da")
("beacon" . "85261a928ae0ec3b41e639f05291ffd6bf7c231c") ("biblio.el" . "517ec18f00f91b61481214b178f7ae0b8fbc499b")
("biblio.el" . "ee52f6cda82ea6fbc3b400e7b12132595cc0374c") ("blacken" . "764912ada13c3bf57e770fcd978c81a1ce26666a")
("blacken" . "3c6eb86ad871ca14fcfd4e5c0e7b285afa1f1f71")
("c-eldoc" . "f4ede1f37f6de583376669735326367d84a0a917") ("c-eldoc" . "f4ede1f37f6de583376669735326367d84a0a917")
("citeproc-el" . "54184baaff555b5c7993d566d75dd04ed485b5c0") ("cider" . "df34f141f32739e3c5657fb85ad6ff23520d44bf")
("clang-format" . "9f4358fcc8b04018cc1ed46fcc96fc7bfa361a47") ("citeproc-el" . "ba49516265fa24b138346c4918d39d19b4de8a62")
("company-anaconda" . "169252fca79a79da41ef22f2ec0eab0cf1313966") ("clang-format" . "e48ff8ae18dc7ab6118c1f6752deb48cb1fc83ac")
("clojure-mode" . "b6f41d74904daa9312648f3a7bea7a72fd8e140b")
("company-anaconda" . "da1566db41a68809ef7f91ebf2de28118067c89b")
("company-auctex" . "9400a2ec7459dde8cbf1a5d50dfee4e300ed7e18") ("company-auctex" . "9400a2ec7459dde8cbf1a5d50dfee4e300ed7e18")
("company-c-headers" . "9d384571b1190e99d0a789e5296176d69a3d0771") ("company-c-headers" . "9d384571b1190e99d0a789e5296176d69a3d0771")
("company-irony" . "b44711dfce445610c1ffaec4951c6ff3882b216a") ("company-irony" . "b44711dfce445610c1ffaec4951c6ff3882b216a")
("company-math" . "3eb006874e309ff4076d947fcbd61bb6806aa508") ("company-math" . "45778f5731c97a21a83e3b965cbde42018709afd")
("company-mode" . "1321e285a54dfe43cae71f52e58bff4f0c8c161d") ("company-mode" . "d5145006b948f93e673f439a766da01f636d39fc")
("compat" . "99d74e635b76c3fa0b8403391e9d2efbd29f9901") ("compat" . "81378ce2549e6c6df5141d459036438cb98b9ad3")
("conda.el" . "ce748a53f9c7d7a7d112632d32c848d6e5482e18") ("conda.el" . "7a34e06931515d46f9e22154762e06e66cfbc81c")
("csv-mode" . "6979fc18ebe133cfe2fca02efda9a9f0cd13428a") ("csv-mode" . "53beddc207864b0c3f81da85b59245dff8eea5ce")
("dash.el" . "1de9dcb83eacfb162b6d9a118a4770b1281bcd84") ("dash.el" . "f9e6602ac9966b74a5ba6e3d332535543c84f4d5")
("delight" . "15acb0f0ba400c470e378f9984b315f9e02c1122") ("delight" . "70cb8cec9e5eb2c24364e065d85c2ea8f14a587c")
("dhall-mode" . "87ab69fe765d87b3bb1604a306a8c44d6887681d") ("dired-du" . "4ce114a0195b852022a81b05f0c8e0cbbc1ed013")
("dired-du" . "c16cad8c40a022a03dee1956a15ff44d1e42dc07") ("dired-hacks" . "7c0ef09d57a80068a11edc74c3568e5ead5cc15a")
("dired-hacks" . "e9e408e8571aee5574ca0a431ef15cac5a3585d4") ("dockerfile-mode" . "b63a3d12b7dea0cb9efc7f78d7ad5672ceab2a3f")
("dockerfile-mode" . "39a012a27fcf6fb629c447d13b6974baf906714c") ("ebib" . "0e243a78f435038dda31953c5b48cbddf2a89e27")
("ebib" . "5ea510a1e4ab17a442352d0212777da5f78d4be2") ("el-get" . "bf3dba444dcd240b8cb358a0850c8c5a92606134")
("el-get" . "c0713e8d8e8ad987fe1283d76b9c637a10f048ef") ("elpy" . "1746e7009000b7635c0ea6f1559018143aa61642")
("elpy" . "c40bab559fe77dcef6b90d5502eba1ecd566e86d") ("emacs-async" . "c78bab7506a70a735d2c3deab13fa87bf44a83d3")
("emacs-async" . "e1d46f97a56e0c57206bd1ea31d04311097a8cbb") ("emacs-buttercup" . "ceedad5efa797e860dbb356bc2c3028a4e0321ec")
("emacs-buttercup" . "dfbef2177209e3a045e981b7d2956ec46ce3b25b") ("emacs-calfw" . "03abce97620a4a7f7ec5f911e669da9031ab9088")
("emacs-dashboard" . "187699e2d80f6a3b0ec7b2fb2e1d7ece2712208f") ("emacs-dashboard" . "34d1f97200055e6b521c131270d8322efc6c52be")
("emacs-format-all-the-code" . "f8feea08fef7ed542b8e676e90445d57ebd2c458") ("emacs-format-all-the-code" . "828280eaf3b46112e17746a7d03235570a633425")
("emacs-htmlize" . "ed5e5b05fd260e8f161a488d56f10e7f6e01fb75") ("emacs-htmlize" . "dd27bc3f26efd728f2b1f01f9e4ac4f61f2ffbf9")
("emacs-language-id" . "44452e4f7962aca41cc2539fce1d27799d6e656c") ("emacs-language-id" . "5325af36d9cd726de47a698ac159fce59f3fd6d9")
("emacs-refactor" . "cac1b52932926f56d7f6d2923732d20bbd20670d") ("emacs-refactor" . "cac1b52932926f56d7f6d2923732d20bbd20670d")
("emacs-reformatter" . "0d29a04d69d47599e2cb7f1a8f8e897a2b592921") ("emacs-web-server" . "22ce66ea43e0eadb9ec1d691a35d9695fc29cee6")
("emacs-request" . "01e338c335c07e4407239619e57361944a82cb8a") ("emacs-which-key" . "1ab1d0cc88843c9a614ed3226c5a1070e32e4823")
("emacs-web-server" . "3982c55e9061475038a3ccd61aecb2de3d407cec") ("emacsmirror-mirror" . "2e1ceba3c8036637832e99414d9012359911f5e4")
("emacs-which-key" . "38d4308d1143b61e4004b6e7a940686784e51500") ("epl" . "78ab7a85c08222cd15582a298a364774e3282ce6")
("emacsmirror-mirror" . "8cbbdaa750c897d05ee71980834699a7d7c2d208") ("evil" . "157af04d2cf466e301e82b0e667c5e7203fd96a2")
("evil" . "5db0bdc7dcd9300b983526d37cbe480f35e36211")
("evil-ReplaceWithRegister" . "91cc7bf21a94703c441cc9212214075b226b7f67") ("evil-ReplaceWithRegister" . "91cc7bf21a94703c441cc9212214075b226b7f67")
("evil-collection" . "772571fc6762b6cd1d35cc869e266de9a5c6022b") ("evil-collection" . "98d28bc67909225a4746c557449c9da816f5d0f5")
("evil-commentary" . "c5945f28ce47644c828aac1f5f6ec335478d17fb") ("evil-commentary" . "2dab6ac34d1617971768ad219d73af48f7473fec")
("evil-org-mode" . "b1f309726b1326e1a103742524ec331789f2bf94") ("evil-org-mode" . "0d10ff7bb9a3a93d25cd91018b17f0a052b335f3")
("evil-surround" . "da05c60b0621cf33161bb4335153f75ff5c29d91") ("evil-surround" . "c9e1449bf3f740b5e9b99e7820df4eca7fc7cf02")
("f.el" . "1e7020dc0d4c52d3da9bd610d431cab13aa02d8c") ("f.el" . "bf586b80a5298df68a094f70bc1a1bd6f8e948df")
("fill-column-indicator" . "c35f9de072c241699b57bcb46da84bed5af29cfe") ("fill-column-indicator" . "c35f9de072c241699b57bcb46da84bed5af29cfe")
("flycheck" . "7a6398ea3538a898eba0276f0f89b2f878325a89") ("flycheck" . "66a973afca1d03b8284baaa7590eb2b8615a1e6a")
("flycheck-clang-analyzer" . "646d9f3a80046ab231a07526778695d5decad92d") ("flycheck-clang-analyzer" . "646d9f3a80046ab231a07526778695d5decad92d")
("flycheck-haskell" . "b7c4861aa754220b7d0cfc05aa0895bb35665683") ("flycheck-package" . "615c1ed8c6fb7c73abec6aaa73d3fef498d231bc")
("flycheck-package" . "75efa098cf17dc14c363e2ca9b68afdac7766b5b") ("flyspell-correct" . "7d7b6b01188bd28e20a13736ac9f36c3367bd16e")
("flyspell-correct" . "1e7a5a56362dd875dddf848b9a9e25d1395b9d37") ("gnu-elpa-mirror" . "808923d95777d378ca340b8020dd571e6a62460a")
("gnu-elpa-mirror" . "3d0759ef4792b6461f2979a4e70e1c819df7283a") ("goto-chg" . "278cd3e6d5107693aa2bb33189ca503f22f227d0")
("goto-chg" . "72f556524b88e9d30dc7fc5b0dc32078c166fda7") ("graphviz-dot-mode" . "6e96a89762760935a7dff6b18393396f6498f976")
("graphviz-dot-mode" . "8ff793b13707cb511875f56e167ff7f980a31136") ("haskell-mode" . "5a9f8072c7b9168f0a8409adf9d62a3e4ad4ea3d")
("haskell-mode" . "727f72a2a4b8e4fd0a7b62129668baea55a2c3e0") ("helm-bibtex" . "ce8c17690ddad73d01531084b282f221f8eb6669")
("helm-bibtex" . "8b71b4f5ce62eeaf18067f57faaddc06449fbe1c") ("ht.el" . "c4c1be487d6ecb353d07881526db05d7fc90ea87")
("ht.el" . "1c49aad1c820c86f7ee35bf9fff8429502f60fef") ("hydra" . "9e9e00cb240ea1903ffd36a54956b3902c379d29")
("hydra" . "317e1de33086637579a7aeb60f77ed0405bf359b")
("iedit" . "27c61866b1b9b8d77629ac702e5f48e67dfe0d3b") ("iedit" . "27c61866b1b9b8d77629ac702e5f48e67dfe0d3b")
("impatient-mode" . "a4e4e12852840996b027cb8e9fb2b809c37a0ee3") ("impatient-mode" . "479a2412596ff1dbdddeb7bdbba45482ce5b230c")
("inf-ruby" . "b234625c85a48cc71e7045f5d48f079f410d576a") ("inf-ruby" . "dbf4386bac12f1733257db6105e3f1fca05ffb79")
("inheritenv" . "bac62ca6324828623cf8ce5a3d6aee0fcb65d620") ("inheritenv" . "c2c879acf89682559b157fb069e1da008f4912ea")
("irony-mode" . "40e0ce19eb850bdf1f77225f11713cc816250d95") ("irony-mode" . "870d1576fb279bb93f776a71e65f45283c423a9e")
("jinja2-mode" . "03e5430a7efe1d163a16beaf3c82c5fd2c2caee1") ("jinja2-mode" . "03e5430a7efe1d163a16beaf3c82c5fd2c2caee1")
("js-comint" . "ef2ccccad5740f3d8b5295f52a35df4f62471480") ("js-comint" . "7920252e88eb610add7c9760f7016bb9b884307a")
("json-mode" . "77125b01c0ddce537085201098bea9b4b8ba6be3") ("json-mode" . "eedb4560034f795a7950fa07016bd4347c368873")
("json-snatcher" . "b28d1c0670636da6db508d03872d96ffddbc10f2") ("json-snatcher" . "b28d1c0670636da6db508d03872d96ffddbc10f2")
("let-alist" . "4e05e158612f360f6080b1349d3962b1c8fee902") ("let-alist" . "592553db5929b54db40af0df90c5add0aaca045b")
("lispy" . "fe44efd21573868638ca86fc8313241148fabbe3") ("lispy" . "df1b7e614fb0f73646755343e8892ddda310f427")
("list-utils" . "f02dcef36330871855346f9eab97eef58d323d9a") ("list-utils" . "ca9654cd1418e874c876c6b3b7d4cd8339bfde77")
("lua-mode" . "d074e4134b1beae9ed4c9b512af741ca0d852ba3") ("lua-mode" . "5a9bee8d5fc978dc64fcb677167417010321ba65")
("magit" . "61f6a778ab5b0ca97069778a5955ae527996cd0f") ("magit" . "9b48dd7e3618ac3736f66ef964ae5e1fedd54f98")
("markdown-mode" . "8a7773f87733866a961ea4c518a4a2f283f21970") ("map" . "9f46b9c966505874d68d9036827a4f63b55ab846")
("math-symbol-lists" . "ac3eb053d3b576fcdd192b0ac6ad5090ea3a7079") ("markdown-mode" . "1f709778ac7990f4a07fdf11fe37bc6541810b29")
("melpa" . "a21e230a1e8034076b2a271809ccf613476eeea7") ("math-symbol-lists" . "590d9f09f8ad9aab747b97f077396a2035dcf50f")
("nix-mode" . "719feb7868fb567ecfe5578f6119892c771ac5e5") ("melpa" . "5be08102d4de84c35b18cd1e3321fe8b6836ff56")
("no-littering" . "8b07314d2f0594ff22bf798d9a5f5bf44b4dd4cd") ("no-littering" . "a5aa3faada054f96b70b32ba9d9447f7a4cf403c")
("nongnu-elpa" . "a9a649210a8d8b9295b5a1d0c7b60a77db03c14c")
("org-bullets" . "767f55feb58b840a5a04eabfc3fbbf0d257c4792") ("org-bullets" . "767f55feb58b840a5a04eabfc3fbbf0d257c4792")
("org-ml" . "f57336a9126a168ad32ccce017c072474555395a") ("org-ml" . "f191ebfee6dcf6a05b5d1db43cf75f4a20faa8b4")
("org-ref" . "fd178abf12a85f8e12005d1df683564bdc534124") ("org-ref" . "cbe9e870a5f488cdfc5e6a3b5478845ea8acdcde")
("org-sql" . "43376abf46b897a9a862cfcc1c087f4b8688634c") ("org-sql" . "71b6e01ff94be4c68cfeb17a34518bf1f118cf95")
("org-super-agenda" . "05a710065af5ee4b3982f9619f864f7af12ca1d3") ("org-super-agenda" . "3108bc3f725818f0e868520d2c243abe9acbef4e")
("origami.el" . "e558710a975e8511b9386edc81cd6bdd0a5bda74") ("origami.el" . "e558710a975e8511b9386edc81cd6bdd0a5bda74")
("outline-magic" . "2a5f07417b696cf7541d435c43bafcc64817636b") ("outline-magic" . "2a5f07417b696cf7541d435c43bafcc64817636b")
("ox-pandoc" . "34e6ea97b586e20529d07158a73af3cf33cdd1d5") ("ox-pandoc" . "0a35d0fbfa56bdd9ec5ba5bac2fe002b61c05c52")
("package-lint" . "972dd8403ac8d2d43f298ef89a6b118e49c7355f") ("package-lint" . "622a5a6e853e5a4c7f2b4c53e2ac0edde354b07c")
("paredit" . "037b9b8acbca75151f133b6c0f7f3ff97d9042e5") ("paredit" . "8330a41e8188fe18d3fa805bb9aa529f015318e8")
("parsebib" . "ace9df707108b17759c004c7387655277122d4c1") ("parsebib" . "dd4c5540fa6c2cd990cba324741d7abbc8ed2f23")
("password-store" . "b5e965a838bb68c1227caa2cdd874ba496f10149") ("parseclj" . "1ce54fa2eb7a5d99d34c07d271e18eaabd0489da")
("pcre2el" . "b4d846d80dddb313042131cf2b8fbf647567e000") ("parseedn" . "a67204eeaa32ca8f11f6aeecc2a88349f196add6")
("pdf-tools" . "30b50544e55b8dbf683c2d932d5c33ac73323a16") ("password-store" . "c4d8a1d815e79ddd89a85d3e36a41d29f0475771")
("php-mode" . "59814bd80c59894022bc5950fb3bdf02420e8a89") ("pcre2el" . "0b5b2a2c173aab3fd14aac6cf5e90ad3bf58fa7d")
("pkgbuild-mode" . "8ef396d8fa9187b65c065a6bc2ca15dfaf3255df") ("pdf-tools" . "f9ccdf99e560bae70d3a13325cec9dc0e3cc45b0")
("poly-R" . "8024e852cfca642dea2045a41b2033baa2f1f9a5") ("php-mode" . "4503672471b8fdaaea6c454344817a119c87fcc6")
("poly-markdown" . "98695eb7ca4ca11dcec71a1cab64903bbf79b4d3") ("pkg-info" . "76ba7415480687d05a4353b27fea2ae02b8d9d61")
("pkgbuild-mode" . "8faee70e4640bd6ec1857651ec64e139e4dc2833")
("poly-R" . "e4a39caaf48e1c2e5afab3865644267b10610537")
("poly-markdown" . "d4ca396ec4a7d674ef0d671a6896f929ce5b504c")
("poly-noweb" . "3b0cd36ca9a707e8a09337a3468fa85d81fc461c") ("poly-noweb" . "3b0cd36ca9a707e8a09337a3468fa85d81fc461c")
("polymode" . "ca060e081a1f849a880732670dc15370ac987b89") ("polymode" . "2094c92403fe395dfb2b8b2521da1012a966e9ab")
("popup-el" . "c83d6e5f5fa693e08a542ea9ad7c06eced652de9") ("popup-el" . "976bd8e06100df5a266377d0e5f63b104ba93119")
("powerline" . "c35c35bdf5ce2d992882c1f06f0f078058870d4a") ("powerline" . "566c77844f053cb39fa7acdfbc143a855450f0b5")
("projectile" . "01fb6a5ef023bcfc52b209586dcb4fd13db00218") ("projectile" . "e60883ff370c1545499b97cf56479de1a58c5b3b")
("pythonic" . "c1e5643e044f1faaf6ecfadc719b981c048aeb79") ("pyenv-mode" . "b818901b8eac0e260ced66a6a5acabdbf6f5ba99")
("pythonic" . "fe75bc17baae314bf8f5e0b12aad3fccfc6c5397")
("pyvenv" . "31ea715f2164dd611e7fc77b26390ef3ca93509b") ("pyvenv" . "31ea715f2164dd611e7fc77b26390ef3ca93509b")
("queue" . "8df1334d54d4735d2f821790422a850dfaaa08ef") ("queue" . "130c2d656cd5d7376552272fab9e50a7c37d0c4a")
("rainbow-delimiters" . "f40ece58df8b2f0fb6c8576b527755a552a5e763") ("rainbow-delimiters" . "a32b39bdfe6c61c322c37226d66e1b6d4f107ed0")
("rainbow-mode" . "2e6b18609c2fdd1a2dc513937a64d276fd6cf24c") ("rainbow-mode" . "55a8c15782197cd9db8950d2f5ed1b9caca08dae")
("robe" . "6bc8a07fc483407971de0966d367a11006b3ab80") ("robe" . "11207bd549a5a78e3a4d70265c3715990dcdab71")
("ruby-test-mode" . "d66db4aca6e6a246f65f7195ecfbc7581d35fb7a") ("ruby-test-mode" . "d66db4aca6e6a246f65f7195ecfbc7581d35fb7a")
("rvm.el" . "e1e83b5466c132c066142ac63729ba833c530c83") ("rvm.el" . "c1f2642434b0f68d9baa0687127079ecd884ba12")
("s.el" . "dda84d38fffdaf0c9b12837b504b402af910d01d") ("s.el" . "08661efb075d1c6b4fa812184c1e5e90c08795a9")
("seq" . "da86da9bf111f68fb81efd466d76d53af5aebc00") ("sesman" . "e0f555f963c9f02f8e4a50e06fc353eb4c15ee77")
("snakemake-mode" . "4ad41da69e4b95b38a3d3273874c44caab20cc56") ("snakemake-mode" . "0dfeaff6079558c39081c2c078c41369da01903b")
("spaceline" . "086420d16e526c79b67fc1edec4c2ae1e699f372") ("spaceline" . "9a81afa52738544ad5e8b71308a37422ca7e25ba")
("spacemacs-theme" . "d02edec79404e807445b62d0d2fc1a6fbcc10c71") ("spacemacs-theme" . "bd376f705d6eb7afd9a1dfa0c1bd407e869d1e9f")
("straight.el" . "88e574ae75344e39b436f863ef0344135c7b6517") ("spinner" . "34905eae12a236753fa88abc831eff1e41e8576e")
("string-inflection" . "617df25e91351feffe6aff4d9e4724733449d608") ("straight.el" . "4517e118ee43f849f708025dbb2cf4f281793121")
("sudo-edit" . "74eb1e6986461baed9a9269566ff838530b4379b") ("string-inflection" . "fd7926ac17293e9124b31f706a4e8f38f6a9b855")
("swiper" . "2a25a6fb5b081cb141c5eccac8ee58ab1feeb747") ("sudo-edit" . "23b78a39053088839f281bc0c3134203d7e04e50")
("tablist" . "fcd37147121fabdf003a70279cf86fbe08cfac6f") ("swiper" . "f8d80a4055514f92d94f128f5fcb1cda79e5cd22")
("toc-org" . "6d3ae0fc47ce79b1ea06cabe21a3c596395409cd") ("systemd-mode" . "b6ae63a236605b1c5e1069f7d3afe06ae32a7bae")
("transient" . "3d3f8711d4f6a6ff7f53bc22e465ec82587c62ed") ("tablist" . "faab7a035ef2258cc4ea2182f67e3aedab7e2af9")
("ts.el" . "552936017cfdec89f7fc20c254ae6b37c3f22c5b") ("toc-org" . "bf2e4b358efbd860ecafe6e74776de0885d9d100")
("use-package" . "a6e856418d2ebd053b34e0ab2fda328abeba731c") ("transient" . "2e4426fe8161893382f09b3f4635e152ee02488e")
("with-editor" . "8c550d9e799a0baedb2164471e7ed19fc15d9196") ("ts.el" . "3fee71ceefac71ba55eb34829d7e94bb3df37cee")
("xterm-color" . "2ad407c651e90fff2ea85d17bf074cee2c022912") ("use-package" . "a7422fb8ab1baee19adb2717b5b47b9c3812a84c")
("yaml-mode" . "7b5ce294fb15c2c8926fa476d7218aa415550a2a") ("with-editor" . "4ab8c6148bb2698ff793d4a8acdbd8d0d642e133")
("yasnippet" . "eb5ba2664c3a68ae4a53bb38b85418dd131b208f") ("yaml-mode" . "535273d5a1eb76999d20afbcf4d9f056d8ffd2da")
("yasnippet" . "5cbdbf0d2015540c59ed8ee0fcf4788effdf75b6")
("zoutline" . "32857c6c4b9b0bcbed14d825a10b91a98d5fed0a")) ("zoutline" . "32857c6c4b9b0bcbed14d825a10b91a98d5fed0a"))
:gamma :beta