diff --git a/src/eval/command.rs b/src/eval/command.rs index bcafb7c..f2bdd99 100644 --- a/src/eval/command.rs +++ b/src/eval/command.rs @@ -2,7 +2,7 @@ use std::collections::HashMap; use chrono::NaiveDate; -use crate::files::commands::{BirthdaySpec, Command, Done, Note, Spec, Statement, Task}; +use crate::files::commands::{BirthdaySpec, Command, Done, DoneDate, Note, Spec, Statement, Task}; use crate::files::primitives::Span; use crate::files::SourcedCommand; @@ -73,7 +73,20 @@ impl<'a> CommandState<'a> { } } - fn last_done(&self) -> Option { + /// Last root date mentioned in any `DONE`. + fn last_done_root(&self) -> Option { + match self.command.command { + Command::Task(task) => task + .done + .iter() + .filter_map(|done| done.date.map(DoneDate::root)) + .max(), + Command::Note(_) => None, + } + } + + /// Last completion date mentioned in any `DONE`. + fn last_done_completion(&self) -> Option { match self.command.command { Command::Task(task) => task.done.iter().map(|done| done.done_at).max(), Command::Note(_) => None, diff --git a/src/eval/command/date.rs b/src/eval/command/date.rs index f67397e..cc0b726 100644 --- a/src/eval/command/date.rs +++ b/src/eval/command/date.rs @@ -69,11 +69,14 @@ impl DateSpec { fn start_and_range(&self, s: &CommandState<'_>) -> Option<(NaiveDate, DateRange)> { let (start, range) = match s.command.command { Command::Task(_) => { - let last_done = s.last_done(); - let start = last_done + let start = s + .last_done_completion() .filter(|_| self.start_at_done) .unwrap_or(self.start); - let range_from = last_done.map(|date| date.succ()).unwrap_or(self.start); + let range_from = s + .last_done_root() + .map(|date| date.succ()) + .unwrap_or(self.start); let range = s .range .expand_by(&self.end_delta) diff --git a/src/eval/command/formula.rs b/src/eval/command/formula.rs index 974c63e..0e81ca3 100644 --- a/src/eval/command/formula.rs +++ b/src/eval/command/formula.rs @@ -326,8 +326,8 @@ impl FormulaSpec { .move_by(&self.start_delta); if let Command::Task(_) = s.command.command { - if let Some(last_done) = s.last_done() { - range = range.with_from(last_done.succ())?; + if let Some(last_done_root) = s.last_done_root() { + range = range.with_from(last_done_root.succ())?; } // TODO Otherwise, go back one year or so if no FROM is specified } diff --git a/src/files/commands.rs b/src/files/commands.rs index b33fcb5..0669877 100644 --- a/src/files/commands.rs +++ b/src/files/commands.rs @@ -289,6 +289,18 @@ pub enum DoneDate { }, } +impl DoneDate { + pub fn root(self) -> NaiveDate { + match self { + DoneDate::Date { root } => root, + DoneDate::DateTime { root, .. } => root, + DoneDate::DateToDate { root, .. } => root, + DoneDate::DateTimeToTime { root, .. } => root, + DoneDate::DateTimeToDateTime { root, .. } => root, + } + } +} + #[derive(Debug)] pub struct Done { pub date: Option,