[org-window-habit] Limit the number of repetitions that actual count per completion window
This commit is contained in:
parent
3ff41f19e5
commit
047e85203a
@ -62,7 +62,8 @@
|
|||||||
(defun org-window-habit-keyed-duration-add-plist (base-time plist)
|
(defun org-window-habit-keyed-duration-add-plist (base-time plist)
|
||||||
(apply 'org-window-habit-keyed-duration-add :base-time base-time plist))
|
(apply 'org-window-habit-keyed-duration-add :base-time base-time plist))
|
||||||
|
|
||||||
(cl-defun org-window-habit-string-duration-to-plist (string-value &key (default nil))
|
(cl-defun org-window-habit-string-duration-to-plist
|
||||||
|
(string-value &key (default nil))
|
||||||
(if (null string-value)
|
(if (null string-value)
|
||||||
default
|
default
|
||||||
(let ((read-value (read string-value)))
|
(let ((read-value (read string-value)))
|
||||||
@ -88,7 +89,8 @@
|
|||||||
(list :hours (string-to-number (match-string 1 string-value))))
|
(list :hours (string-to-number (match-string 1 string-value))))
|
||||||
(t (list :days read-value))))))
|
(t (list :days read-value))))))
|
||||||
|
|
||||||
(defun org-window-habit-normalize-time-to-duration (time-value &optional duration-plist alignment-time)
|
(defun org-window-habit-normalize-time-to-duration
|
||||||
|
(time-value &optional duration-plist alignment-time)
|
||||||
(let* ((alignment-decoded (decode-time (or alignment-time time-value)))
|
(let* ((alignment-decoded (decode-time (or alignment-time time-value)))
|
||||||
(year (nth 5 alignment-decoded))
|
(year (nth 5 alignment-decoded))
|
||||||
(month (nth 4 alignment-decoded))
|
(month (nth 4 alignment-decoded))
|
||||||
@ -174,7 +176,8 @@
|
|||||||
(repetitions-required :initarg :repetitions-required :initform 1)
|
(repetitions-required :initarg :repetitions-required :initform 1)
|
||||||
(okay-repetitions-required :initarg :okay-repetitions-required :initform 1)
|
(okay-repetitions-required :initarg :okay-repetitions-required :initform 1)
|
||||||
(done-times :initarg :done-times :initform nil)
|
(done-times :initarg :done-times :initform nil)
|
||||||
(window-decrement-plist :initarg :window-decrement-plist :initform nil)))
|
(window-decrement-plist :initarg :window-decrement-plist :initform nil)
|
||||||
|
(max-repetitions-per-interval :initarg :max-repetitions-per-interval :initform 1)))
|
||||||
|
|
||||||
(defun org-window-habit-create-instance-from-heading-at-point ()
|
(defun org-window-habit-create-instance-from-heading-at-point ()
|
||||||
"Construct an org-window-habit instance from the current org entry."
|
"Construct an org-window-habit instance from the current org entry."
|
||||||
@ -198,14 +201,18 @@
|
|||||||
(or (org-entry-get nil "REPETITIONS_REQUIRED" t) "1")))
|
(or (org-entry-get nil "REPETITIONS_REQUIRED" t) "1")))
|
||||||
(okay-repetitions-required
|
(okay-repetitions-required
|
||||||
(string-to-number
|
(string-to-number
|
||||||
(or (org-entry-get nil "OKAY_REPETITIONS_REQUIRED" t) "1"))))
|
(or (org-entry-get nil "OKAY_REPETITIONS_REQUIRED" t) "1")))
|
||||||
|
(max-repetitions-per-interval
|
||||||
|
(string-to-number
|
||||||
|
(or (org-entry-get nil "MAX_REPETITIONS_PER_INTERVAL" t) "1"))))
|
||||||
(make-instance 'org-window-habit
|
(make-instance 'org-window-habit
|
||||||
:duration-plist window-length
|
:duration-plist window-length
|
||||||
:assessment-interval assessment-interval
|
:assessment-interval assessment-interval
|
||||||
:reschedule-interval reschedule-interval
|
:reschedule-interval reschedule-interval
|
||||||
:repetitions-required repetitions-required
|
:repetitions-required repetitions-required
|
||||||
:okay-repetitions-required okay-repetitions-required
|
:okay-repetitions-required okay-repetitions-required
|
||||||
:done-times done-times-vector))))
|
:done-times done-times-vector
|
||||||
|
:max-repetitions-per-interval max-repetitions-per-interval))))
|
||||||
|
|
||||||
(cl-defmethod initialize-instance :after ((habit org-window-habit) &rest _args)
|
(cl-defmethod initialize-instance :after ((habit org-window-habit) &rest _args)
|
||||||
(when (null (oref habit assessment-interval))
|
(when (null (oref habit assessment-interval))
|
||||||
@ -313,9 +320,8 @@
|
|||||||
current-window-start
|
current-window-start
|
||||||
(org-window-habit-time-max
|
(org-window-habit-time-max
|
||||||
current-window-start
|
current-window-start
|
||||||
(org-window-habit-find-aligned-bounding-time earliest-completion
|
(org-window-habit-find-aligned-bounding-time
|
||||||
window-decrement-plist
|
earliest-completion window-decrement-plist current-window-end)))
|
||||||
current-window-end)))
|
|
||||||
collect
|
collect
|
||||||
(list current-window-start effective-start current-window-end
|
(list current-window-start effective-start current-window-end
|
||||||
start-index end-index interval-ongoing)
|
start-index end-index interval-ongoing)
|
||||||
@ -431,9 +437,12 @@
|
|||||||
for (start-time actual-start-time end-time start-index end-index interval-ongoing)
|
for (start-time actual-start-time end-time start-index end-index interval-ongoing)
|
||||||
in past-and-present-windows
|
in past-and-present-windows
|
||||||
for duration-proportion =
|
for duration-proportion =
|
||||||
(org-window-habit-duration-proportion start-time end-time actual-start-time)
|
(org-window-habit-duration-proportion
|
||||||
for scaled-repetitions-required = (* duration-proportion repetitions-required)
|
start-time end-time actual-start-time)
|
||||||
for scaled-okay-repetitions-required = (* duration-proportion okay-repetitions-required)
|
for scaled-repetitions-required =
|
||||||
|
(* duration-proportion repetitions-required)
|
||||||
|
for scaled-okay-repetitions-required =
|
||||||
|
(* duration-proportion okay-repetitions-required)
|
||||||
for interval-start-time =
|
for interval-start-time =
|
||||||
(org-window-habit-keyed-duration-add-plist
|
(org-window-habit-keyed-duration-add-plist
|
||||||
end-time window-decrement-plist)
|
end-time window-decrement-plist)
|
||||||
@ -441,6 +450,9 @@
|
|||||||
(org-window-habit-get-completion-window-indices
|
(org-window-habit-get-completion-window-indices
|
||||||
habit interval-start-time end-time
|
habit interval-start-time end-time
|
||||||
:start-index start-index :end-index start-index)
|
:start-index start-index :end-index start-index)
|
||||||
|
for strict-completions =
|
||||||
|
(org-window-habit-get-completion-count
|
||||||
|
habit start-time end-time :start-index start-index)
|
||||||
for total-completions = (- end-index start-index)
|
for total-completions = (- end-index start-index)
|
||||||
for completions-in-interval = (- interval-end-index interval-start-index)
|
for completions-in-interval = (- interval-end-index interval-start-index)
|
||||||
for completions-outside-interval = (- total-completions completions-in-interval)
|
for completions-outside-interval = (- total-completions completions-in-interval)
|
||||||
@ -513,6 +525,30 @@
|
|||||||
(org-window-habit-get-next-required-interval
|
(org-window-habit-get-next-required-interval
|
||||||
(org-window-habit-create-instance-from-heading-at-point))))
|
(org-window-habit-create-instance-from-heading-at-point))))
|
||||||
|
|
||||||
|
(cl-defmethod org-window-habit-get-completion-count
|
||||||
|
((habit org-window-habit) start-time end-time &key (start-index 0))
|
||||||
|
(cl-loop
|
||||||
|
with next-start-index = start-index
|
||||||
|
with interval-end-time = end-time
|
||||||
|
for interval-start-time =
|
||||||
|
;; This is just a sanity check for the case where the interval does not
|
||||||
|
;; evenly divide the window. But you shouldn't do that anyway.
|
||||||
|
(org-window-habit-time-max
|
||||||
|
start-time
|
||||||
|
(org-window-habit-keyed-duration-add-plist
|
||||||
|
interval-end-time (oref habit window-decrement-plist)))
|
||||||
|
for (start-index end-index) =
|
||||||
|
(org-window-habit-get-completion-window-indices
|
||||||
|
habit interval-start-time interval-end-time
|
||||||
|
:start-index next-start-index
|
||||||
|
:end-index next-start-index)
|
||||||
|
for completions-within-interval =
|
||||||
|
(min (oref habit max-repetitions-per-interval) (- end-index start-index))
|
||||||
|
sum completions-within-interval
|
||||||
|
do (setq next-start-index end-index
|
||||||
|
interval-end-time interval-start-time)
|
||||||
|
while (time-less-p start-time interval-start-time)))
|
||||||
|
|
||||||
(cl-defmethod org-window-habit-get-next-required-interval ((habit org-window-habit))
|
(cl-defmethod org-window-habit-get-next-required-interval ((habit org-window-habit))
|
||||||
(cl-loop
|
(cl-loop
|
||||||
with
|
with
|
||||||
@ -532,7 +568,9 @@
|
|||||||
:start-index last-start-index
|
:start-index last-start-index
|
||||||
:end-index last-end-index
|
:end-index last-end-index
|
||||||
:reverse t)
|
:reverse t)
|
||||||
for actual-completions = (- end-index start-index)
|
for actual-completions =
|
||||||
|
(org-window-habit-get-completion-count
|
||||||
|
habit start-time end-time :start-index start-index)
|
||||||
for expected-completions = actual-completions
|
for expected-completions = actual-completions
|
||||||
for actual-start = (org-window-habit-time-max effective-start start-time)
|
for actual-start = (org-window-habit-time-max effective-start start-time)
|
||||||
for proportion =
|
for proportion =
|
||||||
@ -552,10 +590,10 @@
|
|||||||
(message
|
(message
|
||||||
"h: %s %s %s %s %s"
|
"h: %s %s %s %s %s"
|
||||||
interval-has-completion
|
interval-has-completion
|
||||||
reschedule-decrement-plist
|
old-completions
|
||||||
(org-window-habit-show-time-string reschedule-start-time)
|
actual-completions
|
||||||
(org-window-habit-show-time-string end-time)
|
(org-window-habit-show-time-string start-time)
|
||||||
(org-window-habit-show-time-string last-end-time))
|
(org-window-habit-show-time-string end-time))
|
||||||
until (and (not interval-has-completion) (< expected-completions required))
|
until (and (not interval-has-completion) (< expected-completions required))
|
||||||
for (new-start-time new-end-time) =
|
for (new-start-time new-end-time) =
|
||||||
(org-window-habit-advance-window habit start-time end-time)
|
(org-window-habit-advance-window habit start-time end-time)
|
||||||
@ -567,7 +605,6 @@
|
|||||||
last-end-index end-index)
|
last-end-index end-index)
|
||||||
finally return (list last-end-time end-time)))
|
finally return (list last-end-time end-time)))
|
||||||
|
|
||||||
;; TODO: check for completion WITHIN the current interval
|
|
||||||
(defun org-window-habit-auto-repeat (&rest args)
|
(defun org-window-habit-auto-repeat (&rest args)
|
||||||
(interactive)
|
(interactive)
|
||||||
(let* ((required-interval-start
|
(let* ((required-interval-start
|
||||||
|
Loading…
Reference in New Issue
Block a user