org: ¿Cómo ordenar los encabezados por TODO y luego por prioridad?

24

A menudo tengo una lista como esta:

* 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

Me gustaría ordenarlo de acuerdo con la palabra de tarea 'TODO' primero. Luego, los elementos dentro del TODO ordenado me gustaría ordenar por prioridad. (sería bueno ordenar más por "Esfuerzo").

Y quiero decir que actualmente puedo hacer clic en el encabezado principal y ordenar a los hijos ya sea por prioridad o por palabra clave todo, pero no ambos.

¿Es posible ordenar por ambos como una estrategia de clasificación?


Actualmente tengo dos encabezados

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

Pero el problema con este enfoque es que tengo que barajar constantemente las tareas cuando las completo.

[EDITAR] ¿
Esto es algo similar a esto excepto que no pude entender su respuesta para transferirla a mis necesidades?

Leo Ufimtsev
fuente
1
La función org-sort-entriesactuará en un encabezado principal para todos los subtítulos, o puede ordenar lo que está en una región seleccionada. Hay opciones interactivas para que pueda elegir. También puede usarlo mediante programación, y son posibles varios tipos: a menudo uso a, o, p, t (uno después del siguiente para lograr 4 niveles de criterios de clasificación). Por ejemplo, puede ordenar todo primero por alfabético, luego por palabras clave todo, luego por prioridad y luego por tiempo.
abogados
Hola, conozco la opción org-sort-entries para ordenar las tareas secundarias. He actualizado la pregunta para reflejarlo mejor. Gracias por tu comentario.
Leo Ufimtsev
Aquí hay un enlace a un enfoque detallado para ordenar un búfer en modo org mediante programación: stackoverflow.com/a/22232709/2112489
leyes
Ya tengo este enlace en mi pregunta. Lo anterior se adapta a las necesidades específicas de alguien. ¿Hay un propósito más general / enfoque más fácil?
Leo Ufimtsev
1
@LeoUfimtsev Intenta configurar org-refile-targetsalgo así (setq org-refile-targets '((nil . (:maxlevel . 6)))). Eso hará que los org-modeencabezados de los programas lleguen a una profundidad de 6 al volver a llenar. Puede consultar la documentación para org-refile-targetsobtener más información.
itsjeyd

Respuestas:

19

Sería genial si hubiera algo así con lo org-agenda-sorting-stratagyque funcionó org-sort-entries, pero no parece haberlo . Podemos fingirlo ya que org-sort-entriespuede tomar un argumento que especifica una función que asigna una tecla (cadena o número) a cada encabezado, que se usará para ordenar las entradas cuando se proporcione el ?ftipo de ordenación. Todo lo que tenemos que hacer es obtener una cadena para las propiedades TODO y PRIORIDAD. El truco es que queremos ordenar la propiedad TODO por su posición org-todo-keywords, no alfabéticamente.

(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-entriesse ordenará por la palabra clave TODO y romperá los lazos con PRIORITY ( org-default-prioritycuando no se da prioridad). Esto se romperá si tiene más de 1000 palabras clave TODO, lo cual es una buena razón para no hacerlo.

erikstokes
fuente
Omg, gracias por el guión. Un problema: instalé el tablero. Luego probé el script, pero recibo un error: la definición del símbolo es nula: todo-to-int. Supongo que tiene esa función en algún lugar de su archivo .emacs, pero ¿olvidó incluir en lo anterior? o tal vez algún error tipográfico?
Leo Ufimtsev
Cambié la función que convierte una palabra clave en int todo-to-intdespués de haber pegado mi respuesta. Ya está arreglado.
erikstokes
1
Ahora todo funciona. Amigo, gracias por todo tu esfuerzo, muy apreciado :-D.
Leo Ufimtsev
1
Nota: ya no se recomienda usar cl de acuerdo con los documentos .
cammil
1

Agregue lo siguiente a su archivo:

#+ARCHIVE: :: * Completed.

Y barajar se convierte en archivado

En lugar de ordenar las entradas, ¿qué tal una vista ordenada?

(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))))))

Restrinja al archivo actual con <. Puede marcar HECHO y archivar desde la vista ordenada.

Hijo de un ñu
fuente
1

También puede definir una org-agenda-cmp-user-definedfunción y agregarla org-agenda-sorting-strategy. Este es el que creé como ejemplo.

(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)
Prgrm.celeritas
fuente
1

Puede usar esta biblioteca hecha por mí: https://github.com/felipelalli/org-sort-tasks

Utiliza Merge Sort algo preguntando al usuario si una tarea A es más importante que B, y luego construye una lista ordenada.

Felipe
fuente
¿Puede agregar alguna descripción de lo que esto hace y, en particular, cómo difiere de las otras respuestas?
Andrew Swann
Utiliza Merge Sort algo preguntando al usuario si una tarea A es más importante que B, y luego construye una lista ordenada.
Felipe