在组织模式下对标题的混合列表进行排序

Dro*_*ror 10 emacs org-mode

我有很多标题org-mode:

* Tasks [/]
** TODO Foo
** TODO Bar
** DONE World
** DONE Abba
Run Code Online (Sandbox Code Playgroud)

我想按如下方式排序:

* Tasks [/]
** TODO Bar
** TODO Foo
** DONE Abba
** DONE World
Run Code Online (Sandbox Code Playgroud)

随着org-sort-entries我可以得到

* Tasks [/]
** DONE Abba
** TODO Bar
** TODO Foo
** DONE World
Run Code Online (Sandbox Code Playgroud)

(即字母顺序),或

* Tasks [/]
** TODO Foo
** TODO Bar
** DONE World
** DONE Abba
Run Code Online (Sandbox Code Playgroud)

(即根据状态分组).

换句话说,我想按字母顺序TODODONE项目和项目进行排序,但将它们保存在两个块中.我怎么能实现它?我想将整个标题集保存在同一个子树中!

编辑:

我没有设法利用下面的建议.因此,我尝试使用下面提供的提示来提出我需要的解决方案.这是我的代码:

(defun drorata-sort-TODO-DONE-headings ()
  (interactive)
  (save-excursion
    ;; Sort according to the TODO/DONE keywords
    (org-sort-entries t ?o)
    ;; Now there is a block of TODO's and a block of DONE's
    ;; Mark the TODO's
    (next-line)
    (beginning-of-line)
    (set-mark-command nil)
    (search-forward-regexp "[*].* DONE" nil t)
    (beginning-of-line)
    ;; Sort the marked region (of TODO's) alphabetically
    (org-sort-entries t ?a)
    ;; Now its time to sort the DONE's
    (search-forward "[*].* DONE" nil t)
    (beginning-of-line)
    (set-mark-command nil)
    ;; How can I find all headings labeled with DONE in the current level?
    )
)
Run Code Online (Sandbox Code Playgroud)

我的想法是标记标记的标题TODO并按字母顺序排序,然后对DONE标题执行相同的操作.到目前为止,我只有它的工作TODO...

law*_*ist 15

短暂的答案

  • 步骤#1:将光标放在父级上.

  • 第2步M-x org-sort-entries RET a RET

  • 第3步:  M-x org-sort-entries RET o RET

  • 第四步:打开你最喜欢的饮料,喝一杯.


长篇大论

为了扩展@pmr的答案(即,对所选区域进行排序),还可以考虑对主标题进行操作以组织子标题.例如,我喜欢执行多重排序 - 首先按字母顺序排列,然后按顺序排序,按第三顺序排列,按优先顺序排在第三位,按时间排在第四位.对于不包含截止日期且仅包含一种待办事项状态的副标题,我的需求仅按字母排序就足够了.下面给出的是一个示例函数,用于对包含各种主标题和子标题的整个缓冲区进行排序.以下是来自的备忘单org-sort-entries:

Sort: [a]lpha  [n]umeric  [p]riority  p[r]operty  todo[o]rder  [f]unc
               [t]ime [s]cheduled  [d]eadline  [c]reated
               A/N/P/R/O/F/T/S/D/C means reversed.
Run Code Online (Sandbox Code Playgroud)

注意:   如果条目不包含时间戳,则org-sort-entries使用current-time基于时间戳的when排序条目.使用的结果current-time是,凡是不注日期的条目之前将包含时间戳未来的任务与选项排序时进行排序t,c,s,或d.要对未注明日期的条目进行加权,以便在日期条目之后对它们进行排序,可以使用比日期更晚的日期current-time.相关的let-bound变量定义为(now (current-time)),并将其在函数中的用法写为(org-float-time now).这可以通过许多不同的方式来处理 - 例如,修改包含(org-float-time now)含有人工日期的东西的代码远远落后于未来 - 例如,(org-time-string-to-seconds "<2030-12-31 Tue>").

(defun lawlist-sort ()
  (when
      (save-excursion
        (goto-char (point-max))
        (re-search-backward "^\\* CONTACTS" nil t)
        (re-search-forward  "^\\*\\* \\(Planning\\)" nil t))
    (goto-char (point-max))
    (re-search-backward "^\\* CONTACTS" nil t)
    (org-sort-entries t ?a) )
  (when
      (save-excursion
        (goto-char (point-max))
        (re-search-backward "^\\* DONE" nil t)
        (re-search-forward  "^\\*\\* \\(None\\)" nil t))
    (goto-char (point-max))
    (re-search-backward "^\\* DONE" nil t)
    (org-sort-entries t ?a) )
  (when
      (save-excursion
        (goto-char (point-max))
        (re-search-backward "^\\* UNDATED" nil t)
        (re-search-forward  "^\\*\\* \\(Someday\\)" nil t))
    (goto-char (point-max))
    (re-search-backward "^\\* UNDATED" nil t)
    (org-sort-entries t ?a) )
  (when
      (save-excursion
        (goto-char (point-max))
        (re-search-backward "^\\* EVENTS" nil t)
        (re-search-forward  "^\\*\\* \\(Reference\\|Delegated\\|Postponed\\|Waiting\\)" nil t))
    (goto-char (point-max))
    (re-search-backward "^\\* EVENTS" nil t)
    (org-sort-entries t ?a)
    (org-sort-entries t ?o)
    (org-sort-entries t ?p)
    (org-sort-entries t ?t) )
  (when
      (save-excursion
        (goto-char (point-max))
        (re-search-backward "^\\* TASKS" nil t)
        (re-search-forward "^\\*\\* \\(Active\\|Next Action\\|Hold\\|Canceled\\)" nil t))
    (goto-char (point-max))
    (re-search-backward "^\\* TASKS" nil t)
    (org-sort-entries t ?a)
    (org-sort-entries t ?o)
    (org-sort-entries t ?p)
    (org-sort-entries t ?t) ) )
Run Code Online (Sandbox Code Playgroud)

以下是如何对包含主标题和子标题的整个缓冲区进行排序和重组的示例.如果用户希望使用org-toodledo库与Toodledo服务器同步,这将非常有用:https: //github.com/christopherjwhite/org-toodledo  为了在重新组织包含数百个子标题的缓冲区时加快进程,用户可能希望考虑通过修改负责的功能来抑制消息 - 但是,这超出了本答案的范围.

(setq org-todo-keywords '(
  (sequence
  "Active(a)"
  "Next Action(n)"
  "Canceled(c)"
  "Hold(h)"
  "Reference(r)"
  "Delegated(d)"
  "Waiting(w)"
  "Postponed(P)"
  "Someday(s)"
  "Planning(p)"
  "|"
  "None(N)") ))

