Cómo ajustar automáticamente el estado de una tarea Org con sus casillas de verificación secundarias

10

Tengo varias tareas en mi archivo Org, una de las cuales tiene elementos que comienzan con una casilla de verificación (pero solo esas). Todos tienen una cookie de estadísticas al final ([n / m]).

Estoy buscando una manera de actualizar automáticamente la tarea de los padres de TODOque DONEuna vez que todas las casillas están marcadas como se ha hecho así.

La documentación dice:

Si desea que una entrada TODO cambie automáticamente a HECHO cuando todos los niños hayan terminado, puede usar la siguiente configuración [...]

Otra posibilidad es el uso de casillas de verificación para identificar (una jerarquía de) una gran cantidad de subtareas (ver Casillas de verificación).

Según tengo entendido, la última parte es que si los elementos secundarios son casillas de verificación, el estado primario ya debería actualizarse automáticamente (que no es el caso).

¿Qué me estoy perdiendo?


Editar:

De org-after-todo-statistics-hookla documentación de (org.el):

Enlace que se llama después de que se haya actualizado una cookie de estadísticas TODO. Cada función se llama con dos argumentos: el número de entradas no realizadas y el número de entradas realizadas.

Lo que significa que el código propuesto de orgmode.org:

(defun org-summary-todo (n-done n-not-done)
  "Switch entry to DONE when all subentries are done, to TODO otherwise."
  (let (org-log-done org-log-states)   ; turn off logging
    (org-todo (if (= n-not-done 0) "DONE" "TODO"))))

(add-hook 'org-after-todo-statistics-hook 'org-summary-todo)

no contará los elementos de la casilla de verificación.

Mathieu Marques
fuente
¿Tienes una cookie de estadísticas en el titular? Así:* Heading [0/1]
erikstokes
Sí hay. Olvidé mencionar que mordió mi mal.
Mathieu Marques
1
Creo que este malentendido proviene del manual de la organización que no es tan claro en este caso. La línea que comienza "Otra posibilidad es el uso de casillas de verificación ..." es un nuevo párrafo bajo el encabezado "Desglosar las tareas en subtareas". Yo creo que "otra posibilidad" en este caso se refiere a otra posibilidad de dividir las tareas en subtareas no otra posibilidad para cambiar automáticamente el estado de TODO. Tal vez intente su función sugerida y enganche (aunque no pude hacer que esto funcione)
más que el
@elethan En realidad tiene sentido, supongo. Sí, vea mi edición :)
Mathieu Marques
1
Esta es una pregunta frecuente .
NickD

Respuestas:

6

Como mencionó en su pregunta actualizada, org-after-todo-statistics-hookno es lo que quiere. Lo que queremos es org-checkbox-statistics-hook.

Utilizo esta función para hacer lo que usted describe (realmente deberían poner esta funcionalidad en modo org):

(defun my/org-checkbox-todo ()
  "Switch header TODO state to DONE when all checkboxes are ticked, to TODO otherwise"
  (let ((todo-state (org-get-todo-state)) beg end)
    (unless (not todo-state)
      (save-excursion
    (org-back-to-heading t)
    (setq beg (point))
    (end-of-line)
    (setq end (point))
    (goto-char beg)
    (if (re-search-forward "\\[\\([0-9]*%\\)\\]\\|\\[\\([0-9]*\\)/\\([0-9]*\\)\\]"
                   end t)
        (if (match-end 1)
        (if (equal (match-string 1) "100%")
            (unless (string-equal todo-state "DONE")
              (org-todo 'done))
          (unless (string-equal todo-state "TODO")
            (org-todo 'todo)))
          (if (and (> (match-end 2) (match-beginning 2))
               (equal (match-string 2) (match-string 3)))
          (unless (string-equal todo-state "DONE")
            (org-todo 'done))
        (unless (string-equal todo-state "TODO")
          (org-todo 'todo)))))))))

(add-hook 'org-checkbox-statistics-hook 'my/org-checkbox-todo) lo llamará cada vez que active una casilla de verificación.

Requiere que tengas una cookie de estadísticas (lo que obtienes con [/]o [%]luego C-c C-c) en el encabezado.

Inops
fuente
1
¿Tiene una versión que, cuando TODO está programado para repetirse, desmarca la lista de verificación para la programación nuevamente? :)
ctietze
0

Quería una versión que haga lo que @ctietze está buscando: alternar el estado de la casilla de verificación para los elementos de la lista de verificación. Intenté llamar org-reset-checkbox-state-subtreepero obtuve errores sobre demasiados marcos anidados (estoy usando Spacemacs).

Aquí está mi solución de trabajo:

    (defun my/org-reset-checkbox-state-subtree ()
    "Simplified version of org-list builtin"
    ;; Begin copy from org-reset-checkbox-subtree
    (org-narrow-to-subtree)
      (org-show-subtree)
      (goto-char (point-min))
      (let ((end (point-max)))
        (while (< (point) end)
          (when (org-at-item-checkbox-p)
            (replace-match "[ ]" t t nil 1))
          (beginning-of-line 2)))
      (org-update-checkbox-count-maybe 'all)
    ;; End copy from org-reset-checkbox-subtree
    )

  (defun my/org-checkbox-todo ()
    "Switch header TODO state to DONE when all checkboxes are ticked, to TODO otherwise"
    (let ((todo-state (org-get-todo-state)) beg end)
      (unless (not todo-state)
        (save-excursion
          (org-back-to-heading t)
          (setq beg (point))
          (end-of-line)
          (setq end (point))
          (goto-char beg)
          (if (re-search-forward "\\[\\([0-9]*%\\)\\]\\|\\[\\([0-9]*\\)/\\([0-9]*\\)\\]"
                                 end t)
              (if (match-end 1)
                  (if (equal (match-string 1) "100%")
                      (unless (string-equal todo-state "DONE")
                        (my/org-reset-checkbox-state-subtree)
                        (org-todo 'done))
                    (unless (string-equal todo-state "TODO")
                      (org-todo 'todo)))
                (if (and (> (match-end 2) (match-beginning 2))
                         (equal (match-string 2) (match-string 3)))
                    (unless (string-equal todo-state "DONE")
                      (my/org-reset-checkbox-state-subtree)
                      (org-todo 'done))
                  (unless (string-equal todo-state "TODO")
                    (org-todo 'todo)))))))))
  (add-hook 'org-checkbox-statistics-hook 'my/org-checkbox-todo)
Wesley
fuente