“实战Elisp”系列旨在讲述我使用Elisp定制Emacs的经验,抛砖引玉,还请广大Emacs同好不吝赐教——如果真的有广大Emacs用户的话,哈哈哈。
GTD的第一条原则是“搜集”,为此我有一个inbox.org
文件,专门记录所有的新想法、新任务。我会在每晚的固定时间处理其中的内容——有些可以马上开始做并做完,更多的则是移动到其它.org
文件中,等待排期。
org-mode有一个内置的快捷键C-c C-w
,专门完成将条目(org-mode的术语,即.org
文件中带星号前缀的一行,参见An Explanation of Basic Org-Mode Concepts)移动到其它.org
文件的需求,但它有一个缺陷——不能把条目移动到其它.org
文件的顶层,而这是我经常需要做的。
为了移动到顶层,需要:
- 使用
org-cut-subtree
命令剪切当前条目(其实还会包括条目的子节点,但inbox.org
中的条目基本上都没有子节点); - 打开目标的
.org
文件; - 将光标定位到文件末尾;
- 使用
org-paste-subtree
命令粘贴条目。
为了轻松完成上述四个步骤,org-refile-to-eof
函数应运而生。
org-refile-to-eof函数
废话不多说,直接亮相吧
;;; 定义一个Helm的source,以便选择要粘贴的.org文件
(defvar *org-refile-eof--helm-source* nil
"用于提供目标.org文件下拉菜单的来源")
;;; 将当前条目剪切并粘贴到某个目标.org文件的末尾
(defun org-refile-to-eof ()
"将当前条目剪切到一个.org文件的末尾。"
(interactive)
;; 先调用Helm获取目标.org文件。这里需要处理没有选中任何文件的情况
(let ((path (helm :sources '(*org-refile-eof--helm-source*))))
(when path
(org-cut-subtree)
(save-excursion
;; 打开选中的文件的buffer,并移动到最后
(find-file path)
(end-of-buffer)
;; 调用org-paste-subtree粘贴进去
(org-paste-subtree)))))
变量*org-refile-eof--helm-source*
定义了helm
函数所要求的下拉列表名称、选项,以及选中后的处理逻辑(Helm的使用可以从How to write helm extension入门)。在我的环境中,它的值是
(setq *org-refile-eof--helm-source*
'((name . "refile到下列的哪个文件")
(candidates . org-agenda-files)
(action . (lambda (candidate)
candidate))))
现在,只需要敲入M-: org-refile-to-eof RET
便能轻松完成之前繁琐的四个步骤。
后记
如果有迫切需求的话,我会考虑将org-refile
(也就是C-c C-w
对应的命令)和org-refile-to-eof
合并在一起。例如,按下C-c C-w
时调用的是org-refile
,而按下C-u C-c C-w
时调用的则是org-refile-to-eof
,想想也有点小激动呢。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。