org-modeでアイテムをrefileした際にヘッドラインのstatistics cookieを自動更新する

#emacs
#org-mode

要は上のようにTODO itemを移動した際、その完了ステータスに応じてタスク数(statistics cookie)の値を更新したい。簡単なことだけど地味なworkaroundが必要だった。

cookieの更新は `org-update-statistics-cookies` 関数で行えるので、これをrefileが完了した際の `org-after-refile-insert-hook` で呼べばいい。しかしこれだとitemを移動した先のヘッドラインしか数値が更新されない。

結論以下のような設定を入れることで解決できた。

(use-package org :preface (defun my/org-update-statistics-cookies-after-refile () (run-at-time "0.01 sec" nil (lambda () (org-update-statistics-cookies 'all)))) :hook ((org-after-refile-insert . my/org-update-statistics-cookies-after-refile)))

org-refileのアイテム移動とは移動先ヘッドラインへのアイテム挿入と移動元での削除のセットであり、`org-after-refile-insert-hook` は文字通り前者のアイテム挿入時に呼ばれている。このタイミングではまだ移動元にアイテムが残っているので `(org-update-statistics-cookies 'all)` で全ヘッドラインのcookieに更新をかけても移動前のものは変わらない事になる。ドキュメントにも記載があった。

Hook run after `org-refile' has inserted its stuff at the new location. Note that this is still before the stuff will be removed from the old location.

https://orgmode.org/worg/doc.html

見る限りorg-refileに関するhookはinsert時のものしか無かったので、愚直にinsert後に一瞬待ってからcookieを更新した。

Tweet