22// ----------------------------------------------------------------------------
33// Command to Process Date Offsets and Shifts
44// @jgclark
5- // Last updated 2025-08-22 for v0.23.0 , by @jgclark
5+ // Last updated 2025-10-20 for v0.23.1 , by @jgclark
66// ----------------------------------------------------------------------------
77// Note: Potential TODOs
88// * [Allow other date styles in /process date offsets](https://github.com/NotePlan/plugins/issues/221) from Feb 2021 -- but much harder than it looks.
@@ -21,9 +21,11 @@ import {
2121 RE_NP_WEEK_SPEC ,
2222 RE_OFFSET_DATE ,
2323 RE_OFFSET_DATE_CAPTURE ,
24+ splitIntervalToParts ,
2425} from '@helpers/dateTime'
2526import { clo , log , logDebug , logError , logInfo , logWarn } from '@helpers/dev'
2627import { displayTitle } from '@helpers/general'
28+ import { getNPWeekData } from '@helpers/NPdateTime'
2729import { findEndOfActivePartOfNote } from '@helpers/paragraph'
2830import { stripBlockIDsFromString } from '@helpers/stringTransforms'
2931import { isTimeBlockPara } from '@helpers/timeblocks'
@@ -61,21 +63,21 @@ export async function shiftDates(): Promise<void> {
6163 // Use the whole note
6264 pArr = paragraphs . slice ( 0 , findEndOfActivePartOfNote ( note ) )
6365 }
64- logDebug ( pluginJson , `shiftDates starting for ${ pArr . length } lines` )
66+ logDebug ( 'shiftDates' , `shiftDates starting for ${ pArr . length } lines` )
6567 if ( pArr . length === 0 ) {
66- logError ( pluginJson , `Empty selection found. Stopping.` )
68+ logError ( 'shiftDates' , `Empty selection found. Stopping.` )
6769 await showMessage ( 'Please select some lines to process.' , 'OK' , 'Shift Dates' )
6870 return
6971 }
7072
7173 // Get interval to use
7274 const interval = await askDateInterval ( "{question:'What interval would you like me to shift these dates by?'}" )
7375 if ( interval === '' ) {
74- logError ( pluginJson , `No valid interval supplied. Stopping.` )
76+ logError ( 'shiftDates' , `No valid interval supplied. Stopping.` )
7577 await showMessage ( `Sorry, that was not a valid date interval.` )
7678 return
7779 }
78- // const intervalParts = splitIntervalToParts(interval)
80+ const intervalParts = splitIntervalToParts ( interval )
7981
8082 // Main loop
8183 let updatedCount = 0
@@ -91,7 +93,7 @@ export async function shiftDates(): Promise<void> {
9193
9294 // If wanted, remove @done(...) part
9395 const doneDatePart = updatedContent . match ( RE_DONE_DATE_OPT_TIME ) ?? [ '' ]
94- // logDebug(pluginJson , `>> ${String(doneDatePart)}`)
96+ // logDebug('shiftDates' , `>> ${String(doneDatePart)}`)
9597 if ( config . removeDoneDates && doneDatePart [ 0 ] !== '' ) {
9698 updatedContent = updatedContent . replace ( doneDatePart [ 0 ] , '' )
9799 }
@@ -104,27 +106,27 @@ export async function shiftDates(): Promise<void> {
104106 // If wanted, set any complete or cancelled tasks/checklists to not complete
105107 if ( config . uncompleteTasks ) {
106108 if ( p . type === 'done' ) {
107- // logDebug(pluginJson , `>> changed done -> open`)
109+ // logDebug('shiftDates' , `>> changed done -> open`)
108110 p . type = 'open'
109111 } else if ( p . type === 'cancelled' ) {
110- // logDebug(pluginJson , `>> changed cancelled -> open`)
112+ // logDebug('shiftDates' , `>> changed cancelled -> open`)
111113 p . type = 'open'
112114 } else if ( p . type === 'scheduled' ) {
113- // logDebug(pluginJson , `>> changed scheduled -> open`)
115+ // logDebug('shiftDates' , `>> changed scheduled -> open`)
114116 p . type = 'open'
115117 } else if ( p . type === 'checklistDone' ) {
116- // logDebug(pluginJson , `>> changed checklistDone -> checklist`)
118+ // logDebug('shiftDates' , `>> changed checklistDone -> checklist`)
117119 p . type = 'checklist'
118120 } else if ( p . type === 'checklistScheduled' ) {
119- // logDebug(pluginJson , `>> changed checklistScheduled -> checklist`)
121+ // logDebug('shiftDates' , `>> changed checklistScheduled -> checklist`)
120122 p . type = 'checklist'
121123 } else if ( p . type === 'checklistCancelled' ) {
122- // logDebug(pluginJson , `>> changed checklistCancelled -> checklist`)
124+ // logDebug('shiftDates' , `>> changed checklistCancelled -> checklist`)
123125 p . type = 'checklist'
124126 }
125127 }
126128
127- // logDebug(pluginJson , `${origContent}`)
129+ // logDebug('shiftDates' , `${origContent}`)
128130 // For any YYYY-MM-DD dates in the line (can make sense in metadata lines to have multiples)
129131 let shiftedDateStr = ''
130132 if ( updatedContent . match ( RE_ISO_DATE ) ) {
@@ -135,10 +137,10 @@ export async function shiftDates(): Promise<void> {
135137 shiftedDateStr = calcOffsetDateStr ( originalDateStr , interval )
136138 // Replace date part with the new shiftedDateStr
137139 updatedContent = updatedContent . replace ( originalDateStr , shiftedDateStr )
138- logDebug ( pluginJson , `- ${ originalDateStr } : match found -> ${ shiftedDateStr } from interval ${ interval } ` )
140+ logDebug ( 'shiftDates' , `- ${ originalDateStr } : day match found -> ${ shiftedDateStr } from interval ${ interval } ` )
139141 updatedCount += 1
140142 }
141- logDebug ( pluginJson , `-> ${ updatedContent } ` )
143+ logDebug ( 'shiftDates' , `-> ${ updatedContent } ` )
142144 }
143145 // For any YYYY-Wnn dates in the line (might in future make sense in metadata lines to have multiples)
144146 if ( updatedContent . match ( RE_NP_WEEK_SPEC ) ) {
@@ -150,13 +152,14 @@ export async function shiftDates(): Promise<void> {
150152 // shiftedDateStr = calcOffsetDateStr(originalDateStr, interval)
151153
152154 // v2: using NPdateTime::getNPWeekData instead
153- // const thisWeekInfo = getNPWeekData(originalDateStr, intervalParts.number, intervalParts.type)
155+ const thisWeekInfo = getNPWeekData ( originalDateStr , intervalParts . number , intervalParts . type )
156+ shiftedDateStr = thisWeekInfo ?. weekString ?? '(error)'
154157 // Replace date part with the new shiftedDateStr
155158 updatedContent = updatedContent . replace ( originalDateStr , shiftedDateStr )
156- logDebug ( pluginJson , `- ${ originalDateStr } : match found -> ${ shiftedDateStr } from interval ${ interval } ` )
159+ logDebug ( 'shiftDates' , `- ${ originalDateStr } : week match found -> ${ shiftedDateStr } from interval ${ interval } ` )
157160 updatedCount += 1
158161 }
159- logDebug ( pluginJson , `-> ${ updatedContent } ` )
162+ logDebug ( 'shiftDates' , `-> ${ updatedContent } ` )
160163 }
161164 // else {
162165 // Note: This would be the place to assess another date format, but it's much harder than it looks.
@@ -167,7 +170,7 @@ export async function shiftDates(): Promise<void> {
167170
168171 // Update the paragraph content
169172 p . content = updatedContent . trimEnd ( )
170- // logDebug(pluginJson , `-> '${p.content}'`)
173+ // logDebug('shiftDates' , `-> '${p.content}'`)
171174 }
172175 } )
173176 // Write all paragraphs to the note
@@ -176,10 +179,10 @@ export async function shiftDates(): Promise<void> {
176179 Editor . highlightByIndex ( startingCursorPos , 0 )
177180
178181 // Notify user
179- logDebug ( pluginJson , `Shifted ${ updatedCount } dates in ${ pArr . length } lines` )
182+ logDebug ( 'shiftDates' , `Shifted ${ updatedCount } dates in ${ pArr . length } lines` )
180183 await showMessage ( `Shifted ${ updatedCount } dates in ${ pArr . length } lines` , 'OK' , 'Shift Dates' )
181184 } catch ( err ) {
182- logError ( pluginJson , err . message )
185+ logError ( pluginJson , `Error in shiftDates(): ${ err . message } ` )
183186 }
184187}
185188
@@ -212,7 +215,7 @@ export async function processDateOffsets(): Promise<void> {
212215 return
213216 }
214217 const noteTitle = displayTitle ( note )
215- logDebug ( pluginJson , `processDateOffsets() for note '${ noteTitle } '` )
218+ logDebug ( pluginJson , `Starting processDateOffsets() for note '${ noteTitle } '` )
216219 const config = await getEventsSettings ( )
217220
218221 let currentTargetDate = ''
@@ -225,7 +228,7 @@ export async function processDateOffsets(): Promise<void> {
225228 // Look through this open note to find date offsets
226229 const dateOffsetParas = paragraphs . filter ( ( p ) => p . content . match ( RE_DATE_INTERVAL ) && p . lineIndex < endOfActive )
227230 if ( dateOffsetParas . length > 0 ) {
228- logDebug ( pluginJson , `Found ${ dateOffsetParas . length } date offsets in '${ noteTitle } '` )
231+ logDebug ( 'processDateOffsets' , `Found ${ dateOffsetParas . length } date offsets in '${ noteTitle } '` )
229232
230233 // Go through each line in the active part of the file
231234 // Keep track of the indent level when a suitable date is found, so we know
@@ -348,6 +351,6 @@ export async function processDateOffsets(): Promise<void> {
348351 await showMessage ( `No date offset patterns found.` , `OK` , `Process Date Offsets` )
349352 }
350353 } catch ( err ) {
351- logError ( pluginJson , err . message )
354+ logError ( pluginJson , `Error in processDateOffsets(): ${ err . message } ` )
352355 }
353356}
0 commit comments