0

Hi I would like to use the built-in notifications library in emacs with org mode (requires compiling with d-bus). I am trying to get it setup so that I can open my daily agenda view upon startup and have this trigger a series of (run-at-time .. calls that will run ~10 before the actual deadline. Problem is, I cannot seem to extract an alist of DEALINE . TIME entries of the deadlines in my agenda.

I have tried using the built-in org-agenda-get-deadlines but it does not seem to work as running (org-agenda-get-deadlines) results in a error.

I have tried "org-alert" and "alert" but they do not appear to work. Guessing some of their dependencies are depreciated or something.

How would I go about doing this?

UPDATE

HUGE thanks to @NickD for the help, here is what I have now in my setup. (Obviously could use some cleanup, but too excited atm).

(require 'appt)
(appt-activate 1)

(use-package notifications
  :demand t)

(setq appt-display-format 'window)

(setq appt-disp-window-function
      (lambda (nmins curtime msg)
        (notifications-notify :title "RING! RING! RING!"
                              :body (format "You have the appointment %s in %d minutes" msg (string-to-number nmins))
                              :app-name "Emacs: Org"
                              :sound-name "alarm-clock-elapsed")
        ))

(use-package org-agenda
  :init
  (setq org-agenda-finalize-hook 'org-agenda-to-appt)
  )

Obviously this requires opening your agenda at least once (and an emacs compiled with D-Bus support), but after that I get a nice

enter image description here

popup to appear starting within the appt-message-warning-time minutes of my scheduled deadline. Along with a reminder every appt-display-interval minutes within that time frame.

UPDATE 2 Just now noticing this, but you need to enter time in military time for it to work. AM/PM will show deadline in agenda but for some reason appt fails to pick it up. But this only applies if you edit the time manually. If you use the prompt then it looks like org fixes it to military time stamp.

PS

Wonder if there is a way to have the notifications to appear without initially opening the agenda if you work with an emacs compiled with systemd support? Donno whether the agenda can be opened in a daemon tho.

1

1 Answer 1

1

You can use the appt package, in combination with org-agenda-to-appt to get notifications from agenda items. Something like this should be enough:

(require "appt")
(org-agenda-to-appt)
(appt-activate 1)

org-agenda-to-appt adds all the relevant agenda entries to an appt list, that the appt package then uses for notifying you about them.

You will need to eval org-agenda-to-appt every day to get that day's entries into the appointment list for that day. You will also need to call it if you add items to the agenda during the day. I define a timer to run a function to do the "every day part": set the appt list for the day and reset the timer for next day - like this:

(defun ndk/agenda-to-appt()
  ;; reset the appt list and initialize it from the agenda
  (setq appt-time-msg-list nil)
  (org-agenda-to-appt))

(defun ndk/agenda-to-appt-and-reset-timer ()
  ;; initialize appt list for today and reset the timer to run again for tomorrow.
  (ndk/agenda-to-appt)
  (setq ndk/org-appt-timer 
    (run-at-time "24:01" nil 
             #'ndk/agenda-to-appt-and-reset-timer)))

;;; eval the function to get the ball rolling
;;; save the timer in ndk/org-appt-timer so it can be cancelled if necessary
;;; with:
;;;     (cancel-timer ndk/org-appt-timer)
(setq ndk/org-appt-timer (ndk/agenda/to-appt-and-reset-timer))

For the "add another thing to the agenda during the day" part, I add an after advice to org-agenda-redo to run the ndk/agenda-to-appt function above, so after I add an event, I can press g in the agenda to redisplay it and reinitialize the appt list:

(defadvice  org-agenda-redo (after org-agenda-redo-add-appts)
  "Pressing `r' or or `g' in the agenda will also add appointments."
  (ndk/agenda-to-appt))
(ad-activate 'org-agenda-redo)

(This code is old: there is a newer method of advising functions, but that's left as an exercise for the interested reader.)

Finally, the appt package allows you to customize your notifications using the variables appt-display-format and appt-disp-window-function: do (setq appt-display format 'window) and set the latter to a function that uses whatever notification system you want - that's left for you to do since I don't know anything about the notifications library:

(setq appt-display-format 'window)

(defun my/notify-function (nmins curtime msg)
   ;; use some notification system to output a message composed of the arguments:
   ;; nmins is the number of minutes to the appt, msg is a description of the appt.
    ...
)

(setq appt-disp-window-function #'my/notify-function)

There is a very similar setup described in Org Hacks in Worg (the Org Wiki). The most significant difference is that instead of advising org-agenda-redo, the author prefers to add the update to org-agenda-finalize-hook. You might want to experiment and see if you prefer one method over the other.

2
  • Thanks for the thorough response. I haven't had a chance to give your full answer a try yet but I'll update on this tomorrow.
    – skyfire
    Sep 2, 2020 at 1:42
  • I added some missing initialization to the first code block: please make sure that you get the updated code.
    – NickD
    Sep 2, 2020 at 3:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.