给 org TODO 任务设置默认的 effort 的方法

agend file 里一个任务和其分解如下

 * 主任务
 ** 分解后子任务 1
 ** 分解后子任务 2
 ** 分解后子任务 3
 ** 分解后子任务 4
 ** 分解后子任务 5
 ** 分解后子任务 6

假设我分解任务的时候将各个子任务都刻意控制在 30 分钟左右,那么如果要使用 effort, 我需要为每个子任务都加上相同的 effort PROPERTIES

* 主任务
** 分解后子任务 1
:PROPERTIES:
:Effort:   0:30
:END:
** 分解后子任务 2
:PROPERTIES:
:Effort:   0:30
:END:
** 分解后子任务 3
:PROPERTIES:
:Effort:   0:30
:END:
** 分解后子任务 4
:PROPERTIES:
:Effort:   0:30
:END:
** 分解后子任务 5
:PROPERTIES:
:Effort:   0:30
:END:
** 分解后子任务 6
:PROPERTIES:
:Effort:   0:30
:END:

这样我在 clock in 每个子任务的时候 modeline 才会显示类似 [0:00/0:30] 的时间信息,到了 30 分钟该信息会变红,提醒我任务要超时了

我的需求是,既然已经把各个任务都分解到了同样的时间间隔,我就只需要在主任务层级或者文件层级设置一个全局的 effort 选项, 使得子任务都继承这个 effort, 这样我就不需要重复地设置相同的 effort properties 了,以此减少很多冗余行

一种期望的(无效)设置方法如下:

* 主任务
:PROPERTIES:
:Effort:   0:30
# 我希望这个选项对所有 subtree 甚至 subsubtree 都递归地设置同样的 effort
# 但这种写法只对主任务有用
:END:
** 分解后子任务 1
** 分解后子任务 2
** 分解后子任务 3
** 分解后子任务 4
** 分解后子任务 5
** 分解后子任务 6

我的最终目的实际是希望对每个任务 clock in 的时候都显示一个默认的 effort 来提醒

例如,以下例子,希望所有的分解任务在 clock in 的时候都自动显示 [0:00/0:30] 这样的计时样式,只有 分解后子任务 2 在 clock in 后显示 [0:00/0:15], 因为它单独设置了特定的 effort

* 主任务
** 分解后子任务 1
** 分解后子任务 2
:PROPERTIES:
:Effort:   0:15
:END:
** 分解后子任务 3
** 分解后子任务 4
** 分解后子任务 5
** 分解后子任务 6

因此可能不需要考虑设置全局属性的问题,也许在 clock in 函数加一个 hook 就可以?

不知是否已经有现成的实现方案,在此讨教

Org Property Inheritance 之类的东西,可能要改一下 Clock 获取 Entry Effort 时候的逻辑。

摘自 org-use-property-inheritance 文档

When querying an entry with org-entry-get, you can control if inheritance
should be used.  By default, org-entry-get looks only at the local
properties.  You can request inheritance by setting the inherit argument
to t (to force inheritance) or to selective (to respect the setting
in this variable).

有一个人写了个 elfeed score 的插件,是针对 elfeed 的 rss 条目做自动重要性排列的。

他的实现思路是,用某个数值代表基准值,涉及到某些关键字时,则加权。

你可以看看它的实现思路——

Top (elfeed-score)

感谢,最近抽空看了一下 clock-in 部分的代码,发现有好几种解决思路,我当前用了最简单的一种,不涉及继承属性,原理如下:

在对任务 clock-in 后,显示在 modeline 里的如 [0:11/0:30] 中的 effort 值完全是由 org-clock-effort 这个全局变量决定的,这个值是在执行 clock-in 命令后 clock-in-hook 前调用 org-entry-get 函数去读 org header 的 effort 属性设置的,如果没有设置 Effort 就会返回 nil ,因此在 clock-in-hook 里把这个变量设置成希望的默认值(例如 30 分钟)就可以了

  (defun set-org-clock-effort-to-30-when-nil ()
    (when (not org-clock-effort)
      (setq org-clock-effort "0:30")
      (org-clock-update-mode-line)))
  (add-hook 'org-clock-in-hook #'set-org-clock-effort-to-30-when-nil)
1 个赞

感谢回答,我用另外简单的方式解决了,可以参考我上一个回复