怎么在新建标题的时候自动插入 PROPERTIES?

我希望在每新建一个标题的时候自动插入 created 属性,也就是新建各级 * 回车后,自动执行 C-c C-x p created C-u C-c ! 。

效果如

* 一级标题
:PROPERTIES:
:created: [2017-03-16 Thu 19:14]
:END:

** 最好子标题也能有
:PROPERTIES:
:created: [2017-03-16 Thu 19:15]
:END:

不知道是不是关键词不对,只在网上找到个类似的:

流程应该是:

  1. 挂个钩子(不知道钩子叫啥)
  2. 添加属性,属性值是方括号格式的时间戳(用 org-insert-property-drawer()?)
  3. 把光标移回正确的位置(我的加个回车到抽屉下就好了)

作为一个 el 白,看别人扩展的时候感觉就是道理我都懂,但我写不出来啊,所以请 el 高帮我填下空,我就“挺急的在线等”吧。:upside_down:

谢谢。

2 个赞

1 如果没有钩子,用上 advice。(好押韵) 2和3都很好写啊。稍微想想就出来了。

你找到的那个例子基本上可以搬过来用了。你自己要解决的问题是如何响应回车:

  • M-x describe-keyRET 找到回车键绑定的函数(我这里看到的是 org-return)。

  • org-return 加上 advice

那个用到了 org-expiry,你这里不用 todo 的话,其实直接一句就可以搞定:

(add-hook 'org-insert-heading-hook
          (lambda () (org-set-property "CREATED" (format-time-string "%Y/%m/%d %H:%M"))))

时间的格式可以自己修改

2 个赞

我是拿 org-mode 写笔记的门外用户,一点不懂 elisp。自己写得出来就不发帖了,advice 是什么更不知道了。:cold_sweat:

他那个例子我粘到自己的 .el 文件里试了,不生效,不懂 elisp 无法排查原因,而且我看他是加在 TODO 上的,我想加在普通标题上。

我的回复被无视了,他那个需要外来的库 org-expire

先谢谢,这句我粘到自己的 .el 里不生效,我的 .el 里只有几个格式的配置,应该没有冲突。

在你的 emacs 里能生效吗?

我这边试了生效的,你 eval 这一句才能生效,然后用 alt+enter 命令来快速插入标题

没有无视,我拿去试了,没生效。:tired_face:

我这边是可以生效的。。。

建议时间和Org格式一样

  (add-hook 'org-insert-heading-hook
     (lambda () (org-set-property "CREATED" (format-time-string "[%Y-%m-%d %a %H:%M]"))))
2 个赞
(with-eval-after-load 'org
    body...)
1 个赞

eval 这一句才能生效

什么意思?

在代码后面按C-x C-e

1 个赞

你先按 M-: 回车,把这一句粘贴进去,然后回车

生效了,谢谢大家。:grin:

原来是只有在 M-<RET> 创建标题时才行,自己打 * 标题 <RET> 时不起作用。

楼主的问题跟我想象的有偏差(平时很少用 org-mode,所以也不知道 org-insert-heading 的存在😅)

我以为使用场景是这样的:

  • 输入标题

    * foo
    
  • 回车得到

    * foo
    :PROPERTIES:
    :CREATED:  2017/03/16 23:18
    :END:
    

以下是代码实现:

(defun org/insert-heading-property (f &rest args)
  "Insert property after invoke function `F' with parameters `ARGS'."
  (let ((is-head-line (string-match "\\`\\*+ " (thing-at-point 'line t)))
        (has-property (save-excursion
                          (forward-line)
                          (string-match "\\`[ ]+:[^:]" (thing-at-point 'line t)))))
    (apply f args)
    (unless (null is-head-line)
      (when (null has-property)
       (org-set-property "CREATED" (format-time-string "%Y/%m/%d %H:%M"))
        ))))

(advice-add 'org-return :around #'org/insert-heading-property)

我觉得这样也不错,不需要记任何快捷键。

我又想了一下,觉得这样改的话,如果 org-return 有其它用处就不太好了。 并且 M-RET 在 org 中是常用的命令,用官方提供的 hook 不是更好?

比如你要输入四级标题的时候,前面要输 4个 *和一个空格,我觉得还是 M-RET 更方便吧?

spacemacs 中,这个命令被绑定到 , h I 上,更方便快捷了。

当然主要还是看个人喜好了,@twlz0ne 的提议也是一个不错的办法。

做个比较:

  • M-RET

    *** 标题 <-- 光标在这里
        :PROPERTIES:
        :CREATED:  2017/03/17 00:07
        :END:
        <-- 接下来要移动到这里
    
  • 输入 *** 标题RET

    *** 标题
        :PROPERTIES:
        :CREATED:  2017/03/17 00:07
        :END:
        <--- 光标在这里
    

哪一种按键更少呢?

这可能还是跟个人的使用习惯有关吧,我没有这样设置 Property。我也很少自己手动输星号。

挑自己喜欢的用就好了。

这种带 drawer 的标题一般是在 org-capture 中使用比较多。那个一般都用模板,就不存在我们现在争论的基础了。看楼主也是要用 org 做 gtd 的,不管用哪个,估计过不多久这个工作流就又要升级了,所以可能到时候两种都不用也有可能。

我自己也有这种困惑,有的时候花时间做的 Customization,过段时间就完全弃用了,有点可惜☹️