在org-mode中将CREATED date属性添加到TODO

Ren*_*ald 19 emacs elisp org-mode

我阅读了组织模式手册,但找不到向新创建的TODO添加CREATED字段的简单方法.org-log-done然后结合一个可以计算关闭特定TODO所花费的时间.这在使用存档文件时特别有用.

例:

* TODO Do something
  CREATED:  [2012-09-02 Sun 23:02]
* DONE Do something else
  CREATED: [2012-09-02 Sun 20:02]
  CLOSED: [2012-09-02 Sun 22:02]
Run Code Online (Sandbox Code Playgroud)

我希望每当保存文件时,CREATED字段都会被添加到新任务(没有该字段的任务)中.

有关如何实现这一目标的任何建议?使用像Git这样的东西不是我跟踪TODOS创作的解决方案.

小智 14

我使用org-expiry来实现该功能,该功能位于org的contrib目录中.

我使用的基本配置是:

;; Allow automatically handing of created/expired meta data.
(require 'org-expiry)
;; Configure it a bit to my liking
(setq
  org-expiry-created-property-name "CREATED" ; Name of property when an item is created
  org-expiry-inactive-timestamps   t         ; Don't have everything in the agenda view
)

(defun mrb/insert-created-timestamp()
  "Insert a CREATED property using org-expiry.el for TODO entries"
  (org-expiry-insert-created)
  (org-back-to-heading)
  (org-end-of-line)
  (insert " ")
)

;; Whenever a TODO entry is created, I want a timestamp
;; Advice org-insert-todo-heading to insert a created timestamp using org-expiry
(defadvice org-insert-todo-heading (after mrb/created-timestamp-advice activate)
  "Insert a CREATED property using org-expiry.el for TODO entries"
  (mrb/insert-created-timestamp)
)
;; Make it active
(ad-activate 'org-insert-todo-heading)
Run Code Online (Sandbox Code Playgroud)

如果你正在使用捕获它不会自动工作,需要一点胶水.我在这里发布了完整的配置:https: //gist.github.com/4037694

  • 谢谢你。我认为这是一个很好的解决方案。但是,我只将它放入我的 init 文件中`(require 'org-expiry) (org-expiry-insinuate) (setq org-expiry-inactive-timestamps t)` (5认同)

小智 6

您不需要使用'defadvice'修改函数来在捕获时运行到期代码.你应该使用钩子:

(add-hook 'org-capture-before-finalize-hook 
         #'(lambda()
               (save-excursion
                    (org-back-to-heading)
                    (org-expiry-insert-created))))
Run Code Online (Sandbox Code Playgroud)

'org-insert-todo-heading'也是如此.有一个钩子:

(add-hook 'org-insert-heading-hook 
         #'(lambda()
               (save-excursion
                    (org-back-to-heading)
                    (org-expiry-insert-created))))
Run Code Online (Sandbox Code Playgroud)


Wil*_*hes 6

Org 提供了一个钩子org-after-todo-state-change-hook,你可以在这里使用:

org-after-todo-state-change-hook 是在 'org.el' 中定义的变量。

文档:

在 TODO 项的状态更改后运行的钩子。新状态(带有 TODO 关键字或 nil 的字符串)在 Lisp 变量 'org-state' 中可用。

使用方法如下:

(require 'org-expiry)

(add-hook 'org-after-todo-state-change-hook
          (lambda ()
            (when (string= org-state "TODO")
              (save-excursion
                (org-back-to-heading)
                (org-expiry-insert-created)))))
Run Code Online (Sandbox Code Playgroud)

org-expiry 是 org-contrib 的一部分,它包含在 org ELPA 上的 org-plus-contrib 包中


Jos*_*h.F 6

这是一个埋藏的宝藏:

(setq org-treat-insert-todo-heading-as-state-change t)
Run Code Online (Sandbox Code Playgroud)

我在这里找到了它,以回应有人说他们想要一个org-insert-todo-heading-hook.

刚刚试了一下,真的,当你org-insert-todo-heading,它算作一个状态改变,所以例如:#+TODO: TODO(t!) | ...会添加一个日志。


ole*_*enb 5

更轻量级的解决方案是向状态添加!标志TODO:

(setq org-todo-keywords '((sequence "TODO(!)" "DONE")))
Run Code Online (Sandbox Code Playgroud)

然后:

* TODO get of your ass
  - State "TODO"    from    [2016-06-03 to. 10:35]
Run Code Online (Sandbox Code Playgroud)

虽然不是很漂亮.

参考:http://orgmode.org/org.html#Tracking-TODO-state-changes