From 1a1830c65a3ef60285982c55b91f8d677a950ccd Mon Sep 17 00:00:00 2001 From: Ramesh Baskaran Date: Wed, 5 Aug 2026 07:57:50 +0400 Subject: [PATCH] Add --due-date and --clear-due-date to the edit command The edit command could change a reminder's title and notes but had no way to change its due date, even though add supports --due-date. This adds: - edit --due-date/-d : set a new due date, parsed with the same natural language parser add uses - edit --clear-due-date: remove the due date entirely Setting a new due date replaces any existing alarms, and adds an absolute alarm when the parsed date includes a time, matching add's behaviour. Clearing the due date also removes existing alarms. --due-date and --clear-due-date are mutually exclusive, and edit now accepts a due date change alone (previously it required new text or notes). --- README.md | 4 ++++ Sources/RemindersLibrary/CLI.swift | 21 ++++++++++++++++--- Sources/RemindersLibrary/Reminders.swift | 26 +++++++++++++++++++++++- 3 files changed, 47 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 4d7b7cc..efd46e3 100644 --- a/README.md +++ b/README.md @@ -45,6 +45,10 @@ $ reminders show Soon ``` $ reminders edit Soon 0 Some edited text Updated reminder 'Some edited text' +$ reminders edit Soon 0 --due-date "tomorrow 9am" +Updated reminder 'Some edited text' +$ reminders edit Soon 0 --clear-due-date +Updated reminder 'Some edited text' $ reminders show Soon 0 Ship reminders-cli 1 Some edited text diff --git a/Sources/RemindersLibrary/CLI.swift b/Sources/RemindersLibrary/CLI.swift index 8978505..ad2bbef 100644 --- a/Sources/RemindersLibrary/CLI.swift +++ b/Sources/RemindersLibrary/CLI.swift @@ -242,14 +242,27 @@ private struct Edit: ParsableCommand { help: "The notes to set on the reminder, overwriting previous notes") var notes: String? + @Option( + name: .shortAndLong, + help: "The new date the reminder is due") + var dueDate: DateComponents? + + @Flag(help: "Remove the due date from the reminder") + var clearDueDate = false + @Argument( parsing: .remaining, help: "The new reminder contents") var reminder: [String] = [] func validate() throws { - if self.reminder.isEmpty && self.notes == nil { - throw ValidationError("Must specify either new reminder content or new notes") + if self.dueDate != nil && self.clearDueDate { + throw ValidationError("Cannot specify both --due-date and --clear-due-date") + } + + if self.reminder.isEmpty && self.notes == nil && self.dueDate == nil && !self.clearDueDate { + throw ValidationError( + "Must specify either new reminder content, new notes, or a due date change") } } @@ -259,7 +272,9 @@ private struct Edit: ParsableCommand { itemAtIndex: self.index, onListNamed: self.listName, newText: newText.isEmpty ? nil : newText, - newNotes: self.notes + newNotes: self.notes, + newDueDateComponents: self.dueDate, + clearDueDate: self.clearDueDate ) } } diff --git a/Sources/RemindersLibrary/Reminders.swift b/Sources/RemindersLibrary/Reminders.swift index fb04a20..5c650c3 100644 --- a/Sources/RemindersLibrary/Reminders.swift +++ b/Sources/RemindersLibrary/Reminders.swift @@ -230,7 +230,14 @@ public final class Reminders { } } - func edit(itemAtIndex index: String, onListNamed name: String, newText: String?, newNotes: String?) { + func edit( + itemAtIndex index: String, + onListNamed name: String, + newText: String?, + newNotes: String?, + newDueDateComponents: DateComponents? = nil, + clearDueDate: Bool = false) + { let calendar = self.calendar(withName: name) let semaphore = DispatchSemaphore(value: 0) @@ -243,6 +250,23 @@ public final class Reminders { do { reminder.title = newText ?? reminder.title reminder.notes = newNotes ?? reminder.notes + + if clearDueDate { + reminder.dueDateComponents = nil + for alarm in reminder.alarms ?? [] { + reminder.removeAlarm(alarm) + } + } else if let newDueDateComponents { + reminder.dueDateComponents = newDueDateComponents + for alarm in reminder.alarms ?? [] { + reminder.removeAlarm(alarm) + } + + if let dueDate = newDueDateComponents.date, newDueDateComponents.hour != nil { + reminder.addAlarm(EKAlarm(absoluteDate: dueDate)) + } + } + try Store.save(reminder, commit: true) print("Updated reminder '\(reminder.title!)'") } catch let error {