如何使用 org capture template 插入当前 point 所处的 word 和 sentence

org-capture 可以使用 %() 来插入 elisp 表达式,然后 (current-word) 以及 (thing-at-point 'word 'no-properties) 都可以获得当前 point 的单词,以及 (thing-at-point 'sentence 'no-properties) 可以获得当前 point 的句子,因此我试着写下来如下的示例 elisp 代码。

(setq org-capture-templates
        '(("t" "Personal note" entry
           (file "~/orgmode/note.org")
           "* %(current-word) %(thing-at-point 'word 'no-properties) %(thing-at-point 'sentence 'no-properties)")))

但是在实践的时候发现这三段 elisp 代码都不起作用,(thing-at-point) 会一直返回 nil, org-capture 在调用 (current-word) ,会一直返回字符串:“current-word”。

更新:发现当 org-capture 在调用 elisp 表达式的时候,该 elisp 表达式并不能得到正确的 (point),因此也就无法得到正确的调用结果。

目前想到的一个work around是

(defvar my-org-capture-word-under-point nil)
(defvar my-org-capture-sentence-under-point nil)

(defun my-get-word-and-sentence-under-point-and-then-org-capture ()
  "get word and sentence under point and then call `org-capture'"
  (interactive)
  (setq my-org-capture-word-under-point (current-word))
  (setq my-org-capture-sentence-under-point (thing-at-point 'sentence t))
  (call-interactively #'org-capture))

(setq org-capture-templates
        '(("t" "Personal note" entry
           (file "~/orgmode/note.org")
           "* %(symbol-value 'my-org-capture-word-under-point) %(symbol-value 'my-org-capture-sentence-under-point)")))

然后把 M-x org-capture 变成 M-x my-get-word-and-sentence-under-point-and-then-org-capture

但是感觉这个方法有点蠢,太不优雅了

需要切换到 original buffer

(setq org-capture-templates
      '(("t" "Personal note" entry
         (file "")
         "* %(with-current-buffer (org-capture-get :original-buffer)
(thing-at-point 'word 'no-properties))")))
1 个赞

楼上正解,做点补充说明。

%(...) 的求值过程发生在临时的 capture buffer 中的,所以不行,然后看看 Template expansion (The Org Manual) (orgmode.org) 里面好像也没有提供 thing-at-point 相关的选项。用 org-captture-get 可以获取 capture 发生时的一些环境信息。

这段代码和楼上的功能上应该一样,只不过更 hack 一点:

(setq org-capture-templates
      '(("t" "Personal note"
	    entry
	    (file "~/test.org")
	    "* %(with-current-buffer (cadr (buffer-list)) (thing-at-point 'word t))")))

至于为啥要这样做,可以参考 Buffer List (GNU Emacs Lisp Reference Manual)

感谢回复!其实我猜到了是因为临时 buffer 的原因,但是想不到有什么办法得到我原来的那个 buffer 到底是在哪个地方。翻了翻 org-capture 的文档,也没找到说明。但原来 org-capture 确实提供了这个 api 可以访问原来的buffer 哈哈。 至于你这个hack的方法,应该是因为buffer list的排序,刚刚创建的临时buffer是buffer list的第一个,然后一开始的那个buffer就是buffer list的第二个,这样就还是访问得到了。还是没有仔细读文档哈哈。

1 个赞