Working blocker
This commit is contained in:
@@ -470,7 +470,7 @@ change ~org-directory~. It must be set before org loads!
|
|||||||
(org-agenda-start-day "2026-01-29")
|
(org-agenda-start-day "2026-01-29")
|
||||||
(org-agenda-overriding-header "📅 Installation Bombardier")
|
(org-agenda-overriding-header "📅 Installation Bombardier")
|
||||||
(org-agenda-prefix-format " %12t") ;; reserve time space
|
(org-agenda-prefix-format " %12t") ;; reserve time space
|
||||||
(org-agenda-todo-keyword-format " %-12s ") ;; fixed-width TODO
|
(org-agenda-todo-keyword-format " %-5s") ;; fixed-width TODO
|
||||||
(org-agenda-tags-column -100) ;; right-align tags
|
(org-agenda-tags-column -100) ;; right-align tags
|
||||||
(org-agenda-time-grid nil)
|
(org-agenda-time-grid nil)
|
||||||
)))
|
)))
|
||||||
@@ -2248,6 +2248,29 @@ If FILE is nil, refile in the current file."
|
|||||||
(nthcdr 3 (decode-time next)))))))
|
(nthcdr 3 (decode-time next)))))))
|
||||||
(t t1))))
|
(t t1))))
|
||||||
|
|
||||||
|
(defun gortium/org--get-range-end (pos)
|
||||||
|
"Extract the END timestamp from an existing range like <A>--<B> at POS.
|
||||||
|
POS can be a marker or a cons cell (file . position)."
|
||||||
|
(let ((marker (if (markerp pos) pos
|
||||||
|
(let ((file (car pos))
|
||||||
|
(p (cdr pos)))
|
||||||
|
(with-current-buffer (find-file-noselect file)
|
||||||
|
(copy-marker p))))))
|
||||||
|
(with-current-buffer (marker-buffer marker)
|
||||||
|
(save-excursion
|
||||||
|
(goto-char marker)
|
||||||
|
(org-back-to-heading t)
|
||||||
|
(let ((subtree-end (save-excursion (org-end-of-subtree t) (point)))
|
||||||
|
(end-time nil))
|
||||||
|
(save-restriction
|
||||||
|
(narrow-to-region (point) subtree-end)
|
||||||
|
(goto-char (point-min))
|
||||||
|
(when (re-search-forward "<[^>]+>--<\\([^>]+\\)>" nil t)
|
||||||
|
(condition-case nil
|
||||||
|
(setq end-time (org-time-string-to-time (match-string 1)))
|
||||||
|
(error nil))))
|
||||||
|
end-time)))))
|
||||||
|
|
||||||
(defun gortium/org--get-range-start (pos)
|
(defun gortium/org--get-range-start (pos)
|
||||||
"Extract the start timestamp from an existing range like <A>--<B>.
|
"Extract the start timestamp from an existing range like <A>--<B>.
|
||||||
Returns nil if no range found (safe, non-blocking)."
|
Returns nil if no range found (safe, non-blocking)."
|
||||||
@@ -2321,7 +2344,7 @@ Returns nil if no range found (safe, non-blocking)."
|
|||||||
;; Helper: Find dependency end time
|
;; Helper: Find dependency end time
|
||||||
;; ------------------------------------------------------------
|
;; ------------------------------------------------------------
|
||||||
(defun gortium/internal--get-blocker-end (blocker-str task-end-map)
|
(defun gortium/internal--get-blocker-end (blocker-str task-end-map)
|
||||||
"Return latest end time only if blockers are DONE or have been recalculated."
|
"Return the latest end time of all blockers if they are all resolved."
|
||||||
(let ((clean (s-trim (format "%s" blocker-str)))
|
(let ((clean (s-trim (format "%s" blocker-str)))
|
||||||
(latest-time nil)
|
(latest-time nil)
|
||||||
(all-resolved t))
|
(all-resolved t))
|
||||||
@@ -2329,23 +2352,29 @@ Returns nil if no range found (safe, non-blocking)."
|
|||||||
(not (string-empty-p (s-trim (match-string 1 clean)))))
|
(not (string-empty-p (s-trim (match-string 1 clean)))))
|
||||||
(dolist (tid (split-string (match-string 1 clean) "[ ,]+" t))
|
(dolist (tid (split-string (match-string 1 clean) "[ ,]+" t))
|
||||||
(let* ((clean-id (replace-regexp-in-string "[\"']\\|id:" "" tid))
|
(let* ((clean-id (replace-regexp-in-string "[\"']\\|id:" "" tid))
|
||||||
(pos (org-id-find clean-id t))
|
(pos (org-id-find clean-id t)) ;; Returns marker OR (file . pos)
|
||||||
(computed-end (gethash clean-id task-end-map))
|
(computed-end (gethash clean-id task-end-map))
|
||||||
(blocker-end
|
(blocker-end
|
||||||
(cond
|
(cond
|
||||||
;; 1) Use the new time we just calculated in this run (Priority!)
|
|
||||||
(computed-end computed-end)
|
(computed-end computed-end)
|
||||||
|
|
||||||
;; 2) If it's DONE, use the CLOSED timestamp
|
;; Use a temporary buffer context to check properties if pos is a list
|
||||||
((and pos (org-entry-get pos "CLOSED"))
|
((and pos (let ((m (if (markerp pos) pos (set-marker (make-marker) (cdr pos) (find-file-noselect (car pos))))))
|
||||||
(org-time-string-to-time (org-entry-get pos "CLOSED")))
|
(with-current-buffer (marker-buffer m)
|
||||||
|
(org-with-point-at m
|
||||||
;; 3) If it's FIXED, use the existing range/scheduled time
|
(cond
|
||||||
((and pos (string-equal "t" (org-entry-get pos "FIXED")))
|
((org-entry-get nil "CLOSED")
|
||||||
(or (gortium/org--get-range-start pos) ;; Note: This needs range end logic, but start is a fallback
|
(org-time-string-to-time (org-entry-get nil "CLOSED")))
|
||||||
(org-get-scheduled-time pos)))
|
((string-equal "t" (org-entry-get nil "FIXED"))
|
||||||
|
(gortium/org--get-range-end m))
|
||||||
;; Otherwise: We MUST wait for this blocker to be recalculated
|
(t nil))))))
|
||||||
|
;; This captures the result of the let/with-current-buffer block
|
||||||
|
(let ((m (if (markerp pos) pos (set-marker (make-marker) (cdr pos) (find-file-noselect (car pos))))))
|
||||||
|
(with-current-buffer (marker-buffer m)
|
||||||
|
(org-with-point-at m
|
||||||
|
(if (org-entry-get nil "CLOSED")
|
||||||
|
(org-time-string-to-time (org-entry-get nil "CLOSED"))
|
||||||
|
(gortium/org--get-range-end m))))))
|
||||||
(t nil))))
|
(t nil))))
|
||||||
|
|
||||||
(if blocker-end
|
(if blocker-end
|
||||||
@@ -2485,17 +2514,16 @@ Returns list of task IDs involved in cycles, or nil if no cycles found."
|
|||||||
|
|
||||||
;; --- MAIN SCHEDULER ---
|
;; --- MAIN SCHEDULER ---
|
||||||
(defun gortium/org-schedule-subtree-chains ()
|
(defun gortium/org-schedule-subtree-chains ()
|
||||||
"Optimized scheduler: Ignores stale buffer ranges to ensure correct dependency flow."
|
"Standard Gortium scheduler: Correctly calculates Finish-to-Start dependencies."
|
||||||
(interactive)
|
(interactive)
|
||||||
(message "=== Starting Gortium Scheduler ===")
|
(message "=== Starting Gortium Scheduler ===")
|
||||||
|
|
||||||
;; 1. Global deactivations to prevent the "Parser Error"
|
(let ((all-tasks '())
|
||||||
(let ((org-element-use-cache nil)
|
|
||||||
(all-tasks '())
|
|
||||||
(task-end-times (make-hash-table :test 'equal))
|
(task-end-times (make-hash-table :test 'equal))
|
||||||
(start-time (current-time)))
|
(start-time (current-time))
|
||||||
|
(org-element-use-cache nil)) ;; Disable buggy cache
|
||||||
|
|
||||||
;; 2. COLLECTION
|
;; 1. COLLECT
|
||||||
(org-map-entries
|
(org-map-entries
|
||||||
(lambda ()
|
(lambda ()
|
||||||
(when (org-get-todo-state)
|
(when (org-get-todo-state)
|
||||||
@@ -2512,7 +2540,7 @@ Returns list of task IDs involved in cycles, or nil if no cycles found."
|
|||||||
|
|
||||||
(setq all-tasks (nreverse all-tasks))
|
(setq all-tasks (nreverse all-tasks))
|
||||||
|
|
||||||
;; 3. THE LOOP
|
;; 2. ITERATE
|
||||||
(let* ((remaining all-tasks)
|
(let* ((remaining all-tasks)
|
||||||
(limit (* 20 (length remaining)))
|
(limit (* 20 (length remaining)))
|
||||||
(iter 0))
|
(iter 0))
|
||||||
@@ -2524,7 +2552,6 @@ Returns list of task IDs involved in cycles, or nil if no cycles found."
|
|||||||
(pcase-let ((`(,buf ,pos ,id ,effort ,blocker ,fixed ,sched ,offset) task))
|
(pcase-let ((`(,buf ,pos ,id ,effort ,blocker ,fixed ,sched ,offset) task))
|
||||||
(let* ((blocker-end (gortium/internal--get-blocker-end blocker task-end-times))
|
(let* ((blocker-end (gortium/internal--get-blocker-end blocker task-end-times))
|
||||||
(has-blocker (and blocker (not (string-empty-p (s-trim blocker)))))
|
(has-blocker (and blocker (not (string-empty-p (s-trim blocker)))))
|
||||||
;; A task is ready if it's FIXED or all blockers are in the task-end-times map
|
|
||||||
(is-fixed (string-equal fixed "t"))
|
(is-fixed (string-equal fixed "t"))
|
||||||
(ready (or is-fixed (not has-blocker) blocker-end)))
|
(ready (or is-fixed (not has-blocker) blocker-end)))
|
||||||
|
|
||||||
@@ -2532,10 +2559,15 @@ Returns list of task IDs involved in cycles, or nil if no cycles found."
|
|||||||
(with-current-buffer buf
|
(with-current-buffer buf
|
||||||
(org-element-with-disabled-cache
|
(org-element-with-disabled-cache
|
||||||
(let* ((off-days (if (stringp offset) (string-to-number offset) 0))
|
(let* ((off-days (if (stringp offset) (string-to-number offset) 0))
|
||||||
|
;; CRITICAL: For fixed tasks, base-start is THEIR start.
|
||||||
|
;; For dependent tasks, base-start is the blocker's END.
|
||||||
(base-start (cond (is-fixed (or (gortium/org--get-range-start pos) sched (current-time)))
|
(base-start (cond (is-fixed (or (gortium/org--get-range-start pos) sched (current-time)))
|
||||||
(t (or blocker-end sched (current-time)))))
|
(t (or blocker-end (or sched (current-time))))))
|
||||||
|
|
||||||
(final-start (if is-fixed base-start
|
(final-start (if is-fixed base-start
|
||||||
(gortium/internal--snap-to-working-hours (time-add base-start (days-to-time off-days)))))
|
(gortium/internal--snap-to-working-hours
|
||||||
|
(time-add base-start (days-to-time off-days)))))
|
||||||
|
|
||||||
(span (gortium/internal--calculate-task-span final-start effort))
|
(span (gortium/internal--calculate-task-span final-start effort))
|
||||||
(final-end (car span))
|
(final-end (car span))
|
||||||
(wknd (cadr span)))
|
(wknd (cadr span)))
|
||||||
@@ -2544,10 +2576,11 @@ Returns list of task IDs involved in cycles, or nil if no cycles found."
|
|||||||
(push task done-this-loop))))))))
|
(push task done-this-loop))))))))
|
||||||
(setq remaining (cl-set-difference remaining done-this-loop))))
|
(setq remaining (cl-set-difference remaining done-this-loop))))
|
||||||
|
|
||||||
|
;; 3. CLEANUP
|
||||||
|
(setq org-element-use-cache t)
|
||||||
(org-element-cache-reset 'all)
|
(org-element-cache-reset 'all)
|
||||||
(message "=== Scheduler completed (%d tasks, %d iterations) ===" (length all-tasks) iter))))
|
(message "=== Scheduler completed (%d tasks, %d iterations) ===" (length all-tasks) iter))))
|
||||||
|
|
||||||
|
|
||||||
;; ---------------------------------------------
|
;; ---------------------------------------------
|
||||||
(defun gortium/org-ensure-task-properties ()
|
(defun gortium/org-ensure-task-properties ()
|
||||||
"Iterate through all tasks (TODO, NEXT, STRT, WAIT, HOLD, DONE, etc.)
|
"Iterate through all tasks (TODO, NEXT, STRT, WAIT, HOLD, DONE, etc.)
|
||||||
|
|||||||
@@ -340,7 +340,7 @@
|
|||||||
(org-agenda-start-day "2026-01-29")
|
(org-agenda-start-day "2026-01-29")
|
||||||
(org-agenda-overriding-header "📅 Installation Bombardier")
|
(org-agenda-overriding-header "📅 Installation Bombardier")
|
||||||
(org-agenda-prefix-format " %12t") ;; reserve time space
|
(org-agenda-prefix-format " %12t") ;; reserve time space
|
||||||
(org-agenda-todo-keyword-format " %-12s ") ;; fixed-width TODO
|
(org-agenda-todo-keyword-format " %-5s") ;; fixed-width TODO
|
||||||
(org-agenda-tags-column -100) ;; right-align tags
|
(org-agenda-tags-column -100) ;; right-align tags
|
||||||
(org-agenda-time-grid nil)
|
(org-agenda-time-grid nil)
|
||||||
)))
|
)))
|
||||||
@@ -1594,6 +1594,29 @@ If FILE is nil, refile in the current file."
|
|||||||
(nthcdr 3 (decode-time next)))))))
|
(nthcdr 3 (decode-time next)))))))
|
||||||
(t t1))))
|
(t t1))))
|
||||||
|
|
||||||
|
(defun gortium/org--get-range-end (pos)
|
||||||
|
"Extract the END timestamp from an existing range like <A>--<B> at POS.
|
||||||
|
POS can be a marker or a cons cell (file . position)."
|
||||||
|
(let ((marker (if (markerp pos) pos
|
||||||
|
(let ((file (car pos))
|
||||||
|
(p (cdr pos)))
|
||||||
|
(with-current-buffer (find-file-noselect file)
|
||||||
|
(copy-marker p))))))
|
||||||
|
(with-current-buffer (marker-buffer marker)
|
||||||
|
(save-excursion
|
||||||
|
(goto-char marker)
|
||||||
|
(org-back-to-heading t)
|
||||||
|
(let ((subtree-end (save-excursion (org-end-of-subtree t) (point)))
|
||||||
|
(end-time nil))
|
||||||
|
(save-restriction
|
||||||
|
(narrow-to-region (point) subtree-end)
|
||||||
|
(goto-char (point-min))
|
||||||
|
(when (re-search-forward "<[^>]+>--<\\([^>]+\\)>" nil t)
|
||||||
|
(condition-case nil
|
||||||
|
(setq end-time (org-time-string-to-time (match-string 1)))
|
||||||
|
(error nil))))
|
||||||
|
end-time)))))
|
||||||
|
|
||||||
(defun gortium/org--get-range-start (pos)
|
(defun gortium/org--get-range-start (pos)
|
||||||
"Extract the start timestamp from an existing range like <A>--<B>.
|
"Extract the start timestamp from an existing range like <A>--<B>.
|
||||||
Returns nil if no range found (safe, non-blocking)."
|
Returns nil if no range found (safe, non-blocking)."
|
||||||
@@ -1667,7 +1690,7 @@ Returns nil if no range found (safe, non-blocking)."
|
|||||||
;; Helper: Find dependency end time
|
;; Helper: Find dependency end time
|
||||||
;; ------------------------------------------------------------
|
;; ------------------------------------------------------------
|
||||||
(defun gortium/internal--get-blocker-end (blocker-str task-end-map)
|
(defun gortium/internal--get-blocker-end (blocker-str task-end-map)
|
||||||
"Return latest end time only if blockers are DONE or have been recalculated."
|
"Return the latest end time of all blockers if they are all resolved."
|
||||||
(let ((clean (s-trim (format "%s" blocker-str)))
|
(let ((clean (s-trim (format "%s" blocker-str)))
|
||||||
(latest-time nil)
|
(latest-time nil)
|
||||||
(all-resolved t))
|
(all-resolved t))
|
||||||
@@ -1675,23 +1698,29 @@ Returns nil if no range found (safe, non-blocking)."
|
|||||||
(not (string-empty-p (s-trim (match-string 1 clean)))))
|
(not (string-empty-p (s-trim (match-string 1 clean)))))
|
||||||
(dolist (tid (split-string (match-string 1 clean) "[ ,]+" t))
|
(dolist (tid (split-string (match-string 1 clean) "[ ,]+" t))
|
||||||
(let* ((clean-id (replace-regexp-in-string "[\"']\\|id:" "" tid))
|
(let* ((clean-id (replace-regexp-in-string "[\"']\\|id:" "" tid))
|
||||||
(pos (org-id-find clean-id t))
|
(pos (org-id-find clean-id t)) ;; Returns marker OR (file . pos)
|
||||||
(computed-end (gethash clean-id task-end-map))
|
(computed-end (gethash clean-id task-end-map))
|
||||||
(blocker-end
|
(blocker-end
|
||||||
(cond
|
(cond
|
||||||
;; 1) Use the new time we just calculated in this run (Priority!)
|
|
||||||
(computed-end computed-end)
|
(computed-end computed-end)
|
||||||
|
|
||||||
;; 2) If it's DONE, use the CLOSED timestamp
|
;; Use a temporary buffer context to check properties if pos is a list
|
||||||
((and pos (org-entry-get pos "CLOSED"))
|
((and pos (let ((m (if (markerp pos) pos (set-marker (make-marker) (cdr pos) (find-file-noselect (car pos))))))
|
||||||
(org-time-string-to-time (org-entry-get pos "CLOSED")))
|
(with-current-buffer (marker-buffer m)
|
||||||
|
(org-with-point-at m
|
||||||
;; 3) If it's FIXED, use the existing range/scheduled time
|
(cond
|
||||||
((and pos (string-equal "t" (org-entry-get pos "FIXED")))
|
((org-entry-get nil "CLOSED")
|
||||||
(or (gortium/org--get-range-start pos) ;; Note: This needs range end logic, but start is a fallback
|
(org-time-string-to-time (org-entry-get nil "CLOSED")))
|
||||||
(org-get-scheduled-time pos)))
|
((string-equal "t" (org-entry-get nil "FIXED"))
|
||||||
|
(gortium/org--get-range-end m))
|
||||||
;; Otherwise: We MUST wait for this blocker to be recalculated
|
(t nil))))))
|
||||||
|
;; This captures the result of the let/with-current-buffer block
|
||||||
|
(let ((m (if (markerp pos) pos (set-marker (make-marker) (cdr pos) (find-file-noselect (car pos))))))
|
||||||
|
(with-current-buffer (marker-buffer m)
|
||||||
|
(org-with-point-at m
|
||||||
|
(if (org-entry-get nil "CLOSED")
|
||||||
|
(org-time-string-to-time (org-entry-get nil "CLOSED"))
|
||||||
|
(gortium/org--get-range-end m))))))
|
||||||
(t nil))))
|
(t nil))))
|
||||||
|
|
||||||
(if blocker-end
|
(if blocker-end
|
||||||
@@ -1831,17 +1860,16 @@ Returns list of task IDs involved in cycles, or nil if no cycles found."
|
|||||||
|
|
||||||
;; --- MAIN SCHEDULER ---
|
;; --- MAIN SCHEDULER ---
|
||||||
(defun gortium/org-schedule-subtree-chains ()
|
(defun gortium/org-schedule-subtree-chains ()
|
||||||
"Optimized scheduler: Ignores stale buffer ranges to ensure correct dependency flow."
|
"Standard Gortium scheduler: Correctly calculates Finish-to-Start dependencies."
|
||||||
(interactive)
|
(interactive)
|
||||||
(message "=== Starting Gortium Scheduler ===")
|
(message "=== Starting Gortium Scheduler ===")
|
||||||
|
|
||||||
;; 1. Global deactivations to prevent the "Parser Error"
|
(let ((all-tasks '())
|
||||||
(let ((org-element-use-cache nil)
|
|
||||||
(all-tasks '())
|
|
||||||
(task-end-times (make-hash-table :test 'equal))
|
(task-end-times (make-hash-table :test 'equal))
|
||||||
(start-time (current-time)))
|
(start-time (current-time))
|
||||||
|
(org-element-use-cache nil)) ;; Disable buggy cache
|
||||||
|
|
||||||
;; 2. COLLECTION
|
;; 1. COLLECT
|
||||||
(org-map-entries
|
(org-map-entries
|
||||||
(lambda ()
|
(lambda ()
|
||||||
(when (org-get-todo-state)
|
(when (org-get-todo-state)
|
||||||
@@ -1858,7 +1886,7 @@ Returns list of task IDs involved in cycles, or nil if no cycles found."
|
|||||||
|
|
||||||
(setq all-tasks (nreverse all-tasks))
|
(setq all-tasks (nreverse all-tasks))
|
||||||
|
|
||||||
;; 3. THE LOOP
|
;; 2. ITERATE
|
||||||
(let* ((remaining all-tasks)
|
(let* ((remaining all-tasks)
|
||||||
(limit (* 20 (length remaining)))
|
(limit (* 20 (length remaining)))
|
||||||
(iter 0))
|
(iter 0))
|
||||||
@@ -1870,7 +1898,6 @@ Returns list of task IDs involved in cycles, or nil if no cycles found."
|
|||||||
(pcase-let ((`(,buf ,pos ,id ,effort ,blocker ,fixed ,sched ,offset) task))
|
(pcase-let ((`(,buf ,pos ,id ,effort ,blocker ,fixed ,sched ,offset) task))
|
||||||
(let* ((blocker-end (gortium/internal--get-blocker-end blocker task-end-times))
|
(let* ((blocker-end (gortium/internal--get-blocker-end blocker task-end-times))
|
||||||
(has-blocker (and blocker (not (string-empty-p (s-trim blocker)))))
|
(has-blocker (and blocker (not (string-empty-p (s-trim blocker)))))
|
||||||
;; A task is ready if it's FIXED or all blockers are in the task-end-times map
|
|
||||||
(is-fixed (string-equal fixed "t"))
|
(is-fixed (string-equal fixed "t"))
|
||||||
(ready (or is-fixed (not has-blocker) blocker-end)))
|
(ready (or is-fixed (not has-blocker) blocker-end)))
|
||||||
|
|
||||||
@@ -1878,10 +1905,15 @@ Returns list of task IDs involved in cycles, or nil if no cycles found."
|
|||||||
(with-current-buffer buf
|
(with-current-buffer buf
|
||||||
(org-element-with-disabled-cache
|
(org-element-with-disabled-cache
|
||||||
(let* ((off-days (if (stringp offset) (string-to-number offset) 0))
|
(let* ((off-days (if (stringp offset) (string-to-number offset) 0))
|
||||||
|
;; CRITICAL: For fixed tasks, base-start is THEIR start.
|
||||||
|
;; For dependent tasks, base-start is the blocker's END.
|
||||||
(base-start (cond (is-fixed (or (gortium/org--get-range-start pos) sched (current-time)))
|
(base-start (cond (is-fixed (or (gortium/org--get-range-start pos) sched (current-time)))
|
||||||
(t (or blocker-end sched (current-time)))))
|
(t (or blocker-end (or sched (current-time))))))
|
||||||
|
|
||||||
(final-start (if is-fixed base-start
|
(final-start (if is-fixed base-start
|
||||||
(gortium/internal--snap-to-working-hours (time-add base-start (days-to-time off-days)))))
|
(gortium/internal--snap-to-working-hours
|
||||||
|
(time-add base-start (days-to-time off-days)))))
|
||||||
|
|
||||||
(span (gortium/internal--calculate-task-span final-start effort))
|
(span (gortium/internal--calculate-task-span final-start effort))
|
||||||
(final-end (car span))
|
(final-end (car span))
|
||||||
(wknd (cadr span)))
|
(wknd (cadr span)))
|
||||||
@@ -1890,10 +1922,11 @@ Returns list of task IDs involved in cycles, or nil if no cycles found."
|
|||||||
(push task done-this-loop))))))))
|
(push task done-this-loop))))))))
|
||||||
(setq remaining (cl-set-difference remaining done-this-loop))))
|
(setq remaining (cl-set-difference remaining done-this-loop))))
|
||||||
|
|
||||||
|
;; 3. CLEANUP
|
||||||
|
(setq org-element-use-cache t)
|
||||||
(org-element-cache-reset 'all)
|
(org-element-cache-reset 'all)
|
||||||
(message "=== Scheduler completed (%d tasks, %d iterations) ===" (length all-tasks) iter))))
|
(message "=== Scheduler completed (%d tasks, %d iterations) ===" (length all-tasks) iter))))
|
||||||
|
|
||||||
|
|
||||||
;; ---------------------------------------------
|
;; ---------------------------------------------
|
||||||
(defun gortium/org-ensure-task-properties ()
|
(defun gortium/org-ensure-task-properties ()
|
||||||
"Iterate through all tasks (TODO, NEXT, STRT, WAIT, HOLD, DONE, etc.)
|
"Iterate through all tasks (TODO, NEXT, STRT, WAIT, HOLD, DONE, etc.)
|
||||||
|
|||||||
Reference in New Issue
Block a user