diff --git a/src/cli.rs b/src/cli.rs index b4a1273..ea2a550 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -25,8 +25,8 @@ pub fn run() -> anyhow::Result<()> { let now = files.now().naive_local(); let range = DateRange::new( - NaiveDate::from_ymd(2021, 1, 1), - NaiveDate::from_ymd(2022, 12, 31), + NaiveDate::from_ymd(2021, 12, 12 - 3), + NaiveDate::from_ymd(2021, 12, 12 + 13), ) .unwrap(); diff --git a/src/eval/command.rs b/src/eval/command.rs index c514b27..53b85f6 100644 --- a/src/eval/command.rs +++ b/src/eval/command.rs @@ -25,7 +25,20 @@ pub struct CommandState<'a> { } impl<'a> CommandState<'a> { - pub fn new(command: SourcedCommand<'a>, range: DateRange) -> Self { + pub fn new(command: SourcedCommand<'a>, mut range: DateRange) -> Self { + // If we don't calculate entries for the source of the move command, it + // fails even though the user did nothing wrong. Also, move commands (or + // chains thereof) may move an initially out-of-range entry into range. + // + // To fix this, we just expand the range to contain all move command + // sources. This is a quick fix, but until it becomes a performance + // issue (if ever), it's probably fine. + for statement in command.command.statements() { + if let Statement::Move { from, .. } = statement { + range = range.containing(*from) + } + } + Self { range, command, diff --git a/src/eval/range.rs b/src/eval/range.rs index 60cc87d..1fb924c 100644 --- a/src/eval/range.rs +++ b/src/eval/range.rs @@ -28,6 +28,22 @@ impl DateRange { Self::new(self.from, until) } + pub fn containing(&self, date: NaiveDate) -> Self { + if date < self.from { + Self { + from: date, + until: self.until, + } + } else if self.until < date { + Self { + from: self.from, + until: date, + } + } else { + *self + } + } + pub fn contains(&self, date: NaiveDate) -> bool { self.from <= date && date <= self.until } diff --git a/src/files/commands.rs b/src/files/commands.rs index dbdf755..ccb43e9 100644 --- a/src/files/commands.rs +++ b/src/files/commands.rs @@ -325,6 +325,13 @@ impl Command { Self::Note(note) => ¬e.desc, } } + + pub fn statements(&self) -> &[Statement] { + match self { + Self::Task(task) => &task.statements, + Self::Note(note) => ¬e.statements, + } + } } #[derive(Debug)]