(defun lawlist-reorganize ()
(interactive)
  (with-current-buffer (get-buffer "test.org")
    (setq buffer-read-only nil)
    (lawlist-refile-tasks)
    (lawlist-refile-events)
    (lawlist-refile-undated)
    (lawlist-refile-contacts)
    (lawlist-refile-done)
    (lawlist-sort)
    (goto-char (point-min))
    (save-buffer)
    (setq buffer-read-only t)))

(defun lawlist-refile-tasks ()
(interactive)
  (let* (
      (org-archive-location "/Users/HOME/Desktop/test.org::* TASKS")
      (org-archive-save-context-info nil))
    (goto-char (point-min))
    (unless (re-search-forward "^\\* TASKS" nil t)
      (goto-char (point-max))
      (insert "* TASKS\n\n"))
    (goto-char (point-max))
    (while
        (re-search-backward
          "^\\*\\* \\(Active\\|Next Action\\|Hold\\|Canceled\\)" nil t)
      (org-archive-subtree))))

(defun lawlist-refile-events ()
  (let* (
      (org-archive-location "/Users/HOME/Desktop/test.org::* EVENTS")
      (org-archive-save-context-info nil))
    (goto-char (point-min))
    (unless (re-search-forward "^\\* EVENTS" nil t)
      (goto-char (point-max))
      (insert "* EVENTS\n\n"))
    (goto-char (point-max))
    (while
        (re-search-backward
          "^\\*\\* \\(Reference\\|Delegated\\|Postponed\\|Waiting\\)" nil t)
      (org-archive-subtree))))

