Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 0 additions & 67 deletions docs/routine-tasks-v1.md

This file was deleted.

63 changes: 0 additions & 63 deletions docs/routine-tasks-v2.md

This file was deleted.

4 changes: 3 additions & 1 deletion docs/routine-tasks-v3.md → docs/routine-tasks.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@
3. bi-weekly
4. monthly-on-date
5. monthly-on-weekday (4 weeks)
6. once (one-shot reminder)

## How to store them in markdown
- [ ] {󰃵:d yyyy-mm-dd} daily
- [ ] {󰃵:w yyyy-mm-dd} weekly
- [ ] {󰃵:b yyyy-mm-dd} bi-weekly
- [ ] {󰃵:q yyyy-mm-dd} monthly-on-weekday
- [ ] {󰃵:m yyyy-mm-dd} monthly-on-date
- [ ] {󰃵:1 yyyy-mm-dd} reminder

## Where to save
There will be a dedicated taskbox file, named `ROUTINES.md`, and the structure will be:
Expand All @@ -35,7 +37,7 @@ There will be a dedicated taskbox file, named `ROUTINES.md`, and the structure w

## How to operate on them
* use `add` command to add a new routine task with option, and it will be store in ROUTINES md file with proper *routine-prefix* and current date, available options are:
* `-r/--routine <daily | weekly | biweekly | qweekly | monthly>`
* `-r/--routine <daily | weekly | biweekly | qweekly | monthly | once>`
* add a new command `checkout` to pick up any matched routine tasks to "today" box, with expanded routine info (means "checkout")
* actually its an alias of `collect --inbox routines`
* when to run `today` cli with any command, will have a daily-once hook to run `checkout`
Expand Down
1 change: 1 addition & 0 deletions src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ pub enum Routine {
Biweekly,
Qweekly,
Monthly,
Once,
}

#[derive(Debug, Clone, Subcommand)]
Expand Down
16 changes: 10 additions & 6 deletions src/taskbox.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ lazy_static! {
static ref RE_PREFIX_OPEN :Regex = Regex::new(r"^- \[[ ]\] (.*)").unwrap();
static ref RE_PREFIX_DONE :Regex = Regex::new(r"^- \[[xX\-/<>\*]\] (.*)").unwrap();
static ref RE_ROUTINES :Regex =
Regex::new(r"\{󰃯:([dDwWbBqQmM]) (\d{4}-\d{2}-\d{2})\w{3} 󰳟\} (.*)").unwrap();
Regex::new(r"\{󰃯:([dDwWbBqQmM1]) (\d{4}-\d{2}-\d{2})\w{3} 󰳟\} (.*)").unwrap();
static ref RE_ROUTINES_CHECKOUT :Regex =
Regex::new(r"\{󰃯:(daily|weekly|biweekly|qweekly|monthly)\} (.*)").unwrap();
Regex::new(r"\{󰃯:(daily|weekly|biweekly|qweekly|monthly|reminder)\} (.*)").unwrap();
}

