Jak automatycznie dostosować stan zadania Org za pomocą jego pól wyboru potomnych

10

W moim pliku Org mam kilka zadań, z których jedno zawiera elementy zaczynające się od pola wyboru (ale tylko te). Wszystkie mają na końcu statystyczny plik cookie ([n / m]).

Szukam sposobu na automatyczną aktualizację zadania nadrzędnego od TODOdo DONEmomentu, gdy wszystkie pola wyboru zostaną oznaczone jako wykonane.

Dokumentacja mówi:

Jeśli chcesz, aby pozycja DO ZROBIENIA automatycznie zmieniała się na GOTOWE, gdy wszystkie dzieci są gotowe, możesz użyć następującej konfiguracji [...]

Inną możliwością jest użycie pól wyboru do identyfikacji (hierarchii) dużej liczby podzadań (patrz Pola wyboru).

Rozumiem, że ostatnia część jest taka, że ​​jeśli elementy potomne są polami wyboru, stan nadrzędny powinien już być automatycznie aktualizowany (co nie jest prawdą).

czego mi brakuje?


Edytować:

Z org-after-todo-statistics-hookdokumentacji (org.el):

Zaczep wywoływany po zaktualizowaniu pliku cookie statystyk TODO. Każda funkcja jest wywoływana z dwoma argumentami: liczbą niezrealizowanych wpisów i liczbą wykonanych wpisów.

Co oznacza, że ​​proponowany kod z 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)

nie będzie liczyć elementów pola wyboru.

Mathieu Marques
źródło
Czy masz nagłówek statystyczny plik cookie? W ten sposób:* Heading [0/1]
erikstokes
Tak jest. Zapomniałem wspomnieć, że to trochę mnie źle.
Mathieu Marques
1
Myślę, że to nieporozumienie wynika z niezrozumiałego w tym przypadku podręcznika organizacji. Linia rozpoczynająca się od „Inną możliwością jest użycie pól wyboru ...” to nowy akapit pod nagłówkiem „Podział zadań na podzadania”. Myślę , że „inna możliwość” w tym przypadku odnosi się do innej możliwości podziału zadań na podzadania, a nie innej możliwości automatycznej zmiany stanu TODO. Może wypróbuj ich sugerowaną funkcję i zaczep (chociaż nie mogłem tego dostać do wokr)
elethan
@elethan To chyba ma sens. Tak, zobacz moją edycję :)
Mathieu Marques
1
To jest FAQ .
NickD

Odpowiedzi:

6

Jak wspomniałeś w zaktualizowanym pytaniu, org-after-todo-statistics-hooknie jest to, czego chcesz. To czego chcesz org-checkbox-statistics-hook.

Używam tej funkcji do robienia tego, co opisujesz (naprawdę powinni wprowadzić tę funkcję do trybu 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) będzie to nazywać za każdym razem, gdy przełączasz pole wyboru.

Wymaga to pliku cookie statystyk (rzecz, którą otrzymujesz [/]lub [%]wtedy C-c C-c) w nagłówku.

Inops
źródło
1
Czy zdarza ci się mieć wersję, która po powtórzeniu TODO odznacza listę kontrolną dla harmonogramu? :)
ctietze
0

Chciałem wersji, która spełnia to, czego szuka @ctietze - przełącz stan pola wyboru dla elementów na liście kontrolnej. Próbowałem zadzwonić, org-reset-checkbox-state-subtreeale wystąpiły błędy dotyczące zbyt wielu zagnieżdżonych ramek (używam Spacemac).

Oto moje działające rozwiązanie:

    (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
źródło