8

I've got a list of todo's, and I'd like to change all of the todo's in that list with a single command, instead of moving point to each item and changing the status manually. For example.

* TODO Item 1
** TODO Item 1.1
** TODO Item 1.2
* TODO Item 2

Is there a way to select the whole region and set the todo-state for the whole region? Or any other method?

Bernhard
  • 355
  • 1
  • 9
  • 1
    `M-h` will select the subtree in `org-mode` by default, so that should solve the first part of your problem. As for toggling multiple todos at once, I have no clue whether this can be achieved without writing a custom function. –  Jul 04 '19 at 15:40
  • 1
    Here is an answer I wrote-up a few years ago to carry forward all of my overdue tasks to the current date -- during that process, I programmatically change the todo state in addition to changing the due date. You can modify the example to suit your needs, including, but not limited to confining the changes to an active region: https://emacs.stackexchange.com/a/5700/2287 – lawlist Jul 04 '19 at 16:11

3 Answers3

9

The Org documentation says

Many commands in Org work on the region if the region is active.

And indeed defining a region followed by C-c C-t acts on all headlines in that region. Note that customizable variable org-loop-over-headlines-in-active-region must be set.

A further way is to use the respective bulk agenda action. Possible steps are as follows:

  1. Open an agenda with the todo-items of the buffer. Typically bound to C-c C-a < t.
  2. Mark all items in the agenda by pressing *.
  3. Start the bulk action with B t.
  4. Choose the wanted state.
  5. [optional] Close the agenda with q.

If you follow the recommendation of lawlist you can achieve the greatest control and flexibility, I guess.

Marco Wahl
  • 2,796
  • 11
  • 13
  • 2
    I tried selection the region and making a change with `C-c C-t` before I even posted here, but that doesn't have the desired behavior: it only changes the todo state of the headline at point. I read through the manual to see what's involved in making a region active, but all I learned there is that `transient-mark-mode` needs to be turned on, which it is. Is there anything else involved in making a region active beyond going to the beginning of the region, hitting `C-`, and moving point to the end of the region? – Bernhard Jul 06 '19 at 06:55
  • 1
    Please check the state of variable `org-loop-over-headlines-in-active-region`. To do this you can use `M-x customize-variable org-loop-over-headlines-in-active-region`. – Marco Wahl Jul 06 '19 at 09:54
  • 1
    Bernhard: you have to press d for each headline in the region. It looks like it only changes only the one at point, but the point moves to the next headline and the todo state chooser stays open so you can choose what state to do there. – John Kitchin Jul 06 '19 at 13:29
  • 2
    Marco Wahl: changing the state of the variable `org-loop-over-headlines-in-active-region` solved the problem. Emacs now has exactly the behavior I want. – Bernhard Jul 08 '19 at 05:23
1

If you want to change them all to the same state with a single command you can use a function like this that works on a region or the buffer.

(defun j-change-todo (start end state)
  "Change heading todo states in region defined by START and END to STATE.
Operate on whole buffer if no region is defined."
  (interactive (list
        (if (region-active-p) (region-beginning) (point-min))
        (if (region-active-p) (region-end) (point-max))
        (completing-read "State: " org-todo-keywords-1)))
  (save-excursion
    (goto-char start)
    (when (org-at-heading-p)
      (org-todo state))
    (while (re-search-forward org-heading-regexp end t)
      (org-todo state))))
John Kitchin
  • 11,555
  • 1
  • 19
  • 41
0

If you like helm, here is an approach where you can choose the headings in helm, mark them, and the change the state on all of them.

(require 'helm-org)

(defun j-helm-org-todo (candidate)
  (let ((state (completing-read "State: " org-todo-keywords-1)))
    (save-excursion
      (cl-loop for marker in (helm-marked-candidates) do
           (goto-char marker)
           (org-todo state)))))

(add-to-list 'helm-org-headings-actions '("Set todo state" . j-helm-org-todo) t)
John Kitchin
  • 11,555
  • 1
  • 19
  • 41