Allow repetitions to start from last DONE

This commit is contained in:
Joscha 2021-11-25 01:23:50 +01:00
parent bfbf53784b
commit 11399468e7
4 changed files with 40 additions and 8 deletions

View file

@ -97,6 +97,14 @@ impl DeltaStep {
#[derive(Debug)]
pub struct Delta(pub Vec<DeltaStep>);
#[derive(Debug)]
pub struct Repeat {
/// Start at the date when the latest `DONE` was created instead of the
/// task's previous occurrence.
pub start_at_done: bool,
pub delta: Delta,
}
#[derive(Debug)]
pub struct DateSpec {
pub start: NaiveDate,
@ -105,7 +113,7 @@ pub struct DateSpec {
pub end: Option<NaiveDate>,
pub end_delta: Option<Delta>,
pub end_time: Option<Time>,
pub repeat: Option<Delta>,
pub repeat: Option<Repeat>,
}
#[derive(Debug)]

View file

@ -4,7 +4,7 @@ use chrono::Datelike;
use super::commands::{
Birthday, BirthdaySpec, Command, DateSpec, Delta, DeltaStep, Done, DoneDate, Expr, File,
FormulaSpec, Note, Spec, Task, Time, Var, Weekday, WeekdaySpec,
FormulaSpec, Note, Repeat, Spec, Task, Time, Var, Weekday, WeekdaySpec,
};
fn format_desc(f: &mut fmt::Formatter<'_>, desc: &[String]) -> fmt::Result {
@ -52,6 +52,15 @@ impl fmt::Display for Delta {
}
}
impl fmt::Display for Repeat {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if self.start_at_done {
write!(f, "done ")?;
}
write!(f, "{}", self.delta)
}
}
impl fmt::Display for DateSpec {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
// Start

View file

@ -89,7 +89,8 @@ expr = { term ~ (op ~ term)* }
date_fixed_start = { datum ~ delta? ~ time? }
date_fixed_end = { datum ~ delta? ~ time? | delta ~ time? | time }
date_fixed_repeat = { delta }
repeat_done = { "done" }
date_fixed_repeat = { repeat_done? ~ delta }
date_fixed = { date_fixed_start ~ ("--" ~ date_fixed_end)? ~ (";" ~ date_fixed_repeat)? }
date_expr_start = { ("*" | paren_expr) ~ delta? ~ time? }

View file

@ -7,6 +7,8 @@ use pest::iterators::Pair;
use pest::prec_climber::{Assoc, Operator, PrecClimber};
use pest::{Parser, Span};
use crate::files::commands::Repeat;
use super::commands::{
Birthday, BirthdaySpec, Command, DateSpec, Delta, DeltaStep, Done, DoneDate, Expr, File,
FormulaSpec, Note, Spec, Task, Time, Var, Weekday, WeekdaySpec,
@ -251,13 +253,25 @@ fn parse_date_fixed_end(p: Pair<'_, Rule>, spec: &mut DateSpec) -> Result<()> {
fn parse_date_fixed_repeat(p: Pair<'_, Rule>, spec: &mut DateSpec) -> Result<()> {
assert_eq!(p.as_rule(), Rule::date_fixed_repeat);
let mut p = p.into_inner();
let mut ps = p.into_inner().collect::<Vec<_>>();
if let Some(p) = p.next() {
spec.repeat = Some(parse_delta(p)?);
}
let repeat = match ps.len() {
1 => Repeat {
start_at_done: false,
delta: parse_delta(ps.pop().unwrap())?,
},
2 => {
assert_eq!(ps[0].as_rule(), Rule::repeat_done);
Repeat {
start_at_done: true,
delta: parse_delta(ps.pop().unwrap())?,
}
}
_ => unreachable!(),
};
spec.repeat = Some(repeat);
assert_eq!(p.next(), None);
Ok(())
}