原文地址:https://lujun9972.github.io/blog/2019/06/27/repeated-task執行(org-todo-"done")不會記錄狀態變更日誌之謎/index.html
今天遇到一個很奇怪的情況,我們都知道當repeated task的state變成DONE時,是會自動將state變回原state, 同時會記錄一條狀態變更的日誌。
比如,下面這個 t.org
,
當執行了 (org-todo "DONE")
之後變成了
其中的
- State "DONE" from "" [2019-06-27 四 20:49]
就是org自動生成的狀態日誌變更記錄。
但是,若你以 EmacsScript 的形式執行 (org-todo "DONE")
時卻發現狀態變更日誌不見了。
比如,我們創建一個測試文件 t.el
,內容爲
(find-file "t.org") (org-todo "DONE") (save-some-buffers t) (save-buffers-kill-terminal)
然後執行
cat t.org emacs --batch -l t.el echo ======================================= sleep 60 cat t.org emacs -q -l t.el echo ======================================= cat t.org
* test SCHEDULED: <2019-06-27 四 +1d> ======================================= * test SCHEDULED: <2019-06-28 五 +1d> :PROPERTIES: :LAST_REPEAT: [2019-06-27 四 21:07] :END: ======================================= * test SCHEDULED: <2019-06-29 六 +1d> :PROPERTIES: :LAST_REPEAT: [2019-06-27 四 21:08] :END:
你會發現 SCHEDULED
和 LAST_REPEAT
都改變了,但是 - State "DONE" from "" [2019-06-27 四 20:49]
這樣的狀態變更日誌不見了
經過查看 org.el
中的源代碼,終於找到原因了。 org 插入狀態變更記錄的流程爲:
org-todo
調用org-auto-repeat-maybe
函數org-auto-repeat-maybe
函數中通過org-add-log-setup
在post-command-hook
中設置org-add-log-note
函數org-add-log-note
根據org-log-note-how
的值(若爲'time或'state)來調用org-store-log-note
org-store-log-note
中根據org-log-note-headings
變量中定義的模板組裝狀態變更的日誌(note變量)並插入repeated task中
這裏主要的問題在於 org-add-log-note
是通過 post-command-hook
來觸發的。而 post-command-hook
只有在 Command Loop
中才會被執行,
而在上面的例子中,我們在執行完elisp後直接通過 (save-buffers-kill-terminal)
退出了Emacs,根本沒有時機觸發 post-command-hook
解決方法是,手工通過 run-hooks
來運行 post-command-hook
,比如將 t.el
改成
(find-file "t.org") (org-todo "DONE") (run-hooks 'post-command-hook) (save-some-buffers t) (save-buffers-kill-terminal)
再執行
cat t.org emacs --batch -l t.el echo ======================================= sleep 60 cat t.org emacs -q -l t.el echo ======================================= cat t.org
* test SCHEDULED: <2019-06-29 六 +1d> :PROPERTIES: :LAST_REPEAT: [2019-06-27 四 21:08] :END: ======================================= * test SCHEDULED: <2019-06-30 日 +1d> :PROPERTIES: :LAST_REPEAT: [2019-06-27 四 21:36] :END: - State "DONE" from "" [2019-06-27 四 21:36] ======================================= * test SCHEDULED: <2019-07-01 一 +1d> :PROPERTIES: :LAST_REPEAT: [2019-06-27 四 21:37] :END: - State "DONE" from "" [2019-06-27 四 21:37] - State "DONE" from "" [2019-06-27 四 21:36]
你會發現,狀態變更記錄現在正常出現了