2

In my agenda I like to see the free blocks of time. As it was suggested in this thread I tried the approach with org-agenda-time-grid. The only problem with that was that the time-grid shows up even when the time is busy. By doing some research I found a solution on this page (Org ad hoc code, quick hacks and workarounds):

(defun org-time-to-minutes (time)
  "Convert an HHMM time to minutes"
  (+ (* (/ time 100) 60) (% time 100)))

(defun org-time-from-minutes (minutes)
  "Convert a number of minutes to an HHMM time"
  (+ (* (/ minutes 60) 100) (% minutes 60)))

(defadvice org-agenda-add-time-grid-maybe (around mde-org-agenda-grid-tweakify
                                                  (list ndays todayp))
  (if (member 'remove-match (car org-agenda-time-grid))
      (flet ((extract-window
              (line)
              (let ((start (get-text-property 1 'time-of-day line))
                    (dur (get-text-property 1 'duration line)))
                (cond
                 ((and start dur)
                  (cons start
                        (org-time-from-minutes
                         (+ dur (org-time-to-minutes start)))))
                 (start start)
                 (t nil)))))
        (let* ((windows (delq nil (mapcar 'extract-window list)))
               (org-agenda-time-grid
                (list (car org-agenda-time-grid)
                      (cadr org-agenda-time-grid)
                      (remove-if
                       (lambda (time)
                         (find-if (lambda (w)
                                    (if (numberp w)
                                        (equal w time)
                                      (and (>= time (car w))
                                           (< time (cdr w)))))
                                  windows))
                       (caddr org-agenda-time-grid)))))
          ad-do-it))
    ad-do-it))
(ad-activate 'org-agenda-add-time-grid-maybe)

This has worked great until the most recent update to org-mode was released (9.1). There is a new org duration library (org-duration.el) and with its introduction several functions became obsolete which broke the above mentioned defadvice.

To my (amateurish) unterstanding the problem is that the org duration library works with strings which also contain colons (e.g. 19:30 instead of 1930). This is why I have tried to change the functions org-time-to-minutes and org-time-from-minutes to output strings with colons as well. This did not work, however, which is why I am hoping for the community to find a fix.

(Edit: To be honest my ideal solution would not remove the grid lines which are in the range of an appointment but rather change them in a way that there is a visual time block, e.g. by changing the color of the grid lines. But since this is probably much more difficult to achieve, I would already be happy with a fix of the defadvice.)

1 Answer 1

2

I was wrong. It had nothing to do with the org-duration library. There were two different problems:

  1. The order of items in org-agenda-time-grid changed. (The list of integers, indicating the times that should have a grid line is now the second item.) This is why I had to also change the order in the second part of the defadvice.
  2. The function could not do its calculation anymore because the intermediate result was a float instead of an integer. This could be fixed by using the truncate function.

My solution (still the code of Michael Ekstrand with slight alterations):

(defadvice org-agenda-add-time-grid-maybe (around mde-org-agenda-grid-tweakify
                                                  (list ndays todayp))
  (if (member 'remove-match (car org-agenda-time-grid))
      (flet ((extract-window
              (line)
              (let ((start (get-text-property 1 'time-of-day line))
                    (dur (get-text-property 1 'duration line)))
                (cond
                 ((and start dur)
                  (cons start
                        (org-time-from-minutes
                         (truncate
                          (+ dur (org-time-to-minutes start))))))
                 (start start)
                 (t nil)))))
        (let* ((windows (delq nil (mapcar 'extract-window list)))
               (org-agenda-time-grid
                (list
                 (car org-agenda-time-grid)
                 (remove-if
                  (lambda (time)
                    (find-if (lambda (w)
                               (if (numberp w)
                                   (equal w time)
                                 (and (>= time (car w))
                                      (< time (cdr w)))))
                             windows))
                  (cadr org-agenda-time-grid) )
                 (caddr org-agenda-time-grid)
                 (cadddr org-agenda-time-grid)
                 )))
          ad-do-it))
    ad-do-it))
(ad-activate 'org-agenda-add-time-grid-maybe)

Your Answer

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

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