org-mode: Шедулинг дерева на определенную дату

Час­то воз­ни­ка­ет не­об­хо­ди­мость за­пла­ни­ро­вать ка­кую-то слож­ную шту­ку к опре­де­лен­ной да­те. Напри­мер, это экс­пе­ди­ции, ММБ, тре­ни­ро­воч­ный план и т.д. То есть, не­кое ме­ропри­ятие, к ко­то­ро­му на­до на­чи­нать го­то­вить­ся за­ранее и ко­то­рое со­дер­жит к се­бе ку­чу от­дель­ных за­дач, каж­дое со сво­им сме­ще­ни­ем от ос­нов­ной да­ты. Рань­ше для ре­ше­ния этой за­да­чи я на­пи­сал сис­те­му темпле­йтов в org-mode, но ока­за­лось слиш­ком слож­но.

Это вто­рая по­пы­тка: ме­ропри­ятие опи­сы­ва­ем в стан­дарт­ном ви­де, а по­том спе­ци­аль­ная функ­ция ко­пи­ру­ет всё под­де­ре­во с со­раз­мер­ным сдви­гом всех дат. Функ­ция:

(defun my-org-clone-to-date ()
  "Clone current subtree into specified file with all dates shifted to the same period."
  (interactive)
  (let* ((title (message (nth 4 (org-heading-components))))
         (orig-date (org-time-string-to-absolute (org-entry-get nil "SCHEDULED")))
         (dest-date (org-time-string-to-absolute
                     (org-read-date nil nil nil (format "Дата для '%s'" title))))
         (offset (format "+%id" (- dest-date orig-date))))
    (org-copy-subtree)
    (with-temp-buffer
      (org-mode)
      (org-paste-subtree)
      (org-clone-subtree-with-time-shift 1 offset)
      (org-forward-element)
      (org-refile))))

Ска­жем, у нас есть ша­блон ве­черин­ки:

* Грандиозная вечеринка
  SCHEDULED: <2019-05-01 Ср>

** TODO Позвать друзей
   SCHEDULED: <2019-04-29 Пн>
** TODO Купить всё необходимое
   SCHEDULED: <2019-04-30 Вт>

Если мы в кор­не­вом за­го­лов­ке по­зо­вем на­шу функ­цию и ука­жем да­ту [2020-03-06 Пт], то по­лу­чим де­ре­во с со­всем дру­ги­ми да­та­ми:

* Грандиозная вечеринка
  SCHEDULED: <2020-03-06 Пт>

** TODO Позвать друзей
   SCHEDULED: <2020-03-04 Ср>
** TODO Купить всё необходимое
   SCHEDULED: <2020-03-05 Чт>

По-мо­ему, по­лу­чи­лось удоб­но.

Создано при помощи Hugo
Тема Stack, дизайн Jimmy