Org-mode, 用文本文件管理日常(九)

13 篇文章 0 订阅
本节主要介绍作者GTD流程,都是实操性很强的流程,理解流程能够更深入理解org-mode任务管理精髓。

1 GTD 相关

我每天都是截止日期/计划任务驱动的。

每天,第一件事,我会打开agenda视图然后从中选择合适任务来处理,详情参看我是如何确定下一个任务章节。

1.1 每周审查流程

每周第一天(通常周一)我会完成每周审查。 我会像这样保留一个列表来提醒我哪些需要完成。

为保证agenda够快,我设置如下参数

(setq org-agenda-span 'day)

因此默认只有今天的任务才会显示出来。只有每周评审时候我才需要周视图,这使得我的agenda 生成的非常快。

我有个重复任务,可以保证我的每周评审方便处理。每周一会弹出提醒。但是这周评审 是周二完成的因为周一放假。

* NEXT Weekly Review [0/6]
  SCHEDULED: <2009-05-18 Mon ++1w> 
  :LOGBOOK:...
  :PROPERTIES:...

  What to review:

   - [ ] Check follow-up folder
   - [ ] Review weekly agenda =F12 a w //=
   - [ ] Check clocking data for past week =v c=
   - [ ] Review clock report for past week =R=
     - Check where we spent time (too much or too little) and rectify this week
   - [ ] Look at entire agenda for today  =F12 SPC=
   - [ ] Review projects =F12 SPC //= and =V= repeatedly to view each project

   - start work
     - daily agenda first - knock off items
     - then work on NEXT tasks

第一个[]条目用来跟踪文件夹,这项任务使得我能从浩如烟海的纸质文档抽出身来-那些我 需要处理但是不是特别紧急的任务。例如收到的大量邮件情况,我暂时不想要处理。 我只要将它们放入我的 Follow-up 文件夹接下来就可以不用管了,直到每周评审时。

我会过一遍这个文件夹中任务,选出那些需要处理的任务。之后这些任务将会移到 org-mode 文件中。我会对任务设置计划,这样任务后续就会显示到agenda视图中,接下来只要根据 agenda任务列表来处理任务即可。

这个流程非常适合我,对于其他人可能需要调整。

1.2 项目定义以及找出无法推进的项目

我使用一个简单的项目定义来标记任务为一个项目。这不需要额外花经历处理。任何任务 只要有个带todo关键字的子任务,那么这个任务就是项目。

项目中如果没有任意子任务包含 NEXT 关键字,那么这个任务就是无法推进的项目。

org agenda中有单独视图来显示无法推进项目列表。当有受阻项目显示在我的agenda视图 我会将其设置为 NEXT 任务,这样就会保证无法推进列表是空的。同时可以保证项目 继续进行。

我通过如下设置禁用org-mode无法推进项目的agenda视图。

(setq org-stuck-projects (quote ("" nil nil "")))

这可以避免org-mode显示我通过 F12 # 显示的项目。我的定制化受阻项目视图 是我的agenda视图的一部分,可以通过 F12 SPC 来查看。

项目中有可能包含子项目-子项目也有可能无法推进。子项目无法推进时,也是显示在无法 推进项目列表中,因此我可以创建 NEXT 任务推进项目继续进行。

下面的例子中 Stuck Project A 是无法推进项目,因为它子任务都不在 NEXT 状态。

Project C 却不是,因为它包含 NEXT 状态任务 SubTask G 以及 = Task I= . Stuck Sub Project D 也是无法推进项目,因为 SubTask E 并没有 NEXT 状态 也没有其他可以处理的任务。

* Category
** TODO Stuck Project A
*** TODO Task B
** TODO Project C
*** TODO Stuck Sub Project D
**** TODO SubTask E
*** TODO Sub Project F
**** NEXT SubTask G
**** TODO SubTask H
*** NEXT Task I
*** TODO Task J

所有的无法推进项目以及子项目将会一直显示在无法推进列表,直到新建或者修改既有任务 状态到 NEXT 。 如果项目有任务处在 WAITING 状态,等待某些条件得到 满足。 这种情况,我会将他们一直保持在无法推进项目列表,去做其他事情,待到等待条件满足 就可以将项目从无法推进项目列表移除。无法推进项目会非常醒目,能够及时提醒我, 当我查看agenda 视图时,看到有无法推进项目,我就会一直跟踪等待任务是否完成。

下面是一些辅助函数来帮我判定任务是否是项目并用在agenda视图中。

(defun bh/is-project-p ()
  "Any task with a todo keyword subtask"
  (save-restriction
    (widen)
    (let ((has-subtask)
          (subtree-end (save-excursion (org-end-of-subtree t)))
          (is-a-task (member (nth 2 (org-heading-components)) org-todo-keywords-1)))
      (save-excursion
        (forward-line 1)
        (while (and (not has-subtask)
                    (< (point) subtree-end)
                    (re-search-forward "^\*+ " subtree-end t))
          (when (member (org-get-todo-state) org-todo-keywords-1)
            (setq has-subtask t))))
      (and is-a-task has-subtask))))

(defun bh/is-project-subtree-p ()
  "Any task with a todo keyword that is in a project subtree.
Callers of this function already widen the buffer view."
  (let ((task (save-excursion (org-back-to-heading 'invisible-ok)
                              (point))))
    (save-excursion
      (bh/find-project-task)
      (if (equal (point) task)
                   nil
        t))))

(defun bh/is-task-p ()
  "Any task with a todo keyword and no subtask"
  (save-restriction
    (widen)
    (let ((has-subtask)
          (subtree-end (save-excursion (org-end-of-subtree t)))
          (is-a-task (member (nth 2 (org-heading-components)) org-todo-keywords-1)))
      (save-excursion
        (forward-line 1)
        (while (and (not has-subtask)
                    (< (point) subtree-end)
                    (re-search-forward "^\*+ " subtree-end t))
          (when (member (org-get-todo-state) org-todo-keywords-1)
            (setq has-subtask t))))
      (and is-a-task (not has-subtask)))))

(defun bh/is-subproject-p ()
  "Any task which is a subtask of another project"
  (let ((is-subproject)
        (is-a-task (member (nth 2 (org-heading-components)) org-todo-keywords-1)))
    (save-excursion
      (while (and (not is-subproject) (org-up-heading-safe))
        (when (member (nth 2 (org-heading-components)) org-todo-keywords-1)
          (setq is-subproject t))))
    (and is-a-task is-subproject)))

(defun bh/list-sublevels-for-projects-indented ()
  "Set org-tags-match-list-sublevels so when restricted to a subtree we list all subtasks.
  This is normally used by skipping functions where this variable is already local to the agenda."
  (if (marker-buffer org-agenda-restrict-begin)
      (setq org-tags-match-list-sublevels 'indented)
    (setq org-tags-match-list-sublevels nil))
  nil)

(defun bh/list-sublevels-for-projects ()
  "Set org-tags-match-list-sublevels so when restricted to a subtree we list all subtasks.
  This is normally used by skipping functions where this variable is already local to the agenda."
  (if (marker-buffer org-agenda-restrict-begin)
      (setq org-tags-match-list-sublevels t)
    (setq org-tags-match-list-sublevels nil))
  nil)

(defvar bh/hide-scheduled-and-waiting-next-tasks t)

(defun bh/toggle-next-task-display ()
  (interactive)
  (setq bh/hide-scheduled-and-waiting-next-tasks (not bh/hide-scheduled-and-waiting-next-tasks))
  (when  (equal major-mode 'org-agenda-mode)
    (org-agenda-redo))
  (message "%s WAITING and SCHEDULED NEXT Tasks" (if bh/hide-scheduled-and-waiting-next-tasks "Hide" "Show")))

(defun bh/skip-stuck-projects ()
  "Skip trees that are not stuck projects"
  (save-restriction
    (widen)
    (let ((next-headline (save-excursion (or (outline-next-heading) (point-max)))))
      (if (bh/is-project-p)
          (let* ((subtree-end (save-excursion (org-end-of-subtree t)))
                 (has-next ))
            (save-excursion
              (forward-line 1)
              (while (and (not has-next) (< (point) subtree-end) (re-search-forward "^\\*+ NEXT " subtree-end t))
                (unless (member "WAITING" (org-get-tags-at))
                  (setq has-next t))))
            (if has-next
                nil
              next-headline)) ; a stuck project, has subtasks but no next task
        nil))))

(defun bh/skip-non-stuck-projects ()
  "Skip trees that are not stuck projects"
  ;; (bh/list-sublevels-for-projects-indented)
  (save-restriction
    (widen)
    (let ((next-headline (save-excursion (or (outline-next-heading) (point-max)))))
      (if (bh/is-project-p)
          (let* ((subtree-end (save-excursion (org-end-of-subtree t)))
                 (has-next ))
            (save-excursion
              (forward-line 1)
              (while (and (not has-next) (< (point) subtree-end) (re-search-forward "^\\*+ NEXT " subtree-end t))
                (unless (member "WAITING" (org-get-tags-at))
                  (setq has-next t))))
            (if has-next
                next-headline
              nil)) ; a stuck project, has subtasks but no next task
        next-headline))))

(defun bh/skip-non-projects ()
  "Skip trees that are not projects"
  ;; (bh/list-sublevels-for-projects-indented)
  (if (save-excursion (bh/skip-non-stuck-projects))
      (save-restriction
        (widen)
        (let ((subtree-end (save-excursion (org-end-of-subtree t))))
          (cond
           ((bh/is-project-p)
            nil)
           ((and (bh/is-project-subtree-p) (not (bh/is-task-p)))
            nil)
           (t
            subtree-end))))
    (save-excursion (org-end-of-subtree t))))

(defun bh/skip-non-tasks ()
  "Show non-project tasks.
Skip project and sub-project tasks, habits, and project related tasks."
  (save-restriction
    (widen)
    (let ((next-headline (save-excursion (or (outline-next-heading) (point-max)))))
      (cond
       ((bh/is-task-p)
        nil)
       (t
        next-headline)))))

(defun bh/skip-project-trees-and-habits ()
  "Skip trees that are projects"
  (save-restriction
    (widen)
    (let ((subtree-end (save-excursion (org-end-of-subtree t))))
      (cond
       ((bh/is-project-p)
        subtree-end)
       ((org-is-habit-p)
        subtree-end)
       (t
        nil)))))

(defun bh/skip-projects-and-habits-and-single-tasks ()
  "Skip trees that are projects, tasks that are habits, single non-project tasks"
  (save-restriction
    (widen)
    (let ((next-headline (save-excursion (or (outline-next-heading) (point-max)))))
      (cond
       ((org-is-habit-p)
        next-headline)
       ((and bh/hide-scheduled-and-waiting-next-tasks
             (member "WAITING" (org-get-tags-at)))
        next-headline)
       ((bh/is-project-p)
        next-headline)
       ((and (bh/is-task-p) (not (bh/is-project-subtree-p)))
        next-headline)
       (t
        nil)))))

(defun bh/skip-project-tasks-maybe ()
  "Show tasks related to the current restriction.
When restricted to a project, skip project and sub project tasks, habits, NEXT tasks, and loose tasks.
When not restricted, skip project and sub-project tasks, habits, and project related tasks."
  (save-restriction
    (widen)
    (let* ((subtree-end (save-excursion (org-end-of-subtree t)))
           (next-headline (save-excursion (or (outline-next-heading) (point-max))))
           (limit-to-project (marker-buffer org-agenda-restrict-begin)))
      (cond
       ((bh/is-project-p)
        next-headline)
       ((org-is-habit-p)
        subtree-end)
       ((and (not limit-to-project)
             (bh/is-project-subtree-p))
        subtree-end)
       ((and limit-to-project
             (bh/is-project-subtree-p)
             (member (org-get-todo-state) (list "NEXT")))
        subtree-end)
       (t
        nil)))))

(defun bh/skip-project-tasks ()
  "Show non-project tasks.
Skip project and sub-project tasks, habits, and project related tasks."
  (save-restriction
    (widen)
    (let* ((subtree-end (save-excursion (org-end-of-subtree t))))
      (cond
       ((bh/is-project-p)
        subtree-end)
       ((org-is-habit-p)
        subtree-end)
       ((bh/is-project-subtree-p)
        subtree-end)
       (t
        nil)))))

(defun bh/skip-non-project-tasks ()
  "Show project tasks.
Skip project and sub-project tasks, habits, and loose non-project tasks."
  (save-restriction
    (widen)
    (let* ((subtree-end (save-excursion (org-end-of-subtree t)))
           (next-headline (save-excursion (or (outline-next-heading) (point-max)))))
      (cond
       ((bh/is-project-p)
        next-headline)
       ((org-is-habit-p)
        subtree-end)
       ((and (bh/is-project-subtree-p)
             (member (org-get-todo-state) (list "NEXT")))
        subtree-end)
       ((not (bh/is-project-subtree-p))
        subtree-end)
       (t
        nil)))))

(defun bh/skip-projects-and-habits ()
  "Skip trees that are projects and tasks that are habits"
  (save-restriction
    (widen)
    (let ((subtree-end (save-excursion (org-end-of-subtree t))))
      (cond
       ((bh/is-project-p)
        subtree-end)
       ((org-is-habit-p)
        subtree-end)
       (t
        nil)))))

(defun bh/skip-non-subprojects ()
  "Skip trees that are not projects"
  (let ((next-headline (save-excursion (outline-next-heading))))
    (if (bh/is-subproject-p)
        nil
      next-headline)))

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值