pub const INBOX_BOXNAME :&str = "INBOX";
Expand Down Expand Up @@ -277,6 +277,7 @@ impl TaskBox {
"b" => "biweekly",
"q" => "qweekly",
"m" => "monthly",
"1" => "reminder",
_ => "unknown",
};
let checkout_date = match to.as_ref() {
Expand All @@ -293,6 +294,11 @@ impl TaskBox {
if ! self.tasks.contains(&pair) {
self.tasks.push(pair)
}

// clean up "once reminder"
if kind == "reminder" {
tb_from.tasks.retain(|(_task, _)| _task != &task)
}
} else {
// ignore non-routine task
println!("{} {} : {} {}",
Expand Down Expand Up @@ -329,10 +335,7 @@ impl TaskBox {
}
}

// "ROUTINES" not drain
if from != ROUTINE_BOXNAME {
tb_from._dump().unwrap();
}
tb_from._dump().unwrap();
self._dump().unwrap();
}

Expand All @@ -351,6 +354,7 @@ impl TaskBox {
Routine::Biweekly => "b",
Routine::Qweekly => "q",
Routine::Monthly => "m",
Routine::Once => "1",
},
start_date,
weekday_from_date(start_date),
Expand Down
16 changes: 8 additions & 8 deletions src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@ pub fn weekday_from_date(date_str: &str) -> String {
NaiveDate::parse_from_str(date_str, "%Y-%m-%d").unwrap().weekday().to_string()
}

pub fn match_routine(kind: &str, s_date_str: &str, match_to: &str) -> bool {
let mut s_date = NaiveDate::parse_from_str(s_date_str, "%Y-%m-%d").unwrap();
pub fn match_routine(kind: &str, start_date_str: &str, match_to: &str) -> bool {
let mut closest_date = NaiveDate::parse_from_str(start_date_str, "%Y-%m-%d").unwrap();
let match_to_date = match match_to {
"today" => Local::now().date_naive(),
"yesterday" => Local::now().add(chrono::Duration::days(-1)).date_naive(),
Expand All @@ -72,23 +72,23 @@ pub fn match_routine(kind: &str, s_date_str: &str, match_to: &str) -> bool {
};

if kind == "m" {
while s_date < match_to_date {
s_date = s_date + chrono::Months::new(1);
while closest_date < match_to_date {
closest_date = closest_date + chrono::Months::new(1);
}
} else {
let steps = match kind {
"d" => 1,
"d" | "1" => 1,
"w" => 7,
"b" => 14,
"q" => 28,
_ => panic!("unknown routine kind"),
};
while s_date < match_to_date {
s_date += chrono::Duration::days(steps);
while closest_date < match_to_date {
closest_date += chrono::Duration::days(steps);
}
}

s_date == match_to_date
closest_date == match_to_date
}

pub fn get_box_alias(name_in: &str) -> String {
Expand Down
26 changes: 19 additions & 7 deletions tests/taskbox.rs
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ fn test_collect_from_with_sub_done() {
- [ ] Task2 to move
- [ ] Task3 to move but keep with "done" status
- [ ] SubTask1 to move
- [ ] 󰼈 Task5 to move with warning icon
- [ ] Task5 to move with warning icon
- [ ] SubTask1 to move
- [ ] SubTask3 to move
"#;
Expand Down Expand Up @@ -255,7 +255,7 @@ fn test_collect_from_with_dup_sub() {
- [ ] Task2 to move
- [ ] SubTask1 to move
- [ ] Task3 to move
- [ ] 󰼈 Task4 to move
- [ ] Task4 to move
- [ ] SubTask1 to move
"#;

Expand Down Expand Up @@ -290,28 +290,40 @@ fn test_checkout() {
let mut routine = tb.sibling("routine");

routine.add("Daily routine".to_string(), Some(Routine::Daily), false, &get_today());

// two reminders
routine.add("reminder today".to_string(), Some(Routine::Once), false, &get_today());
routine.add("reminder tomorrow".to_string(), Some(Routine::Once), false, &get_tomorrow());

routine.add("ignore not routine".to_string(), None, false, "");

routine.load();
assert_eq!(routine.tasks.len(), 2);
assert_eq!(routine.tasks.len(), 4);
assert!(routine.tasks[0].0.starts_with("{󰃯:d "));
assert!(routine.tasks[0].0.ends_with("} Daily routine"));
assert!(routine.tasks[1].0.starts_with("{󰃯:1 "));
assert!(routine.tasks[1].0.ends_with("} reminder today"));
assert!(routine.tasks[2].0.starts_with("{󰃯:1 "));
assert!(routine.tasks[2].0.ends_with("} reminder tomorrow"));

today.collect_from(&mut routine);

today.load();
assert_eq!(today.tasks.len(), 1);
assert_eq!(today.tasks.len(), 2);
assert!(today.tasks[0].0.starts_with("{󰃯:daily} "));
assert!(today.tasks[0].0.contains("} Daily routine"));
assert!(today.tasks[0].0.contains(" [󰴹 "));

assert!(today.tasks[1].0.starts_with("{󰃯:reminder} "));
assert!(today.tasks[1].0.contains("} reminder today"));
assert!(today.tasks[1].0.contains(" [󰴹 "));

tb.collect_from(&mut routine);
tb.load();
assert_eq!(tb.tasks.len(), 0);

today.collect_from(&mut routine);
today.load();
assert_eq!(today.tasks.len(), 1);
routine.load();
assert_eq!(routine.tasks.len(), 3);
}

#[test]
Expand Down
Loading