tutorial org emacs org-mode

emacs - tutorial - Ordenar una lista mixta de títulos en modo org



org mode tutorial (4)

La función interactiva de nivel superior org-sort (en su caso) llama a org-sort-entries , que actúa en una región. Solo necesita asegurarse de que su región no incluya el otro bloque.

Para extender la región mediante programación sobre un bloque de palabras clave TODO, puede combinar outline-get-next-sibling con org-heading-components y una región activa.

Tengo una larga lista de encabezados en org-mode :

* Tasks [/] ** TODO Foo ** TODO Bar ** DONE World ** DONE Abba

que quiero ordenar de la siguiente manera:

* Tasks [/] ** TODO Bar ** TODO Foo ** DONE Abba ** DONE World

Con org-sort-entries puedo obtenerlo

* Tasks [/] ** DONE Abba ** TODO Bar ** TODO Foo ** DONE World

(es decir, orden alfabético), o

* Tasks [/] ** TODO Foo ** TODO Bar ** DONE World ** DONE Abba

(es decir, agrupación de acuerdo con el estado).

En otras palabras, quiero ordenar los elementos TODO y DONE orden alfabético, pero mantenlos en dos bloques. ¿Cómo podría lograrlo? ¡Quiero mantener todo el conjunto de encabezados en el mismo subárbol!

Editar:

No logré utilizar las sugerencias a continuación. Por lo tanto, traté de usar las sugerencias que se proporcionan a continuación para encontrar la solución que necesito. Aquí está el código que tengo:

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

Mi idea es marcar los encabezados etiquetados por TODO y ordenarlos alfabéticamente y luego hacer lo mismo con los encabezados DONE . Hasta ahora, lo tengo trabajando solo para TODO ...


Traté de resolver con la función de reemplazo y clasificación ordinaria. Creo que no es útil. Pero es uno de respuesta posible.

(El carácter "@" debe ser una cadena única).

  1. Mx fundamental-mode
  2. Mx replace-string RET Cq Cj RET @
  3. Cx Cx
  4. Mx replace-regexp RET @[*][ ] RET Cq Cj * espacio RET
  5. Cx Cx
  6. M->
  7. Mx sort-lines
  8. Cx Cx
  9. Mx replace-string RET @ RET Cq Cj

Entrada:

* TODO Foo ** TODO1 todo1 * TODO Bar ** TODO2 todo2 * DONE World ** DONE1 done1 * DONE Abba ** DONE2 done2

Salida:

* DONE Abba ** DONE2 done2 * DONE World ** DONE1 done1 * TODO Bar ** TODO2 todo2 * TODO Foo ** TODO1 todo1


LA RESPUESTA CORTA

  • PASO # 1 : Coloque el cursor sobre el padre.

  • PASO # 2 : Mx org-sort-entries RET a RET

  • PASO # 3 : Mx org-sort-entries RET o RET

  • PASO # 4 : Abra su bebida favorita y tome una bebida.

LA RESPUESTA DE LARGA VELOCIDAD

Para ampliar la respuesta de @pmr (es decir, ordenar una región seleccionada), también puede considerar actuar sobre los títulos principales para organizar los subtítulos. Por ejemplo, me gusta realizar una ordenación múltiple: primero por orden alfabético, segundo por orden de tareas, tercero por prioridad y cuarto por tiempo. Para las subpartidas que no contienen fechas límite y contienen solo un tipo de estado de tareas pendientes, basta con que mis necesidades solo se clasifiquen alfabéticamente. A continuación se muestra una función de muestra que utilizo para ordenar todo el buffer que contiene varios encabezados y subencabezados principales. Aquí está la hoja de trucos de 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.

NOTA : org-sort-entries usa la current-time al ordenar entradas basadas en la marca de tiempo si la entrada no contiene una marca de tiempo. La consecuencia del uso de la current-time es que las entradas sin fecha se ordenarán antes de las tareas futuras que contengan marcas de tiempo al ordenar con las opciones t , c , s o d . Para ponderar las entradas sin fecha para que estén ordenadas después de las entradas fechadas, es posible utilizar una fecha posterior a la current-time . La variable let-bound relevante se define como (now (current-time)) , y su uso dentro de la función se escribe como (org-float-time now) . Esto puede abordarse de muchas maneras diferentes, por ejemplo, modificando el código que contiene (org-float-time now) con algo que contiene una fecha artificial lejana en el futuro, por ejemplo, (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) ) )

Aquí hay un ejemplo de cómo ordenar y reorganizar un buffer completo que contiene los principales encabezados y subtítulos. Esto es especialmente útil si el usuario desea la sincronización con el servidor Toodledo utilizando la biblioteca org-toodledo : https://github.com/christopherjwhite/org-toodledo Para acelerar el proceso al reorganizar un buffer que contiene cientos de subtítulos, el usuario puede desee considerar suprimir los mensajes modificando las funciones responsables; sin embargo, eso está más allá del alcance de esta respuesta.

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

Aquí hay una función de limpieza de muestra para poner el espacio adecuado entre las entradas y eliminar las líneas vacías al final del búfer: la expresión regular supone que los encabezados y subtítulos son todos alineados a la izquierda:

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

Esta solución no depende de seleccionar regiones, sino que actúa sobre cada encabezado principal y organiza todo bajo ese encabezado principal, es decir, todos los subtítulos están organizados. El código en esta respuesta reagrupará las entradas volviéndolas debajo del encabezado principal correcto. Por ejemplo, si una tarea se ha completado, el subtítulo completo será ** None : el código buscará todos los subtítulos con ** None y los moverá al encabezado principal de * DONE y luego los ordenará alfabéticamente.

Los principales títulos son: * TASKS ; * EVENTS ; * SOMEDAY ; * CONTACTS ; * DONE .

Se eligieron los siguientes subtítulos porque son un método de Getting Things Done, y el servidor de Toodledo usa esta misma metodología: ** 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


Sobre la base de la breve respuesta de la lista de abogados , aquí hay una función interactiva para agrupar por palabra clave TODO y ordenar alfabéticamente. Esto logra el orden por:

  1. Primero ordenando alfabéticamente
  2. Luego ordenando por palabra clave TODO

Tenga en cuenta que esto funciona porque TODO -sort en org-sort-entries conserva el orden alfabético inicial.

(defun apl-org-sort-entries-todo-alphabetical () "Group Org-mode entries by TODO keyword and sort alphabetically. This function achieves this by first sorting alphabetically and then sorting by TODO keyword. This works because the TODO-sort in `org-sort-entries'' preserves the initial alphabetical sort." (interactive) ;; First sort alphabetically (org-sort-entries t ?a) ;; Then sort by TODO keyword (org-sort-entries t ?o) ;; Rotate subtree to show children (org-cycle) ; SUBTREE -> FOLDED (org-cycle) ; FOLDED -> CHILDREN )