Support for repeated tasks
I'm creating this issue as a proposal.
As I mentioned in https://github.com/akhramov/org-wild-notifier.el/issues/30#issuecomment-722579110, repeated tasks format is not parsed correctly, e.g. <2020-09-17 17:50-20:50 .+1w> is parsed by org-parse-time-string as if it was <2020-09-17 17:50>.
org-time-string-to-absolute gives us the closest date to the second argument if there is a specifier for a cyclic time stamp.
(org-time-string-to-absolute "<2020-09-17 Thu 19:56-20:50 .+1w>" "<2020-11-05>")
(org-time-string-to-absolute "<2020-11-05 Thu 19:56-20:50 .+1w>" "<2020-11-05>")
Both lines give us the value of parsing "<2020-11-05 Thu 19:56>".
By using org-format-time-string, we can get the current time formatted as org format requires.
(org-time-string-to-absolute "<2020-09-17 Thu 19:56-20:50 .+1w>"
(org-format-time-string "<%Y-%m-%d>"))
In order to have the same result as the mentioned line, we can use org-time-from-absolute to convert:
(org-time-from-absolute
(org-time-string-to-absolute "<2020-09-17 Thu 19:56-20:50 .+1w>"
(org-format-time-string "<%Y-%m-%d>")))
With all of this together, we could integrate it as:
(defun org-wild-notifier--extract-time (marker)
"Extract timestamps from MARKER.
Timestamps are extracted as cons cells. car holds org-formatted
string, cdr holds time in list-of-integer format."
(-non-nil
(--map
(let* ((org-timestamp (org-entry-get marker it))
(nearest-time (org-time-string-to-absolute org-timestamp)))
(and org-timestamp
(cons org-timestamp
(org-time-from-absolute nearest-time))))
'("DEADLINE" "SCHEDULED" "TIMESTAMP"))))
I have tried all the functions but the last one, as I'm new to elisp and I don't know how to test or debug it. I'm open to suggestions.
I found org-closest-date which does the exact same thing. The problem with this two functions is that they don't look at the hour, just the day.
As a workaround, I'm using this hacks:
I added a new function, which is the responsible of better parsing a timestamp. In case it is a cyclic timestamp, it gets the closest date cycle until today.
(defun org-wild-notifier--timestamp-parse (timestamp)
(let ((parsed (org-parse-time-string timestamp))
(today (org-format-time-string "<%Y-%m-%d>")))
;; seconds-to-time returns also milliseconds and nanoseconds so we
;; have to "trim" the list
(butlast
(seconds-to-time
(org-time-add
;; we get the cycled absolute day (not hour and minutes)
(org-time-from-absolute (org-closest-date timestamp today 'past))
;; so we have to add the minutes too
(+ (* (decoded-time-hour parsed) 3600)
(* (decoded-time-minute parsed) 60))))
2)
))
As org-closest-date returns the time of the absolute day (no hour or minutes considered), we have to sum the hours and minutes to the date.
After that, we change the extract time function:
(defun org-wild-notifier--extract-time (marker)
"Extract timestamps from MARKER.
Timestamps are extracted as cons cells. car holds org-formatted
string, cdr holds time in list-of-integer format."
(-non-nil
(--map
(let ((org-timestamp (org-entry-get marker it)))
(and org-timestamp
(cons org-timestamp
(org-wild-notifier--timestamp-parse org-timestamp))))
'("DEADLINE" "SCHEDULED" "TIMESTAMP"))))
I am new to emacs and elisp in general. How do you implement this? In particular, how to get the org-wild-notifier to call the org-wild-notifier--extract-time function?
I don't know if this will be incompatible with newer versions, as I haven't updated the repo since then I wrote that a year ago. Although, this is how I did it:
I cloned the repo in my private config (locally), then I imported the package from my local copy of the repo. My import looks like this:
(use-package! org-wild-notifier
:load-path "~/.doom.d/lisp/org-wild-notifier.el"
:after org
:config
(setq org-wild-notifier-keyword-whitelist '())
(setq org-wild-notifier-keyword-blacklist '("DONE"))
(setq org-wild-notifier-alert-time '(5))
(org-wild-notifier-mode)
)
I'm using doom-emacs, so you might have to google how to import a local package with the package loader you are using.
Then you can subsitute the defun of the org-wild-notifier--extract-time function in the local repo with the one I showed.
Sorry, guys, I'm such a mess.
Edit: It works. Thanks @xzebra!
After changing the org-wild-notifier.el, I didnt run doom build to remove the stale elc file which is required.
@xzebra Thanks for the swift reply. I tested on the latest version. On my system, seems like the hack does not have any effect. It still only show notification if the date in the timestamp matches with the current date
** Lecture <2021-11-23 Tue 12:00-15:00 .+1d> ;; No notification
** Lecture <2021-11-25 Thu 12:00-15:00 .+1d>
As a workaround, I'm using this hacks:
I added a new function, which is the responsible of better parsing a timestamp. In case it is a cyclic timestamp, it gets the closest date cycle until today.
(defun org-wild-notifier--timestamp-parse (timestamp) (let ((parsed (org-parse-time-string timestamp)) (today (org-format-time-string "<%Y-%m-%d>"))) ;; seconds-to-time returns also milliseconds and nanoseconds so we ;; have to "trim" the list (butlast (seconds-to-time (org-time-add ;; we get the cycled absolute day (not hour and minutes) (org-time-from-absolute (org-closest-date timestamp today 'past)) ;; so we have to add the minutes too (+ (* (decoded-time-hour parsed) 3600) (* (decoded-time-minute parsed) 60)))) 2) ))As
org-closest-datereturns the time of the absolute day (no hour or minutes considered), we have to sum the hours and minutes to the date.After that, we change the extract time function:
(defun org-wild-notifier--extract-time (marker) "Extract timestamps from MARKER. Timestamps are extracted as cons cells. car holds org-formatted string, cdr holds time in list-of-integer format." (-non-nil (--map (let ((org-timestamp (org-entry-get marker it))) (and org-timestamp (cons org-timestamp (org-wild-notifier--timestamp-parse org-timestamp)))) '("DEADLINE" "SCHEDULED" "TIMESTAMP"))))
@akhramov Thanks for creating this package! Do you have a fix for this?
Glad to hear that!
oh god it works! can't believe that. never been this stressed my entire life. Why hasn't this been merged? It works perfectly even two years after it has been written!
seems like this was fixed.