彌補org-refile的不足

「實戰Elisp」系列旨在講述我使用Elisp定製Emacs的經驗,拋磚引玉,還請廣大Emacs同好不吝賜教——若是真的有廣大Emacs用戶的話,哈哈哈。

GTD的第一條原則是「蒐集」,爲此我有一個inbox.org文件,專門記錄全部的新想法、新任務。我會在每晚的固定時間處理其中的內容——有些能夠立刻開始作並作完,更多的則是移動到其它.org文件中,等待排期。html

org-mode有一個內置的快捷鍵C-c C-w,專門完成將條目(org-mode的術語,即.org文件中帶星號前綴的一行,參見An Explanation of Basic Org-Mode Concepts)移動到其它.org文件的需求,但它有一個缺陷——不能把條目移動到其它.org文件的頂層,而這是我常常須要作的。git

爲了移動到頂層,須要:github

  1. 使用org-cut-subtree命令剪切當前條目(其實還會包括條目的子節點,但inbox.org中的條目基本上都沒有子節點);
  2. 打開目標的.org文件;
  3. 將光標定位到文件末尾;
  4. 使用org-paste-subtree命令粘貼條目。

爲了輕鬆完成上述四個步驟,org-refile-to-eof函數應運而生。函數

org-refile-to-eof函數

廢話很少說,直接亮相吧code

;;; 定義一個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入門)。在個人環境中,它的值是htm

(setq *org-refile-eof--helm-source*
      '((name . "refile到下列的哪一個文件")
        (candidates . org-agenda-files)
        (action . (lambda (candidate)
                    candidate))))

如今,只須要敲入M-: org-refile-to-eof RET便能輕鬆完成以前繁瑣的四個步驟。ip

後記

若是有迫切需求的話,我會考慮將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,想一想也有點小激動呢。get

閱讀原文emacs

相關文章
相關標籤/搜索