个人日程管理的逻辑

这个现实世界太复杂,而我又那么无助……

诸多因素导致我的待办事务、邮件、日期提醒、事务预约等错综复杂、相互干扰。 而如何快速合理地整合这些纷纷扰扰,怎可能难住一个电脑专业人士!

日程管理的核心逻辑是,碰到尘世间纷纷扰扰,把其扔进日程管理系统。 然后,让系统每天自动生成待办事项的报告。 就好比是一个不吃不喝的秘书,我们遇到问题,直接把问题扔给秘书,然后要求秘书随时汇报当前需要办哪些事,近期需要办哪些事,远期需要办哪些事。

这个日程管理系统的必要功能是将各种待办事项进行排序, 且能够查看当前要办理哪些事务,然后查看近期还有哪些事需要办,再然后查看远期还有哪些事务需要办。 这样就实现了对短程、中程、长程任务的全场景、全任务、无死角地覆盖。

先设置默认的行为,记录完成事物的时间:

(setq org-log-done 'time)
(setq org-agenda-start-with-log-mode t)

再设置各种类型自定义查询命令:

(setq org-agenda-custom-commands
            '(
              ("n" "Near plans"
               (
                (todo ""
                      (
                       (org-agenda-skip-function (lambda () (or
                                                             (org-agenda-skip-entry-if 'notscheduled)
                                                             (my-org/skip-todos-by-timestamp #'> 10))))
                       (org-agenda-prefix-format '((todo . " %i %-12:c %(my-org/get-scheduled-time) %s")))
                       (org-agenda-overriding-header "Near scheduled plans")))
                (todo ""
                      (
                       (org-agenda-skip-function (lambda () (or (my-org/skip-todos-by-repeated t)
                                                                (org-agenda-skip-entry-if 'notdeadline))))
                       (org-agenda-todo-ignore-deadlines 'far)
                       (org-agenda-prefix-format '((todo . " %i %-12:c %(my-org/get-deadline-time) %s")))
                       (org-agenda-overriding-header "Near deadline plans")))
                (todo ""
                      (
                       (org-agenda-skip-function (lambda () (or
                                                             (my-org/skip-todos-by-repeated nil)
                                                             (my-org/skip-todos-by-timestamp #'> 10))))
                       (org-agenda-prefix-format '((todo . " %i %-12:c %(my-org/get-scheduled-or-deadline-time) %s")))
                       (org-agenda-overriding-header "Near repeated plans")))
                ))
              ("sn" "Near scheduled plans"
               (
                (todo ""
                      (
                       (org-agenda-skip-function (lambda () (or
                                                             (org-agenda-skip-entry-if 'notscheduled)
                                                             (my-org/skip-todos-by-timestamp #'> 10))))
                       (org-agenda-prefix-format '((todo . " %i %-12:c %(my-org/get-scheduled-time) %s")))
                       (org-agenda-overriding-header "Near scheduled plans")))
                ))
              ("sf" "Far scheduled plans"
               (
                (todo ""
                      (
                       (org-agenda-skip-function (lambda () (or
                                                             (org-agenda-skip-entry-if 'notscheduled)
                                                             (my-org/skip-todos-by-timestamp #'<= 10))))
                       (org-agenda-prefix-format '((todo . " %i %-12:c %(my-org/get-scheduled-time) %s")))
                       (org-agenda-overriding-header "Far scheduled plans")))
                ))
              ("dn" "Near deadline plans"
               (
                (todo ""
                      (
                       (org-agenda-skip-function (lambda () (or (my-org/skip-todos-by-repeated t)
                                                                (org-agenda-skip-entry-if 'notdeadline))))
                       (org-agenda-todo-ignore-deadlines 'far)
                       (org-agenda-prefix-format '((todo . " %i %-12:c %(my-org/get-deadline-time) %s")))
                       (org-agenda-overriding-header "Near plans")))
                ))
              ("df" "Far deadline plans"
               (
                (todo ""
                      (
                       (org-agenda-skip-function (lambda () (or (my-org/skip-todos-by-repeated t)
                                                                (org-agenda-skip-entry-if 'notdeadline))))
                       (org-agenda-todo-ignore-deadlines 'near)
                       (org-agenda-prefix-format '((todo . " %i %-12:c %(my-org/get-deadline-time) %s")))
                       (org-agenda-overriding-header "Far plans")))
                ))
              ("rn" "Near repeated plans"
               (
                (todo ""
                      (
                       (org-agenda-skip-function (lambda () (or
                                                             (my-org/skip-todos-by-repeated nil)
                                                             (my-org/skip-todos-by-timestamp #'> 10))))
                       (org-agenda-prefix-format '((todo . " %i %-12:c %(my-org/get-scheduled-or-deadline-time) %s")))
                       (org-agenda-overriding-header "Near repeated plans")))
                ))
              ("rf" "Far repeated plans"
               (
                (todo ""
                      (
                       (org-agenda-skip-function (lambda () (or
                                                             (my-org/skip-todos-by-repeated nil)
                                                             (my-org/skip-todos-by-timestamp #'<= 10))))
                       (org-agenda-prefix-format '((todo . " %i %-12:c %(my-org/get-scheduled-or-deadline-time) %s")))
                       (org-agenda-overriding-header "Far repeated plans")))
                ))
              ("x" "No deadline plans"
               (
                (todo ""
                      (
                       (org-agenda-skip-function (lambda () (my-org/skip-todos-by-repeated t)))
                       (org-agenda-todo-ignore-with-date t)
                       (org-agenda-overriding-header "No deadline plans")))
                ))
              ("b" "Weekly review"
               (
                (agenda ""
                        (
                         (org-agenda-overriding-header "Completed tasks")
                         (org-agenda-span 'week)
                         (org-agenda-start-day "-6d")
                         (org-agenda-end-day "tomorrow")
                         (org-agenda-skip-function '(org-agenda-skip-entry-if 'nottodo 'done))
                         ))
                ))
              ))

设置重复待办事项的双向过滤器:

(defun my-org/skip-todos-by-repeated (skip-repeated)
  "Skip TODO items by the LAST_REPEAT property."
  (let ((has-repeated (org-entry-get nil "LAST_REPEAT")))
    (if (eq (eq nil skip-repeated) (eq nil has-repeated))
        (progn
          (outline-next-heading)
          (if (eobp)  ; End of buffer check
              (point-max)  ; Move to the end of the buffer
            (point))))))

给待办事项添加时间标签以及按照时间距离当前时间的远近所对应的背景渐变色:

(setq org-agenda-prefix-format '((todo . " %i %-12:c %(my-org/get-scheduled-or-deadline-time) %s")))
(add-hook 'org-agenda-finalize-hook #'my-org/color-dates-in-agenda)

需要用到的函数逻辑:

(defun my-org/scheduled-time-face (time-diff)
  "Return the appropriate face based on TIME-DIFF in seconds."
  (cond
    ((> time-diff 720) '(:foreground "black" :background "#00FF00"))
    ((> time-diff 360) '(:foreground "black" :background "#66FF66"))
    ((> time-diff 180) '(:foreground "black" :background "#99FF99"))
    ((> time-diff 90) '(:foreground "black" :background "#CCFFCC"))
    ((> time-diff 60) '(:foreground "black" :background "#FFCCCC"))
    ((> time-diff 30) '(:foreground "black" :background "#FF99FF"))
    ((> time-diff 15) '(:foreground "black" :background "#FF66FF"))
    ((> time-diff 7) '(:foreground "black" :background "#FF33FF"))
    ((> time-diff 0) '(:foreground "black" :background "#FF00FF"))
    (t '(:foreground "black" :background "red"))
    ))


  (defun my-org/get-scheduled-time ()
    "Return the scheduled time of the current Org entry as a string with a face."
    (let ((scheduled (org-get-scheduled-time (point))))
      (if scheduled
          (format-time-string "[%Y-%m-%d]" scheduled)
        "")))


  (defun my-org/get-deadline-time ()
    "Return the scheduled time of the current Org entry as a string with a face."
    (let ((dealined (org-get-deadline-time (point))))
      (if dealined
          (format-time-string "[%Y-%m-%d]" dealined)
        "")))

  (defun my-org/get-scheduled-or-deadline-time ()
    "Return the nearest scheduled or deadline time of the current Org entry as a string with a face."
    (let* ((scheduled (org-get-scheduled-time (point)))
           (deadline (org-get-deadline-time (point)))
           (nearest-time nil))
      (when (or scheduled deadline)
        (setq nearest-time
              (cond
               ((and scheduled deadline)
                (if (time-less-p scheduled deadline)
                    scheduled
                  deadline))
               (scheduled
                scheduled)
               (deadline
                deadline))))
      (if nearest-time
          (format-time-string "[%Y-%m-%d]" nearest-time)
        "")))

  (defun my-org/skip-todos-by-timestamp (comparison-fn days)
    "Skip TODO items by the LAST_REPEAT property."
    (let* ((scheduled (org-get-scheduled-time (point)))
           (deadline (org-get-deadline-time (point)))
           (nearest-time nil))
      (when (or scheduled deadline)
        (setq nearest-time
              (cond
               ((and scheduled deadline)
                (if (time-less-p scheduled deadline)
                    scheduled
                  deadline))
               (scheduled
                scheduled)
               (deadline
                deadline))))
      (if nearest-time
          (if (funcall comparison-fn
                       (-
                        (time-to-days nearest-time)
                        (time-to-days (current-time)))
                       days)
              (progn
                (outline-next-heading)
                (if (eobp)  ; End of buffer check
                    (point-max)  ; Move to the end of the buffer
                  (point)))))))


  (defun my-org/color-dates-in-agenda ()
    "Color scheduled dates based on their proximity to now in the agenda buffer."
    (let ((inhibit-read-only t))
      (save-excursion
        (goto-char (point-min))
        (let ((pattern "\\[\\([0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\}\\)\\]"))
          (while (re-search-forward pattern nil t)
            (let* ((date-str (match-string 1))
                   (date (date-to-time date-str))
                   (time-diff (- (time-to-days date) (time-to-days (current-time))))
                   (face (my-org/scheduled-time-face time-diff)))
              (let ((line-start (line-beginning-position))
                    (line-end (line-end-position)))
                (save-excursion
                  (goto-char line-start)
                  (if (re-search-forward pattern line-end t)
                      (put-text-property (match-beginning 0) (match-end 0) 'face face)
                    nil))
                )))))))

然后再配合org-super-agenda,构成了完美的日期自动管理系统。

石见 石页 /
在共享协议(CC)下发布于
类别: technology 
标签: emacs  日程管理  中