(defun lawlist-refile-undated ()
  (let* (
      (org-archive-location "/Users/HOME/Desktop/test.org::* UNDATED")
      (org-archive-save-context-info nil))
    (goto-char (point-min))
    (unless (re-search-forward "^\\* UNDATED" nil t)
      (goto-char (point-max))
      (insert "* UNDATED\n\n"))
    (goto-char (point-max))
    (while
        (re-search-backward
          "^\\*\\* \\(Someday\\)" nil t)
      (org-archive-subtree))))

(defun lawlist-refile-done ()
  (let* (
      (org-archive-location "/Users/HOME/Desktop/test.org::* DONE")
      (org-archive-save-context-info nil))
    (goto-char (point-min))
    (unless (re-search-forward "^\\* DONE" nil t)
      (goto-char (point-max))
      (insert "* DONE\n\n"))
    (goto-char (point-max))
    (while
        (re-search-backward
          "^\\*\\* \\(None\\)" nil t)
      (org-archive-subtree))))

(defun lawlist-refile-contacts ()
  (let* (
      (org-archive-location "/Users/HOME/Desktop/test.org::* CONTACTS")
      (org-archive-save-context-info nil))
    (goto-char (point-min))
    (unless (re-search-forward "^\\* CONTACTS" nil t)
      (goto-char (point-max))
      (insert "* CONTACTS\n\n"))
    (goto-char (point-max))
    (while
        (re-search-backward
          "^\\*\\* \\(Planning\\)" nil t)
      (org-archive-subtree))))
Run Code Online (Sandbox Code Playgroud)

下面是一个示例清理函数,用于在条目之间放置适当的间距并删除缓冲区末尾的任何空行 - 正则表达式假设标题和子标题都是向左刷新:

(defun lawlist-cleanup ()
(interactive)
  (let ((query-replace-lazy-highlight nil))
    (replace-regexp "\n+\\*\\* " "\n\n** " nil (point-min) (point-max))
    (replace-regexp "\n+\\* " "\n\n\n* " nil (point-min) (point-max))
    (goto-char (point-max))
    (delete-blank-lines)
    (let ((trailnewlines (abs (skip-chars-backward "\n\t"))))
      (if (> trailnewlines 0)
        (delete-char trailnewlines))) ))
Run Code Online (Sandbox Code Playgroud)

该解决方案不依赖于选择区域,而是依赖于每个主标题并组织该主标题下的所有内容 - 即,所有子标题都是有组织的.此答案中的代码将通过在正确的主标题下重新填充条目来重新组合条目.例如 - 如果任务已经完成,则完成的子标题将是** None- 代码将查找所有子标题** None并将其移动到主标题* DONE,然后按字母顺序对它们进行排序.

主要标题是: * TASKS; * EVENTS; * SOMEDAY; * CONTACTS; * DONE.

被选中下面的小标题,因为他们是把事情完成的方法,而Toodledo的服务器使用相同的方法学:   ** Active; ** Next Action; ** Hold; ** Canceled; ** Reference; ** Delegated; ** Postponed; ** Waiting; ** Someday; ** Planning; ** None.

* TASKS

  ** Active

  ** Next Action

  ** Hold

  ** Canceled

* EVENTS

  ** Reference

  ** Delegated

  ** Postponed

  ** Waiting

* SOMEDAY

  ** Someday

* CONTACTS

  ** Planning

* DONE

  ** None
Run Code Online (Sandbox Code Playgroud)