Skip to content

Repeat Extensions: support a concrete base date in @repeat(interval, <date>) - #760

Merged
jgclark merged 5 commits into
NotePlan:mainfrom
darrengillman:concrete-repeat-date
Aug 1, 2026
Merged

jgclark merged 5 commits into
NotePlan:mainfrom
darrengillman:concrete-repeat-date

Conversation

@darrengillman

Copy link
Copy Markdown

Summary

Adds an optional concrete base date to @repeat tags: @repeat(interval, <date>). When present, the next repeat is calculated from that fixed date rather than from the task's scheduled >date or completion/cancellation date. After each completion or cancellation the embedded date is automatically advanced by the same interval, so the anchor rolls forward correctly for future cycles. Fully backward compatible — existing @repeat(interval) and @repeat(+interval) tags are unaffected.

@repeat(1m, 2026-05-12)
@repeat(1w, 2026-W20)
@repeat(1m, 2026-06)
@repeat(1q, 2026-Q3)
@repeat(1y, 2027)

<date> accepts any of NotePlan's calendar-note date formats — day (YYYY-MM-DD), week (YYYY-Wnn), month (YYYY-MM), quarter (YYYY-Qn), year (YYYY) — and works the same whether the task lives in a project note or a calendar note.

Precedence rules

  • @repeat(1m, 2026-05-12) — next repeat calculated from the concrete date, ignoring scheduled >date and completion date.
  • @repeat(+1m, 2026-05-12) — + prefix takes precedence: next repeat calculated from completion/cancellation date as before; concrete date is ignored for scheduling (a warning is logged). The anchor in the tag still advances by one interval, so it keeps a "rolling" anchor one interval behind the completion-date schedule.
  • @repeat(1m) / @repeat(+1m) — unchanged.

Full details, including year-end/52-vs-53-week edge cases and cancelled-task behaviour, are in jgclark.RepeatExtensions/concrete-repeat-date-release-notes.md.

Changes

  • helpers/NPExtendedRepeat.js — concrete-date detection/validation, advancing the anchor on completion (generateRepeatForPara) and cancellation (generateRepeatForCancelledPara).
  • jgclark.RepeatExtensions/__tests__/repeatHelpers.test.js, helpers/__tests__/NPExtendedRepeat.generateRepeatForPara.test.js — new test coverage.
  • jgclark.RepeatExtensions/CHANGELOG.md, plugin.json — v1.2.0.

Test plan

  • npm run test:ci — 3800/3802 passing; the 2 failures are in np.Templating (locale-dependent date-format assertion, unrelated syntax-error test), pre-existing and untouched by this change.
  • node scripts/rollup.js -b -ci — all 43 plugins build successfully.
  • Manually tested completing/cancelling tasks with day/week/month/quarter/year concrete-date anchors in NotePlan, including year-boundary cases.

Darren Gillman and others added 4 commits June 13, 2026 01:15
…l, YYY-MM-DD) format

The `generate repeats` action ignores the scheduled date or calendar note date, and repeats based on the YYYY-MM-DD concrete date
Repeats with the relative (`+`) repeat interval modifier or with no concrete date fall through to the original behaviour

Initial tests added around basic functionality.
Generalizes the concrete base date in @repeat(interval, <date>) to accept
any NotePlan calendar-note date-spec (YYYY-Wnn, YYYY-MM, YYYY-Qn, YYYY) in
addition to YYYY-MM-DD, mirroring the existing non-concrete behaviour.
Advancing the concrete date in regenerated repeats now preserves its
original format (e.g. 2026-W19 -> 2026-W20), including across 52/53-week
year boundaries.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Bumps plugin.version, adds a CHANGELOG entry, and adds standalone release
notes for the concrete @repeat(...) base date feature (day/week/month/
quarter/year specs).
"Calendar-note date-spec" read as if the feature only worked in
calendar notes. It works identically in project notes and calendar
notes — the phrase was describing the date format, not a restriction
on where the tag can be used.
@jgclark
jgclark self-requested a review July 31, 2026 22:02
@jgclark jgclark self-assigned this Jul 31, 2026
@jgclark jgclark added the enhancement New feature or request label Jul 31, 2026
Comment thread helpers/NPExtendedRepeat.js Outdated

const EXTENDED_REPEAT_STR: string = `@repeat\\(${RE_DATE_INTERVAL}\\)` // find @repeat()
// A concrete @repeat(...) base date can be given in any NP calendar-note date-spec: day, week, month, quarter or year
const RE_CONCRETE_REPEAT_DATE: string = `(?:${RE_ISO_DATE}|${RE_NP_WEEK_SPEC}|${RE_NP_MONTH_SPEC}|${RE_NP_QUARTER_SPEC}|${RE_NP_YEAR_SPEC})`

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: I (now) try to use the convention that RE_* are actually of type RegExp, and other regex-related strings (like this), don't start with that. It makes for easier maintenance.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only doc files visible to plugin users are the README files (now via the NP website).
Thanks for writing this file (and updating the CHANGELOG) but it therefore needs to get incorporated into the relevant sections of the README.

@jgclark jgclark left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for adding this, and ensuring there is good test coverage and documentation.
Just a couple of things to look at, please, and then I can release.

- Rename RE_CONCRETE_REPEAT_DATE (a plain string, not a RegExp) to
  CONCRETE_REPEAT_DATE_STR, matching the file's existing convention that
  RE_* is reserved for actual RegExp values.
- Fold the concrete base date feature into the README, since only README
  files are surfaced to users; the standalone release-notes doc is kept
  as a more detailed reference.
@jgclark
jgclark merged commit ee53dd8 into NotePlan:main Aug 1, 2026
2 of 4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants