org:如何按TODO排序标题,然后按优先级排序?


24

我经常有这样的清单:

* Main heading
** TODO [#A] Make world better
** TODO [#B] Make Emacs better 
** TODO [#B] Customize emacs 
** DONE [#C] some task
** TODO [#A] Launch rocket to mars

我想首先根据“ TODO”任务字对它进行排序。然后,我想按优先级对已排序的TODO中的项目进行排序。(然后按“工作量”进一步排序将是不错的选择)。

我的意思是,当前我可以单击主标题,并已按优先级或todo关键字对子级进行排序,但不能同时对二者进行排序。

是否可以像排序策略一样进行排序?


目前我有两个标题

* Tasks
** TODO [#A] meh
** TODO [#B] meh2
* Completed.
** DONE [#B] meh3.

但是这种方法的问题在于,当我完成任务时,我不得不不断地拖延任务。

[编辑]
这有点类似于此,除了我无法理解他的回答以将其转移到我的需要上吗?


1
该函数org-sort-entries将作用于所有子标题的主标题,或者可以对所选区域中的内容进行排序。有交互式选项供您选择。您也可以以编程方式使用它,并且可能进行多种排序-我经常使用a,o,p,t(一个接一个地完成四个级别的排序标准)。例如,您可以先按字母顺序,然后按待办事项关键字,然后按优先级,再按时间对所有内容进行排序。
法律名单

您好,我知道可以对子任务进行排序的org-sort-entries选项。我已经更新了问题,以便更好地反映这一点。感谢您的评论。
Leo Ufimtsev

这是指向以编程方式对组织模式缓冲区进行排序的详细方法的链接: stackoverflow.com/a/22232709/2112489
lawlist

我的问题中已经有此链接。以上内容是针对某人的特定需求量身定制的。是否有更通用的/更简便的方法?
Leo Ufimtsev

1
@LeoUfimtsev尝试将其设置org-refile-targets(setq org-refile-targets '((nil . (:maxlevel . 6))))org-mode重播时,这将使节目标题的深度达到6。您可以查看文档以org-refile-targets获取更多信息。
itsjeyd

Answers:


19

如果可以使用进行类似操作org-agenda-sorting-stratagy,那就太好了org-sort-entries,但是似乎没有。我们可以伪造它,因为org-sort-entries可以接受一个参数,该参数指定一个为每个标题分配(字符串或数字)键的函数,当?f给出排序类型时,该键将用于对条目进行排序。我们要做的就是获取TODO和PRIORITY属性的字符串。诀窍是我们要按TODO属性在中的位置排序org-todo-keywords,而不是按字母顺序排序。

(require 'cl)
(require 'dash)

(defun todo-to-int (todo)
    (first (-non-nil
            (mapcar (lambda (keywords)
                      (let ((todo-seq
                             (-map (lambda (x) (first (split-string  x "(")))
                                   (rest keywords)))) 
                        (cl-position-if (lambda (x) (string= x todo)) todo-seq)))
                    org-todo-keywords))))

(defun my/org-sort-key ()
  (let* ((todo-max (apply #'max (mapcar #'length org-todo-keywords)))
         (todo (org-entry-get (point) "TODO"))
         (todo-int (if todo (todo-to-int todo) todo-max))
         (priority (org-entry-get (point) "PRIORITY"))
         (priority-int (if priority (string-to-char priority) org-default-priority)))
    (format "%03d %03d" todo-int priority-int)
    ))

(defun my/org-sort-entries ()
  (interactive)
  (org-sort-entries nil ?f #'my/org-sort-key))

M-x my/org-sort-entries将按TODO关键字排序,并与PRIORITY断开联系(org-default-priority在不指定优先级的情况下使用)。如果您有1000个以上的TODO关键字,则此操作会中断,这是不这样做的一个很好的理由。


天哪,谢谢你的剧本。问题:我安装了破折号。然后尝试了脚本,但出现错误:符号定义无效:todo-to-int。我猜你在.emacs文件中的某处有该功能,但是忘记了上面的内容吗?或某些错字?
Leo Ufimtsev

todo-to-int粘贴答案后,我更改了将关键字转换为int的函数。现在已修复。
erikstokes

1
现在所有的作品。杜德(Dude),非常感谢您的付出:-D。
Leo Ufimtsev

1
注意:不再建议根据docs使用cl 。
cammil

1

将以下内容添加到您的文件中:

#+ARCHIVE: :: * Completed.

改组成为存档

与其对条目进行排序,不如对排序视图进行排序?

(setq org-agenda-custom-commands
      '(("cx" "TODOs sorted by state, priority, effort"
         todo "*"
         ((org-agenda-overriding-header "\nTODOs sorted by state, priority, effort")
          (org-agenda-sorting-strategy '(todo-state-down priority-down effort-up))))))

使用将它限制为当前文件<。您可以标记“完成”并从已排序的视图中存档。


1

您还可以定义一个org-agenda-cmp-user-defined函数并将其添加到中org-agenda-sorting-strategy。这是我创建的一个示例。

(setq org-todo-sort-order '("WAIT" "TODO" "DOING" "CANCELED" "DONE"))

(defun my:user-todo-sort (a b)
  "Sort todo based on which I want to see first"
  (when-let ((state-a (get-text-property 14 'todo-state a))
             (state-b (get-text-property 14 'todo-state b))
             (cmp (--map (cl-position-if (lambda (x)
                                           (equal x it))
                                         org-todo-sort-order)
                         (list state-a state-b))))
    (cond ((apply '> cmp) 1)
          ((apply '< cmp) -1)
          (t nil))))
(setq org-agenda-cmp-user-defined 'my:user-todo-sort)

1

您可以使用我制作的这个库:https : //github.com/felipelalli/org-sort-tasks

它通过询问用户任务A是否比任务B重要来使用合并排序算法,然后构建排序列表。


您能否添加一些关于此功能的描述,尤其是它与其他答案的不同之处。
安德鲁·斯旺

它通过询问用户任务A是否比任务B重要来使用合并排序算法,然后构建排序列表。
费利佩
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.