diff --git a/.todos.json b/.todos.json index 726fc954..e2adb36d 100644 --- a/.todos.json +++ b/.todos.json @@ -1 +1 @@ -[{"id":1,"subject":"support for priorities +feature","projects":["feature"],"contexts":[],"due":"2016-07-08","completed":false,"archived":false},{"id":2,"subject":"fix bug with 'tod' not being recognized +bug","projects":["bug"],"contexts":[],"due":"2016-07-08","completed":false,"archived":false},{"id":3,"subject":"separate into packages/directories +refactor","projects":["refactor"],"contexts":[],"due":"2016-07-08","completed":false,"archived":false},{"id":4,"subject":"+documentation re-record how it works using this https://asciinema.org/","projects":["documentation"],"contexts":[],"due":"","completed":false,"archived":false},{"id":5,"subject":"+slideplayer nice quote support","projects":["slideplayer"],"contexts":[],"due":"","completed":false,"archived":false},{"id":6,"subject":"+slideplayer image filters using css3","projects":["slideplayer"],"contexts":[],"due":"","completed":false,"archived":false},{"id":7,"subject":"+slideplayer syntax highlighting and code blocks","projects":["slideplayer"],"contexts":[],"due":"","completed":false,"archived":false},{"id":8,"subject":"+slideplayer presenter notes","projects":["slideplayer"],"contexts":[],"due":"","completed":false,"archived":false}] +[{"id":1,"uuid":"fc042e14-af67-4a04-942b-2e1f9dbc0356","subject":"support for priorities +feature","projects":["feature"],"contexts":[],"due":"2016-07-08","completed":false,"completed_date":"","status":"","archived":false,"is_priority":false,"notes":null,"recur":"","recur_until":"","prev_recur_todo_uuid":""},{"id":2,"uuid":"54433144-48e2-47f8-ac0c-4ac639ee9b22","subject":"fix bug with 'tod' not being recognized +bug","projects":["bug"],"contexts":[],"due":"2016-07-08","completed":false,"completed_date":"","status":"","archived":false,"is_priority":false,"notes":null,"recur":"","recur_until":"","prev_recur_todo_uuid":""},{"id":3,"uuid":"840b15f2-8b36-4014-963e-345f5f2469ba","subject":"separate into packages/directories +refactor","projects":["refactor"],"contexts":[],"due":"2016-07-08","completed":false,"completed_date":"","status":"","archived":false,"is_priority":false,"notes":null,"recur":"","recur_until":"","prev_recur_todo_uuid":""},{"id":5,"uuid":"2d78386b-6a4f-4c06-af35-b03238367c40","subject":"+slideplayer nice quote support","projects":["slideplayer"],"contexts":[],"due":"2021-10-15","completed":false,"completed_date":"","status":"","archived":false,"is_priority":false,"notes":null,"recur":"","recur_until":"","prev_recur_todo_uuid":""},{"id":6,"uuid":"e7397190-5fc4-4171-ac5d-37ae5f5e3b43","subject":"+slideplayer image filters using css3","projects":["slideplayer"],"contexts":[],"due":"2021-10-14","completed":false,"completed_date":"","status":"","archived":false,"is_priority":false,"notes":null,"recur":"","recur_until":"","prev_recur_todo_uuid":""},{"id":7,"uuid":"67b040ac-58e0-4564-a660-5c98c64ec558","subject":"+slideplayer syntax highlighting and code blocks","projects":["slideplayer"],"contexts":[],"due":"2021-10-17","completed":false,"completed_date":"","status":"","archived":false,"is_priority":false,"notes":null,"recur":"","recur_until":"","prev_recur_todo_uuid":""},{"id":8,"uuid":"8d4c3e33-84a0-4d18-ba26-27ed9d227995","subject":"+slideplayer presenter notes","projects":["slideplayer"],"contexts":[],"due":"","completed":false,"completed_date":"","status":"","archived":false,"is_priority":false,"notes":null,"recur":"","recur_until":"","prev_recur_todo_uuid":""},{"id":4,"uuid":"42854747-3ac0-4a48-a982-96ce260d2d64","subject":"+documentation re-record how it works using this https://asciinema.org/","projects":["documentation"],"contexts":[],"due":"","completed":true,"completed_date":"2021-10-14T15:56:31-07:00","status":"completed","archived":false,"is_priority":false,"notes":null,"recur":"","recur_until":"","prev_recur_todo_uuid":""},{"id":9,"uuid":"6cd80ec3-27ab-4709-bf50-38938b7ad09a","subject":"Read LOTR","projects":[],"contexts":[],"due":"2021-10-18","completed":false,"completed_date":"","status":"","archived":false,"is_priority":false,"notes":null,"recur":"","recur_until":"","prev_recur_todo_uuid":""},{"id":10,"uuid":"80a21fbc-6187-4dac-80d0-a6523cc82cb8","subject":"Read Harry Potter","projects":[],"contexts":[],"due":"2021-10-04","completed":false,"completed_date":"","status":"","archived":false,"is_priority":false,"notes":null,"recur":"","recur_until":"","prev_recur_todo_uuid":""},{"id":11,"uuid":"c307fd4d-00b7-44ec-bceb-da57dbb9fd4f","subject":"Read Wheel of Time","projects":[],"contexts":[],"due":"2021-10-19","completed":false,"completed_date":"","status":"","archived":false,"is_priority":false,"notes":null,"recur":"","recur_until":"","prev_recur_todo_uuid":""},{"id":12,"uuid":"e9b47668-a699-4503-9a37-124ad433c29e","subject":"Read Game of Thrones","projects":[],"contexts":[],"due":"2021-09-01","completed":false,"completed_date":"","status":"","archived":false,"is_priority":false,"notes":null,"recur":"","recur_until":"","prev_recur_todo_uuid":""},{"id":13,"uuid":"8f201ad4-122c-48e3-9956-08f7ba0fa62c","subject":"Read Clash of Kings","projects":[],"contexts":[],"due":"2021-10-01","completed":false,"completed_date":"","status":"","archived":false,"is_priority":false,"notes":null,"recur":"","recur_until":"","prev_recur_todo_uuid":""},{"id":14,"uuid":"d9e7f68f-9c26-40bc-9c51-5ff1eed45a42","subject":"Read Storm of Swords","projects":[],"contexts":[],"due":"2021-11-01","completed":false,"completed_date":"","status":"","archived":false,"is_priority":false,"notes":null,"recur":"","recur_until":"","prev_recur_todo_uuid":""},{"id":15,"uuid":"49465b87-6a56-4740-806f-96b5330d845c","subject":"write unit tests +improvement","projects":["improvement"],"contexts":[],"due":"2021-11-06","completed":false,"completed_date":"","status":"","archived":false,"is_priority":false,"notes":null,"recur":"","recur_until":"","prev_recur_todo_uuid":""},{"id":16,"uuid":"79bc2856-00ef-48a9-acbf-77a72a6335e8","subject":"Read Feast For Crows +books","projects":["books"],"contexts":[],"due":"2021-12-01","completed":false,"completed_date":"","status":"","archived":false,"is_priority":false,"notes":null,"recur":"","recur_until":"","prev_recur_todo_uuid":""}] \ No newline at end of file diff --git a/ultralist/date_parser.go b/ultralist/date_parser.go index 2f8530aa..376e7340 100644 --- a/ultralist/date_parser.go +++ b/ultralist/date_parser.go @@ -41,6 +41,18 @@ func (dp *DateParser) ParseDate(dateString string, pivotDay time.Time) (date tim case "nextweek": n := bod(pivotDay) return dp.getNearestMonday(n).AddDate(0, 0, 7), nil + case "thisweek": + n := bod(pivotDay) + return dp.getNearestMonday(n), nil + case "thismonth": + n := bod(pivotDay) + return dp.getNearestFirstOfMonth(n), nil + case "lastmonth": + n := bod(pivotDay) + return dp.getNearestFirstOfMonth(n).AddDate(0,-1,0), nil + case "nextmonth": + n := bod(pivotDay) + return dp.getNearestFirstOfMonth(n).AddDate(0,1,0), nil } return dp.parseSpecificDate(dateString, pivotDay) } @@ -119,3 +131,13 @@ func (dp *DateParser) getNearestMonday(t time.Time) time.Time { } } } + +func (dp *DateParser) getNearestFirstOfMonth(t time.Time) time.Time { + for { + if t.Day() != 1 { + t = t.AddDate(0, 0, -1) + } else { + return t + } + } +} diff --git a/ultralist/input_parser.go b/ultralist/input_parser.go index 61fd33af..c2fbfb80 100644 --- a/ultralist/input_parser.go +++ b/ultralist/input_parser.go @@ -113,12 +113,25 @@ func (p *InputParser) Parse(input string) (*Filter, error) { if dueDate.IsZero() { filter.Due = "" } else { - if word == "due:agenda" { - filter.HasDueBefore = true - filter.HasDue = false - filter.DueBefore = dueDate.Format(DATE_FORMAT) - } else { - filter.Due = dueDate.Format(DATE_FORMAT) + switch word { + case "due:agenda": + filter.HasDueBefore = true + filter.HasDue = false + filter.DueBefore = dueDate.Format(DATE_FORMAT) + case "due:lastweek", "due:thisweek", "due:nextweek": + filter.HasDue = false + filter.HasDueBefore = true + filter.DueBefore = dueDate.AddDate(0,0,7).Format(DATE_FORMAT) + filter.HasDueAfter = true + filter.DueAfter = dueDate.AddDate(0,0,-1).Format(DATE_FORMAT) + case "due:lastmonth", "due:thismonth", "due:nextmonth": + filter.HasDue = false + filter.HasDueBefore = true + filter.DueBefore = dueDate.AddDate(0,1,0).Format(DATE_FORMAT) + filter.HasDueAfter = true + filter.DueAfter = dueDate.AddDate(0,0,-1).Format(DATE_FORMAT) + default: + filter.Due = dueDate.Format(DATE_FORMAT) } } match = true