From 3c0fcdd390fe1f1f269981c0fc69b5976924ddb9 Mon Sep 17 00:00:00 2001 From: Ryan Lewis Date: Sun, 4 Oct 2026 12:47:05 +0100 Subject: [PATCH 1/2] fix(edit): treat a --when or empty notes append Things ignores as applied An edit whose --when, --append-notes or --prepend-notes leaves the item as it is made Things record no change, so edit and project edit waited the full read-back budget and failed with "edit did not apply". Compare those flags with the item before waiting, as moves already do. Checked against Things 3 on to-dos and projects; --when today, evening or today's date clears a reminder, so the reminder is read before calling those a no-op. Fixes #377 --- cmd/things/edit.go | 96 ++++++++++++++++++++++++++--------- cmd/things/edit_test.go | 46 +++++++++++++++-- docs/content/agents.md | 7 ++- docs/content/commands.md | 19 ++++--- internal/db/dbtest/schema.sql | 1 + internal/db/tasks.go | 11 ++++ internal/db/tasks_test.go | 19 +++++++ internal/skill/SKILL.md | 2 +- 8 files changed, 163 insertions(+), 38 deletions(-) diff --git a/cmd/things/edit.go b/cmd/things/edit.go index d1dadd5..380e9dc 100644 --- a/cmd/things/edit.go +++ b/cmd/things/edit.go @@ -74,8 +74,7 @@ func (c *EditCmd) Run(d *Deps) error { // checkOwn reports whether any of this command's own field flags may change // the task. None of them is in coveredFields; runEdit adds the shared ones. -// Every field flag belongs either here, in commonEditFlags.uncoveredSet, or in -// covered, so a new one cannot be missed by changesFields and still pass +// Every field flag belongs either here or in commonEditFlags.covered, so a new one cannot be missed by changesFields and still pass // certainNoOp. A move Things will drop (checkMove) does not count. func (c *EditCmd) checkOwn(d *Deps, database *db.DB, task *model.Task) bool { return c.checkMove(d, database, task) || c.checklistSet() @@ -258,7 +257,7 @@ func runEdit(d *Deps, ref string, kind editKind, f *commonEditFlags, s *editStat if err != nil { return err } - ownSet := checkOwn(d, database, task) + uncovered := checkOwn(d, database, task) token := authToken(d, database) update := func() error { @@ -279,17 +278,22 @@ func runEdit(d *Deps, ref string, kind editKind, f *commonEditFlags, s *editStat Reveal: s.Reveal, }) } - uncovered := ownSet || f.uncoveredSet() - changed := f.changesFields(uncovered) && !f.certainNoOp(task, uncovered, foldTags(unknown)) + // A reminder that cannot be read counts as one, so the edit waits. + hasReminder := func() bool { + ok, err := database.HasReminder(task.UUID) + return ok || err != nil + } + changed := f.changesFields(uncovered) && !f.certainNoOp(task, uncovered, foldTags(unknown), hasReminder) return applyEdit(d, database, task, changed, checklist, s.Complete, s.Cancel, s.Duplicate, update) } // certainNoOp reports whether every field flag set on the edit provably // leaves the item as it is, so there is no modification to wait for. -// uncovered says whether any field flag outside coveredFields is set, and -// dropped holds the folded tag names Things will drop (foldTags). -func (f *commonEditFlags) certainNoOp(task *model.Task, uncovered bool, dropped map[string]struct{}) bool { - return !uncovered && f.covered().unchanged(task, dropped) +// uncovered says whether any field flag outside coveredFields is set, +// dropped holds the folded tag names Things will drop (foldTags), and +// hasReminder reads whether the item has a reminder (whenUnchanged). +func (f *commonEditFlags) certainNoOp(task *model.Task, uncovered bool, dropped map[string]struct{}, hasReminder func() bool) bool { + return !uncovered && f.covered().unchanged(task, dropped, hasReminder) } // foldTags folds the names verifyTags says Things will drop, so the no-op @@ -312,13 +316,7 @@ func (f *commonEditFlags) changesFields(uncovered bool) bool { } func (f *commonEditFlags) covered() coveredFields { - return coveredFields{f.Title, f.Notes, f.Deadline, f.Tags, f.AddTags} -} - -// uncoveredSet reports whether any shared field flag outside coveredFields is -// set. runEdit adds the command's own flags (ownFieldsSet). -func (f *commonEditFlags) uncoveredSet() bool { - return anySet(f.PrependNotes, f.AppendNotes, f.When) + return coveredFields{f.Title, f.Notes, f.PrependNotes, f.AppendNotes, f.When, f.Deadline, f.Tags, f.AddTags} } // coveredFields are the edit flags whose effect can be predicted exactly from @@ -326,27 +324,34 @@ func (f *commonEditFlags) uncoveredSet() bool { // before the read-back. Things records no change for such an edit, and // waiting for one would end in a false "did not apply" after the full budget. type coveredFields struct { - title, notes, deadline, tags, addTags *string + title, notes, prependNotes, appendNotes, when, deadline, tags, addTags *string } // set reports whether any covered flag was given. func (f coveredFields) set() bool { - return anySet(f.title, f.notes, f.deadline, f.tags, f.addTags) + return anySet(f.title, f.notes, f.prependNotes, f.appendNotes, f.when, f.deadline, f.tags, f.addTags) } // unchanged reports whether each flag that is set already matches task. It is // deliberately narrow: a value whose outcome depends on how Things reads it -// counts as a change, and the edit waits for its read-back as before. --when -// is left out for that reason — even `today` on an item already in Today may -// touch its reminder, which the CLI does not read. Tags named in dropped do -// not exist in Things, which ignores them, so they count as no change. -func (f coveredFields) unchanged(task *model.Task, dropped map[string]struct{}) bool { +// counts as a change, and the edit waits for its read-back as before. Tags +// named in dropped do not exist in Things, which ignores them, so they count +// as no change. +func (f coveredFields) unchanged(task *model.Task, dropped map[string]struct{}, hasReminder func() bool) bool { if f.title != nil && *f.title != task.Title { return false } if f.notes != nil && *f.notes != task.Notes { return false } + // Checked in Things 3: an empty append or prepend leaves the notes as + // they are. + if f.prependNotes != nil && *f.prependNotes != "" || f.appendNotes != nil && *f.appendNotes != "" { + return false + } + if f.when != nil && !whenUnchanged(*f.when, task, time.Now(), hasReminder) { + return false + } // Tags compare the way Things matches them: case-insensitively, after // trimming (db.FoldTag). have := make(map[string]struct{}, len(task.Tags)) @@ -397,6 +402,51 @@ func deadlineUnchanged(value string, current *model.ThingsDate) bool { return err == nil && current != nil && *current == model.ThingsDateFromTime(date) } +// whenUnchanged covers a --when that leaves the item where it is, as checked +// in Things 3 on to-dos and projects. anytime, and an empty value, match an +// Anytime item with no start date; someday matches a Someday item with no +// start date. today and evening match an item scheduled for today in that part +// of the day, and a date of today matches either part. Each of those clears a +// reminder, which counts as a change, so hasReminder is asked only then. +// tomorrow, or a later date, matches an item scheduled that day, reminder or +// not. A time, a phrase, or a date already past counts as a change. +func whenUnchanged(value string, task *model.Task, now time.Time, hasReminder func() bool) bool { + v, err := things.NormalizeWhen(value) + if err != nil { + return false + } + switch v { + case "", "anytime": + return task.Start == model.StartAnytime && task.StartDate == nil + case "someday": + return task.Start == model.StartSomeday && task.StartDate == nil + case "tomorrow": + v = now.AddDate(0, 0, 1).Format("2006-01-02") + } + today := model.ThingsDateFromTime(now) + if task.StartDate == nil { + return false + } + switch v { + case "today": + return *task.StartDate == today && task.StartBucket == 0 && !hasReminder() + case "evening": + return *task.StartDate == today && task.StartBucket == 1 && !hasReminder() + } + date, err := time.ParseInLocation("2006-01-02", v, time.Local) + if err != nil { + return false + } + want := model.ThingsDateFromTime(date) + switch { + case want < today: + return false + case want == today: + return *task.StartDate == today && !hasReminder() + } + return *task.StartDate == want +} + // anySet reports whether any of the optional flags was given. func anySet(flags ...*string) bool { for _, f := range flags { diff --git a/cmd/things/edit_test.go b/cmd/things/edit_test.go index 37924d0..e8e0962 100644 --- a/cmd/things/edit_test.go +++ b/cmd/things/edit_test.go @@ -329,6 +329,10 @@ func TestEditCertainNoOpSkipsTheWait(t *testing.T) { now := time.Now() today := int(model.ThingsDateFromTime(now)) deadline := int(model.ThingsDateFromTime(time.Date(2026, 10, 15, 0, 0, 0, 0, time.Local))) + day := func(offset int) string { return now.AddDate(0, 0, offset).Format("2006-01-02") } + dayInt := func(offset int) string { + return strconv.Itoa(int(model.ThingsDateFromTime(now.AddDate(0, 0, offset)))) + } cases := []struct { name string @@ -355,15 +359,40 @@ func TestEditCertainNoOpSkipsTheWait(t *testing.T) { {"newDeadline", []string{"edit", "one-1", "--deadline", "2026-10-16"}, false}, {"clearDeadline", []string{"edit", "one-1", "--deadline", ""}, false}, {"clearAbsentDeadline", []string{"edit", "two-1", "--deadline", ""}, true}, - // --when always waits: even `today` on an item already in Today may - // touch its reminder, which the CLI does not read. - {"whenTodayOnToday", []string{"edit", "one-1", "--when", "today"}, false}, + {"emptyAppendNotes", []string{"edit", "one-1", "--append-notes", ""}, true}, + {"emptyPrependNotes", []string{"edit", "one-1", "--prepend-notes", ""}, true}, + {"prependNotes", []string{"edit", "one-1", "--prepend-notes", "x"}, false}, + {"whenTodayOnToday", []string{"edit", "one-1", "--when", "Today"}, true}, + {"whenTodayDateOnToday", []string{"edit", "one-1", "--when", day(0)}, true}, + {"whenEveningOnToday", []string{"edit", "one-1", "--when", "evening"}, false}, + {"whenEveningOnEvening", []string{"edit", "eve-1", "--when", "evening"}, true}, + {"whenTodayDateOnEvening", []string{"edit", "eve-1", "--when", day(0)}, true}, + {"whenTodayOnEvening", []string{"edit", "eve-1", "--when", "today"}, false}, + // Things clears a reminder on a --when for today without a time. + {"whenTodayClearsReminder", []string{"edit", "rem-1", "--when", "today"}, false}, + {"whenTodayDateClearsReminder", []string{"edit", "rem-1", "--when", day(0)}, false}, + {"whenTime", []string{"edit", "rem-1", "--when", "18:00"}, false}, + {"whenDateTime", []string{"edit", "tom-1", "--when", day(1) + "@08:00"}, false}, + {"whenTomorrowKeepsReminder", []string{"edit", "tom-1", "--when", "tomorrow"}, true}, + {"whenTomorrowDate", []string{"edit", "tom-1", "--when", day(1)}, true}, + {"whenOtherDate", []string{"edit", "tom-1", "--when", day(2)}, false}, + {"whenPastDate", []string{"edit", "past-1", "--when", day(-1)}, false}, + {"whenSomedayOnSomeday", []string{"edit", "some-1", "--when", "someday"}, true}, + {"whenSomedayOnScheduled", []string{"edit", "tom-1", "--when", "someday"}, false}, + {"whenAnytimeOnAnytime", []string{"edit", "two-1", "--when", "anytime"}, true}, + {"whenClearOnAnytime", []string{"edit", "two-1", "--when", ""}, true}, + {"whenClearOnSomeday", []string{"edit", "some-1", "--when", ""}, false}, + {"whenClearOnInbox", []string{"edit", "inbox-1", "--when", ""}, false}, + {"whenAnytimeOnToday", []string{"edit", "one-1", "--when", "anytime"}, false}, {"whenPhrase", []string{"edit", "one-1", "--when", "friday"}, false}, - {"allNoOp", []string{"edit", "one-1", "--title", "Post letter", "--notes", "second class", "--add-tags", "errand", "--deadline", "2026-10-15"}, true}, - {"noOpPlusWhen", []string{"edit", "one-1", "--title", "Post letter", "--when", "today"}, false}, + {"allNoOp", []string{"edit", "one-1", "--title", "Post letter", "--notes", "second class", "--add-tags", "errand", "--deadline", "2026-10-15", "--when", "today", "--append-notes", ""}, true}, + {"noOpPlusNewWhen", []string{"edit", "one-1", "--title", "Post letter", "--when", "someday"}, false}, + {"sameWhenPlusNewTitle", []string{"edit", "one-1", "--title", "Post the letter", "--when", "today"}, false}, {"mixed", []string{"edit", "one-1", "--title", "Post letter", "--notes", "first class"}, false}, {"mixedUncoveredFlag", []string{"edit", "one-1", "--title", "Post letter", "--append-notes", "x"}, false}, {"projectSameTitle", []string{"project", "edit", "repproj-1", "--title", "Weekly review"}, true}, + {"projectWhenSomeday", []string{"project", "edit", "proj-1", "--when", "someday", "--append-notes", ""}, true}, + {"projectWhenToday", []string{"project", "edit", "proj-1", "--when", "today"}, false}, {"projectMoveArea", []string{"project", "edit", "repproj-1", "--title", "Weekly review", "--area", "Home"}, false}, } for _, tc := range cases { @@ -376,6 +405,13 @@ func TestEditCertainNoOpSkipsTheWait(t *testing.T) { `INSERT INTO TMTag (uuid, title) VALUES ('tag-1', 'Errand'), ('tag-2', 'Urgent'), ('tag-3', 'Home')`, `INSERT INTO TMTaskTag (tasks, tags) VALUES ('one-1', 'tag-1'), ('one-1', 'tag-2')`, `INSERT INTO TMTask (uuid, title, type, status, trashed, start) VALUES ('two-1', 'Undated', 0, 0, 0, 1)`, + `INSERT INTO TMTask (uuid, title, type, status, trashed, start, startDate, startBucket) VALUES ('eve-1', 'Evening', 0, 0, 0, 1, ` + strconv.Itoa(today) + `, 1)`, + `INSERT INTO TMTask (uuid, title, type, status, trashed, start, startDate, startBucket, reminderTime) VALUES ('rem-1', 'Reminded', 0, 0, 0, 1, ` + strconv.Itoa(today) + `, 0, 1207959552)`, + `INSERT INTO TMTask (uuid, title, type, status, trashed, start, startDate, startBucket, reminderTime) VALUES ('tom-1', 'Tomorrow', 0, 0, 0, 2, ` + dayInt(1) + `, 0, 536870912)`, + `INSERT INTO TMTask (uuid, title, type, status, trashed, start, startDate, startBucket) VALUES ('past-1', 'Overdue start', 0, 0, 0, 1, ` + dayInt(-1) + `, 0)`, + `INSERT INTO TMTask (uuid, title, type, status, trashed, start) VALUES ('some-1', 'Someday', 0, 0, 0, 2)`, + `INSERT INTO TMTask (uuid, title, type, status, trashed, start) VALUES ('inbox-1', 'Inbox', 0, 0, 0, 0)`, + `INSERT INTO TMTask (uuid, title, type, status, trashed, start) VALUES ('proj-1', 'Someday project', 1, 0, 0, 2)`, `INSERT INTO TMArea (uuid, title, "index") VALUES ('area-1', 'Home', 1)`, } for _, s := range stmts { diff --git a/docs/content/agents.md b/docs/content/agents.md index ca42b14..5ea883c 100644 --- a/docs/content/agents.md +++ b/docs/content/agents.md @@ -434,8 +434,11 @@ instead of assuming: - **Edits are read back.** `edit` and `project edit` wait for Things to record the change, then print the item as `things show` would. Exit 0 with the item printed is the confirmation, so the agent does not need a - second `things show`. With `--no-verify` or `--duplicate` nothing is - read back and the output says the edit is unconfirmed. + second `things show`. An edit that re-sets values the item already has, + such as `--when someday` on a Someday item, prints the item at once, so + re-running a plan does not fail on work already done. With `--no-verify` + or `--duplicate` nothing is read back and the output says the edit is + unconfirmed. - **Tags must already exist.** Things silently drops tags it does not know. The CLI warns before writing; `--create-tags` creates the missing ones first and `--strict-tags` refuses to write instead. diff --git a/docs/content/commands.md b/docs/content/commands.md index b02e769..13104ad 100644 --- a/docs/content/commands.md +++ b/docs/content/commands.md @@ -515,13 +515,18 @@ to `add`, `project add`, `complete`, `cancel`, `tag add` and the new items and status changes in an `import`. An edit that sets every field to the value it already has is detected before the wait when every flag is `--title`, -`--notes`, `--tags`, `--add-tags` (tags compared case-insensitively) or a -`--deadline` date. Tags that do not exist in Things count as no change, -since Things drops them, unless `--create-tags` creates them first. So -does a move the warnings above say will leave the item where it is. It -then prints the item straight away. Any other -re-set value, `--when` included, still waits and reports the same error, -so on that error check the item with `things show` before retrying. +`--notes`, `--tags`, `--add-tags` (tags compared case-insensitively), a +`--deadline` date, an empty `--append-notes` or `--prepend-notes`, or a +`--when` of `anytime`, `someday`, `today`, `evening`, `tomorrow`, empty, +or a date from today on. `--when today`, `evening` or today's date clears +a reminder, so on an item with one it counts as a change and waits; a +later day keeps the reminder. Tags that do not exist in Things count as +no change, since Things drops them, unless `--create-tags` creates them +first. So does a move the warnings above say will leave the item where it +is. It then prints the item straight away. Any other re-set value, such as +a `--when` with a time or an English phrase, still waits and reports the +same error, so on that error check the item with `things show` before +retrying. An edit with nothing to change (no field flags, or `--complete` on a task that is already complete) prints the item without waiting. diff --git a/internal/db/dbtest/schema.sql b/internal/db/dbtest/schema.sql index 1dd6fc0..4ca2440 100644 --- a/internal/db/dbtest/schema.sql +++ b/internal/db/dbtest/schema.sql @@ -11,6 +11,7 @@ CREATE TABLE TMTask ( start INTEGER, startDate INTEGER, startBucket INTEGER, + reminderTime INTEGER, deadline INTEGER, deadlineSuppressionDate INTEGER, "index" INTEGER, diff --git a/internal/db/tasks.go b/internal/db/tasks.go index e657bc9..87f6533 100644 --- a/internal/db/tasks.go +++ b/internal/db/tasks.go @@ -1220,6 +1220,17 @@ func (d *DB) GetTaskByUUID(uuid string) (*model.Task, error) { return &t, nil } +// HasReminder reports whether the item has a reminder time set. Things clears +// it when a --when for today arrives without a time, so the edit no-op check +// needs it; nothing prints it. +func (d *DB) HasReminder(uuid string) (bool, error) { + var n int + if err := d.db.QueryRow(`SELECT COUNT(*) FROM TMTask WHERE uuid = ? AND reminderTime IS NOT NULL`, uuid).Scan(&n); err != nil { + return false, fmt.Errorf("reading reminder: %w", err) + } + return n > 0, nil +} + // uuidChunkSize caps how many uuids go into one IN (...) clause, so a caller // passing an arbitrarily long list can never trip SQLITE_MAX_VARIABLE_NUMBER — // the bound parameter limit is a property of the SQLite build, not something diff --git a/internal/db/tasks_test.go b/internal/db/tasks_test.go index 09faa03..1e64d89 100644 --- a/internal/db/tasks_test.go +++ b/internal/db/tasks_test.go @@ -4744,3 +4744,22 @@ func TestListTasksProjectChildrenStayInOtherViews(t *testing.T) { t.Errorf("anytime: sd-anytime-child should still list, got %v", uuidsOf(got)) } } + +// HasReminder reads reminderTime alone; a missing item has none. +func TestHasReminder(t *testing.T) { + d, fx := newFixture(t) + fx.Todo("rem-1", "Reminded", 1) + fx.Todo("plain-1", "Plain", 2) + if _, err := d.db.Exec(`UPDATE TMTask SET reminderTime = 1207959552 WHERE uuid = 'rem-1'`); err != nil { + t.Fatalf("seed: %v", err) + } + for uuid, want := range map[string]bool{"rem-1": true, "plain-1": false, "nope": false} { + got, err := d.HasReminder(uuid) + if err != nil { + t.Fatalf("HasReminder(%q): %v", uuid, err) + } + if got != want { + t.Errorf("HasReminder(%q) = %v, want %v", uuid, got, want) + } + } +} diff --git a/internal/skill/SKILL.md b/internal/skill/SKILL.md index b083a71..e1d094d 100644 --- a/internal/skill/SKILL.md +++ b/internal/skill/SKILL.md @@ -139,7 +139,7 @@ Error: 1 of 2 requested status changes did not apply. …: The rest of that import is already applied — re-run with only the failed items. -`edit` and `project edit` wait for Things to record the write (the item's modification date changes, or with a checklist flag the checklist changes, since Things leaves the date alone for a checklist-only change; with `--complete`/`--cancel` the status must change too, and a status-only edit is checked on the status alone), then print the item exactly as `things show` would — the same object under `--json`. **Exit 0 with the item printed means the edit is confirmed: do not `things show` it again.** A dropped edit exits non-zero with `edit did not apply: …` after the read-back wait (5s by default; see `--verify-timeout` below). An edit that only re-sets values the item already has is caught before the wait and succeeds when every flag is `--title`, `--notes`, `--tags`, `--add-tags` (tags compared case-insensitively) or a `--deadline` date; a tag that does not exist in Things counts as no change, since Things drops it, unless `--create-tags` creates it. Any other flag — `--when` included — or an English phrase still waits, and a no-op there reports the same error. **On that error, run `things show ` before retrying: if the item already shows what you asked for, it is done; do not retry blindly.** `--duplicate` edits a new copy the CLI cannot find, so nothing is read back; under `--no-verify` neither is anything. Both print a line saying the edit was sent but not confirmed — under `--json`, `{"uuid": …, "title": …, "confirmed": false, "reason": "duplicate"|"no-verify"}`. +`edit` and `project edit` wait for Things to record the write (the item's modification date changes, or with a checklist flag the checklist changes, since Things leaves the date alone for a checklist-only change; with `--complete`/`--cancel` the status must change too, and a status-only edit is checked on the status alone), then print the item exactly as `things show` would — the same object under `--json`. **Exit 0 with the item printed means the edit is confirmed: do not `things show` it again.** A dropped edit exits non-zero with `edit did not apply: …` after the read-back wait (5s by default; see `--verify-timeout` below). An edit that only re-sets values the item already has is caught before the wait and succeeds when every flag is `--title`, `--notes`, `--tags`, `--add-tags` (tags compared case-insensitively), a `--deadline` date, an empty `--append-notes`/`--prepend-notes`, or a `--when` of `anytime`, `someday`, `today`, `evening`, `tomorrow`, empty, or a date from today on (`today`, `evening` or today's date clears a reminder, so on an item with one it is a change and waits); a tag that does not exist in Things counts as no change, since Things drops it, unless `--create-tags` creates it. Any other flag, a `--when` with a time, or an English phrase still waits, and a no-op there reports the same error. **On that error, run `things show ` before retrying: if the item already shows what you asked for, it is done; do not retry blindly.** `--duplicate` edits a new copy the CLI cannot find, so nothing is read back; under `--no-verify` neither is anything. Both print a line saying the edit was sent but not confirmed — under `--json`, `{"uuid": …, "title": …, "confirmed": false, "reason": "duplicate"|"no-verify"}`. `add` and `project add` find the item they created (an item of that kind with that title, filed in the project, area and heading the add sent it to — or in none when it named none — created after the write and not there before it) and print it exactly as `things show` would. **Exit 0 with the item printed means it was created: use its `uuid`, do not `things search` for it.** If it never appears they exit non-zero with `add not confirmed: …`; **run the `things search` command the error prints (it keeps your `--db` and `--config`) before retrying, or a retry may create a duplicate.** A same-titled item another command adds elsewhere at the same moment is not taken for yours (unless the database could not be read to resolve where the add was sent). If more than one new item with that title is visible together in the place the add sent it, they exit 0 with a line saying the add is not confirmed and listing the candidate uuids — under `--json`, `{"title": …, "confirmed": false, "reason": "ambiguous", "candidates": [...]}`. `--no-verify` prints the same shape with reason `"no-verify"`, and an unreadable database gives `"unreadable"` with a warning. **Exit 0 with `"confirmed": false` is not a confirmation**: search for the title before acting on it. From 2de0c674b2774cebd46028ca81f805e343c07a8c Mon Sep 17 00:00:00 2001 From: Ryan Lewis Date: Sun, 4 Oct 2026 13:29:33 +0100 Subject: [PATCH 2/2] style(edit): rewrap the checkOwn comment --- cmd/things/edit.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/cmd/things/edit.go b/cmd/things/edit.go index 380e9dc..b6af813 100644 --- a/cmd/things/edit.go +++ b/cmd/things/edit.go @@ -74,8 +74,9 @@ func (c *EditCmd) Run(d *Deps) error { // checkOwn reports whether any of this command's own field flags may change // the task. None of them is in coveredFields; runEdit adds the shared ones. -// Every field flag belongs either here or in commonEditFlags.covered, so a new one cannot be missed by changesFields and still pass -// certainNoOp. A move Things will drop (checkMove) does not count. +// Every field flag belongs either here or in commonEditFlags.covered, so a +// new one cannot be missed by changesFields and still pass certainNoOp. A +// move Things will drop (checkMove) does not count. func (c *EditCmd) checkOwn(d *Deps, database *db.DB, task *model.Task) bool { return c.checkMove(d, database, task) || c.checklistSet() }