Skip to content
Open
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
82 changes: 48 additions & 34 deletions Sources/RemindersLibrary/CLI.swift
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,8 @@ private struct Show: ParsableCommand {
abstract: "Print the items on the given list")

@Argument(
help: "The list to print items from, see 'show-lists' for names",
completion: .custom(listNameCompletion))
var listName: String
help: "The list to print items from, see 'show-lists' for names or IDs")
var listNameOrId: String

@Flag(help: "Show completed items only")
var onlyCompleted = false
Expand Down Expand Up @@ -107,7 +106,7 @@ private struct Show: ParsableCommand {
}

reminders.showListItems(
withName: self.listName, dueOn: self.dueDate, displayOptions: displayOptions,
withNameOrId: self.listNameOrId, dueOn: self.dueDate, displayOptions: displayOptions,
outputFormat: format, sort: sort, sortOrder: sortOrder)
}
}
Expand All @@ -117,9 +116,8 @@ private struct Add: ParsableCommand {
abstract: "Add a reminder to a list")

@Argument(
help: "The list to add to, see 'show-lists' for names",
completion: .custom(listNameCompletion))
var listName: String
help: "The list to add to, see 'show-lists' for names or IDs")
var listNameOrId: String

@Argument(
parsing: .remaining,
Expand Down Expand Up @@ -150,7 +148,7 @@ private struct Add: ParsableCommand {
reminders.addReminder(
string: self.reminder.joined(separator: " "),
notes: self.notes,
toListNamed: self.listName,
toListNameOrId: self.listNameOrId,
dueDateComponents: self.dueDate,
priority: priority,
outputFormat: format)
Expand All @@ -162,16 +160,22 @@ private struct Complete: ParsableCommand {
abstract: "Complete a reminder")

@Argument(
help: "The list to complete a reminder on, see 'show-lists' for names",
completion: .custom(listNameCompletion))
var listName: String
help: "The list to complete a reminder on, see 'show-lists' for names or IDs")
var listNameOrId: String

@Argument(
help: "The index or id of the reminder to delete, see 'show' for indexes")
var index: String
help: "The index or id of the reminder to delete, see 'show' for indexes and IDs")
var indexOrId: String

@Option(
name: .shortAndLong,
help: "Output format (plain or json)")
var format: OutputFormat = .plain

func run() {
reminders.setComplete(true, itemAtIndex: self.index, onListNamed: self.listName)
reminders.setComplete(true, itemAtIndexOrId: self.indexOrId,
onListNamedOrId: self.listNameOrId,
outputFormat: format)
}
}

Expand All @@ -180,16 +184,22 @@ private struct Uncomplete: ParsableCommand {
abstract: "Uncomplete a reminder")

@Argument(
help: "The list to uncomplete a reminder on, see 'show-lists' for names",
completion: .custom(listNameCompletion))
var listName: String
help: "The list to uncomplete a reminder on, see 'show-lists' for names or IDs")
var listNameOrId: String

@Argument(
help: "The index or id of the reminder to delete, see 'show' for indexes")
var index: String
help: "The index or id of the reminder to delete, see 'show' for indexes and IDs")
var indexOrId: String

@Option(
name: .shortAndLong,
help: "Output format (plain or json)")
var format: OutputFormat = .plain

func run() {
reminders.setComplete(false, itemAtIndex: self.index, onListNamed: self.listName)
reminders.setComplete(false, itemAtIndexOrId: self.indexOrId,
onListNamedOrId: self.listNameOrId,
outputFormat: format)
}
}

Expand All @@ -198,16 +208,15 @@ private struct Delete: ParsableCommand {
abstract: "Delete a reminder")

@Argument(
help: "The list to delete a reminder on, see 'show-lists' for names",
completion: .custom(listNameCompletion))
var listName: String
help: "The list to delete a reminder on, see 'show-lists' for names or IDs")
var listNameOrId: String

@Argument(
help: "The index or id of the reminder to delete, see 'show' for indexes")
var index: String
help: "The index or id of the reminder to delete, see 'show' for indexes and IDs")
var indexOrId: String

func run() {
reminders.delete(itemAtIndex: self.index, onListNamed: self.listName)
reminders.delete(itemAtIndexOrId: self.indexOrId, onListNamedOrId: self.listNameOrId)
}
}

Expand All @@ -222,13 +231,12 @@ private struct Edit: ParsableCommand {
abstract: "Edit the text of a reminder")

@Argument(
help: "The list to edit a reminder on, see 'show-lists' for names",
completion: .custom(listNameCompletion))
var listName: String
help: "The list to edit a reminder on, see 'show-lists' for names or IDs")
var listNameOrId: String

@Argument(
help: "The index or id of the reminder to delete, see 'show' for indexes")
var index: String
help: "The index or id of the reminder to delete, see 'show' for indexes and IDs")
var indexOrId: String

@Option(
name: .shortAndLong,
Expand All @@ -240,6 +248,11 @@ private struct Edit: ParsableCommand {
help: "The new reminder contents")
var reminder: [String] = []

@Option(
name: .shortAndLong,
help: "Output format (plain or json)")
var format: OutputFormat = .plain

func validate() throws {
if self.reminder.isEmpty && self.notes == nil {
throw ValidationError("Must specify either new reminder content or new notes")
Expand All @@ -249,10 +262,11 @@ private struct Edit: ParsableCommand {
func run() {
let newText = self.reminder.joined(separator: " ")
reminders.edit(
itemAtIndex: self.index,
onListNamed: self.listName,
itemAtIndexOrId: self.indexOrId,
onListNamedOrId: self.listNameOrId,
newText: newText.isEmpty ? nil : newText,
newNotes: self.notes
newNotes: self.notes,
outputFormat: format
)
}
}
Expand Down
14 changes: 14 additions & 0 deletions Sources/RemindersLibrary/EKCalendar+Encodable.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import EventKit

extension EKCalendar: @retroactive Encodable {
private enum EncodingKeys: String, CodingKey {
case title
case calendarIdentifier
}

public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: EncodingKeys.self)
try container.encode(self.title, forKey: .title)
try container.encode(self.calendarIdentifier, forKey: .calendarIdentifier)
}
}
6 changes: 4 additions & 2 deletions Sources/RemindersLibrary/EKReminder+Encodable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ extension EKReminder: @retroactive Encodable {
case startDate
case dueDate
case list
case listId
}

public func encode(to encoder: Encoder) throws {
Expand All @@ -25,8 +26,9 @@ extension EKReminder: @retroactive Encodable {
try container.encode(self.isCompleted, forKey: .isCompleted)
try container.encode(self.priority, forKey: .priority)
try container.encode(self.calendar.title, forKey: .list)
try container.encode(self.calendar.calendarIdentifier, forKey: .listId)
try container.encodeIfPresent(self.notes, forKey: .notes)

// url field is nil
// https://developer.apple.com/forums/thread/128140
try container.encodeIfPresent(self.url, forKey: .url)
Expand Down Expand Up @@ -59,7 +61,7 @@ extension EKReminder: @retroactive Encodable {
try container.encode(format(creationDate), forKey: .creationDate)
}
}

private func format(_ date: Date?) -> String? {
if #available(macOS 12.0, *) {
return date?.ISO8601Format()
Expand Down
Loading