在使用org的时候, 我发现有一点不太方便的是,很多时候如果你是对org的纯文本直接修改(比如emacs不在身边,选择使用在纯文本上直接修改,然后再用版本控制推送会emacs本地,或者直接云盘云同步),这个时候很多动态更新的内容是不会更新的,比如progress,比如对任务进行计时,比如repeater。
以下是几个常见的例子:
- 更新子任务与总任务的进度
#+title: test
#+STARTUP: logdone
* 测试 [66%]
** DONE 测试子任务一
** DONE 测试子任务二
** TODO 测试子任务三
为了让 org 自动更新测试的总进度,每次更新的时候需要调用 #'org-to-do
,这样才会自动更新测试的总进度,比如如果在纯文本上直接修改,将 子任务三的TODO 改成了 DONE,那么测试的总进度不会更新,这个时候你就必须到子任务三所在的标题栏再调用一次#'org-to-do
,然后选择进度为DONE,这样才会更新总进度。
- checkbox
如果是使用checkbox来更新子任务的话,例如
* 测试 [50%]
- [X] 子任务一
- [ ] 子任务二
这个时候如果手动的修改文本,把子任务二的 [ ] 修改为X,这个时候测试的 50%进度并不会更新,需要在测试这一个大标题所在的这一行调用函数 #'org-update-check-box-count
才能更新。
- 修改计时任务的时间
* 遛狗
** 09/01/2022
*** DONE Corridor Walk
CLOSED: [2022-09-01 Thu 16:29]
:LOGBOOK:
CLOCK: [2022-09-01 Thu 16:05]--[2022-09-01 Thu 16:29] => 0:24
:END:
以上是我使用org来记录每日遛狗的次数以及用时,但是遛狗的时候emacs不在身边,很多时候需要遛完狗之后再过一段时间才能回来更新emacs,这个时候我就只能先随便调用#'org-clock-in
以及#'org-clock-out
来随便记录一段时间,然后再手动把时间修改为正确的时间,之后在手动调用#'org-evaluate-time-range
来更新此次任务时长。
以上的都是我找到对应的函数可以重新更新的,但是对于如果修改了重复任务的时间以后,如何正确的更新 last
以及 下一个 schedule 所对应的日期,我是根本没有找到对应的函数去完成这件事情,难道我真的只能够手动的修改纯文本上的 next schedule 以及 last_property
?
- 修改重复任务的完成时间
* TODO 测试
SCHEDULED: <2022-09-02 Fri 00:50 .+3h>
:PROPERTIES:
:LAST_REPEAT: [2022-09-01 Thu 21:50]
:END:
- State "DONE" from "TODO" [2022-09-01 Thu 21:50]
- State "DONE" from "TODO" [2022-09-01 Thu 20:50]
- State "DONE" from "TODO" [2022-09-01 Thu 19:50]
这个时候如果我手动将最新的最后一次的任务时间从21:50
修改为了22:35
,我希望有一个函数(或者说我没找到这个函数)能够自动将LAST_REPEAT
属性也修改为22:35
,同时schedule的下一次的时间能够自动从00:50
更新为01:35
。事实上这个功能对于我来说我觉得是非常重要的,因为现实中每一次完成任务的的时候你刚好emacs都在身边能够立即更新完成任务的时间实在是罕见的,很多时候完成了任务以后,都要过一段时间才能使用emacs。
以上问题的总结
对于每一个这种可以动态更新的内容,如果手动修改了纯文本,那么想重新更新得到对应的内容,每一个内容可能都对应了一个不同的函数(而且org的函数特别多,找起来很费时间),而且有的动态更新的内容到目前我甚至还没有找到对应的函数(比如对于一个repeat的任务,如果修改了最后一次完成的时间以后。如何将下一次schedule的时间也对应的做更新)。
如果自己手动实现这样的函数,实现难点在于,首先这些动态更新的函数都不是更新整个文本,而只更新你当前所处于的标题的层级,你需要遍历所有的标题层级依次调用这些函数,其次有些修改纯文本后要如何动态更新到底对应什么函数,我根本就不知道。 想知道有没有一个函数实现可以将org的所有的这些需要动态更新的内容都一键更新。
PS:org里有一个函数叫做·org-update-all-dblocks·,但是org官方文档所指的dblocks
似乎和我这里指的可以动态更新的内容并不是一回事。