Pokaż wolne bloki czasu w porządku dziennym trybu org

12

Chciałbym ułatwić znalezienie wolnych bloków czasu w mojej agendzie w trybie org.

Na przykład, jeśli mam dwa spotkania, jeden: 9:30 - 10:30 i drugi 11:15 - 12:30, chciałbym na pierwszy rzut oka zobaczyć, że blok 10:30 - 11:15 jest bezpłatny.

Innymi słowy, chcę móc rozróżniać czas wolny tak łatwo, jak dzieje się to w graficznym programie, takim jak kalendarz Google.

Czy istnieje sposób, aby łatwo było zobaczyć puste bloki czasu? Może pokolorować puste bloki dłuższe niż określona liczba minut?

scaramouche
źródło
2
Czy to org-agenda-time-gridnie wystarcza dla twoich potrzeb? gnu.org/software/emacs/manual/html_node/org/…
lista prawna
2
Siatka nie jest wystarczająca, ponieważ pokazuje się, nawet gdy czas jest zajęty (np. Jeśli jest spotkanie w godzinach 9:30 - 10:30, linia siatki będzie o 10:00). Chciałbym, aby czasy zajęte i nie zajęte były łatwe do rozróżnienia.
scaramouche
1
Myślałem trochę więcej o tej funkcjonalności. Uważam, że najbardziej użytecznym i najprostszym do wdrożenia byłoby zmiana koloru bloku czasowego (tylko nazwa bloku czasowego, np. 8: 00–9: 00) dla tych bloków czasowych, które mają więcej niż określoną ilość czas wolny (np. ponad 15 minut). Zarówno kolor, jak i minimalny czas wolny powinny być konfigurowalne przez użytkownika.
scaramouche
3
@scaramouche, użytkownik na liście mailingowej w trybie org ( orgmode.org/worg/org-mailing-list.html ) pyta, czy próbowałeś calfw( emacswiki.org/emacs/Calfw ).
daveloyall
2
@daveloyall, wielkie dzięki za wskazanie na dyskusję o liście mailowej. Właśnie wypróbowałem cielęcinę (i jest piękna!), Ale wydaje się, że nie ma funkcji, którą chcę (wizualnie dostrzega godziny otwarcia w ciągu dnia). Dla tych, którzy chcą wypróbować calfw + org (wysoce zalecane): zdobądź cielę z Melpy, w init.el, dołącz (require 'calfw-org)i zadzwoń do kalendarza M-x cfw:open-org-calendar.
scaramouche

Odpowiedzi:

2

Z powodu tego własnego pytania spojrzałem na funkcję, org-agenda-add-time-grid-maybektóra tworzy siatkę czasu. Umieszczony tam kod (który nie jest napisany przeze mnie) usuwa linię siatki, jeśli czas jest zajęty, zgodnie z żądaniem w komentarzu PO.

Tak jak ty chciałem w jakiś sposób stworzyć blok wizualny. Mieszając oryginalny kod org-agenda-add-time-grid-maybei defadvice Michaela Ekstranda opublikowanego w innym wątku, wymyśliłem następujący kod org-agenda-add-time-grid-maybe. Wyprowadzi linie siatki w innym kolorze (w tej chwili używam twarzy org-archived), a po czasach pojawi się inny ciąg. Oba można zmienić według własnych upodobań.

(defun org-agenda-add-time-grid-maybe (list ndays todayp)
  "Add a time-grid for agenda items which need it.

LIST is the list of agenda items formatted by `org-agenda-list'.
NDAYS is the span of the current agenda view.
TODAYP is t when the current agenda view is on today."

  (catch 'exit
   (cond ((not org-agenda-use-time-grid) (throw 'exit list))
         ((and todayp (member 'today (car org-agenda-time-grid))))
         ((and (= ndays 1) (member 'daily (car org-agenda-time-grid))))
         ((member 'weekly (car org-agenda-time-grid)))
         (t (throw 'exit list)))
   (let* ((blocks (mapcar (lambda (x)
                            (let ((start (get-text-property 1 'time-of-day x))
                                  (dur (get-text-property 1 'duration x)))
                              (cond
                               ((and start dur) (cons start
                                                      (org-time-from-minutes
                                                       (truncate
                                                        (+ dur (org-time-to-minutes start))))))
                               (start start)
                               (t nil))))
                          list))
          (have (delq nil (mapcar
                           (lambda (x) (get-text-property 1 'time-of-day x))
                           list)))
          (string (nth 3 org-agenda-time-grid))
          (gridtimes (nth 1 org-agenda-time-grid))
          (req (car org-agenda-time-grid))
          (remove (member 'remove-match req))
          new time)
     (if (and (member 'require-timed req) (not have))
         ;; don't show empty grid
         (throw 'exit list))

     (while (setq time (pop gridtimes))
       (unless (and remove (member time have))
         (let* ((windows (delq nil blocks))
                (hit nil))
           (dolist (busy windows)
             (unless hit
               (when (and (>= time (car busy))
                          (< time (cdr busy)))
                 (setq hit t))))
           (setq time (replace-regexp-in-string " " "0" (format "%04s" time)))
           (if hit
               (progn
                 (push (org-agenda-format-item
                        (concat string " dito") string nil "" nil
                        (concat (substring time 0 -2) ":" (substring time -2)))
                       new)
                 (put-text-property 2 (length (car new)) 'face 'org-archived (car new)))
             (progn
               (push (org-agenda-format-item
                      nil string nil "" nil
                      (concat (substring time 0 -2) ":" (substring time -2)))
                     new)
               (put-text-property 2 (length (car new)) 'face 'org-time-grid (car new))))
           (setq hit nil))))

     (when (and todayp org-agenda-show-current-time-in-grid)
       (push (org-agenda-format-item
              nil org-agenda-current-time-string nil "" nil
              (format-time-string "%H:%M "))
             new)
       (put-text-property
        2 (length (car new)) 'face 'org-agenda-current-time (car new)))

     (if (member 'time-up org-agenda-sorting-strategy-selected)
         (append new list)
       (append list new)))))

(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)))

Oczywiście bardziej elegancko byłoby zastosować defawizację, ale nie wiedziałem, gdzie dokładnie interweniować. Sama funkcja przechodzi przez każdy czas siatki (ustawiony w org-agenda-time-grid) i tworzy nową listę z ostateczną siatką zawierającą ściany (nowe).

fabiański
źródło
1
Przydatne, ale naprawdę mam nadzieję, że ktoś wymyśli rozwiązanie, które nie wymaga bezpośredniego zastąpienia funkcji org-agenda.
holocronweaver
Absolutnie się zgadzam! Niestety, moja znajomość elisp i kodu trybu org nie jest wystarczająca, aby wymyślić działającą defadvice. Być może ktoś inny może tutaj pomóc, być może wykorzystując część „mojego” kodu.
Fabian