5

In an org file, is it possible to customize the task sequence by category? For instance, if I have a meeting, I would like to have it evolving through the states TODO and DONE, while if I'm tracking my progress on a MOOC, I may want to have TODO, STARTED, SUSPENDED, COMPLETE. Any hint?

4

stsquad's answer is the way to go if you have one file where you want to use a different sequence. If the keywords are all different, it's also possible to make both sequences available in the same file.

(setq org-todo-keywords
      '((sequence "TODO" "|" "DONE")
        (sequence "MOOC" "STARTED" "|" "COMPLETE" "SUSPENDED")))

See (info "(org) TODO extensions") for more information.


(As pointed out in the comments, this question was about choosing a TODO sequence based on categories.)

Here's one (not thoroughly tested) approach.

You can set up multiple sequences using the standard approach.

(setq org-todo-keywords
      '((sequence "TODO" "|" "DONE")
        (sequence "MOOC" "STARTED" "|" "COMPLETE" "SUSPENDED")))

Then create a custom function that starts the TODO in the desired state based on the current category. After that, let the interactive org-todo take over, because it will stay in that sequence.

(defun km/org-todo ()
  "Change TODO state of item, considering current category.

Run `org-todo', but choose the initial state based on the
category. If the the heading does not already have a TODO state
and the current category is in `km/org-category-todo-starts',
change the heading to that state.

Otherwise, run `org-todo' interactively."
  (interactive)
  (let ((current-todo (org-get-todo-state))
        (category-todo (km/org-select-todo-by-category)))
    (if (and (not current-todo)
             category-todo)
        (org-todo category-todo)
      (call-interactively 'org-todo))))

(defun km/org-select-todo-by-category ()
  "Choose starting TODO keyword based on the category.
If no value is found for the category, return the value for
`default'."
  (or (cdr (assoc (org-no-properties (org-get-category))
                  km/org-category-todo-starts))
      (cdr (assoc 'default km/org-category-todo-starts))))

(defvar km/org-category-todo-starts '((default . "TODO")
                                      ("mooc" . "MOOC"))
  "List of properties and first TODO keyword to start with.
The TODO keyword should be present in `org-todo-keywords'.")

This can be remapped so that C-c C-t will call this function instead.

(define-key org-mode-map [remap org-todo] 'km/org-todo)

(Note that if you use speed commands, t will still call org-todo, so you'd have to override that separately.)

| improve this answer | |
  • Thanks for the reply. I have something like this already set up and it could work. But I'd like to have something more, getting the right sequence for the proper category. So, if I add a new task which is a MOOC and press C-c C-t I should only see the second sequence. – petrux Oct 29 '14 at 16:00
  • Sorry, I should've read your question more carefully. I don't know of any built-in mechanism where the todo sequence is aware of the category context. – Kyle Meyer Oct 29 '14 at 16:34
3

You can split your tasks across files and then at the top of each file add:

#+TODO: TODO(t) STARTED(s) REVIEW(r) LIST(l) PULL(p) | DONE(d) CANCELED(c) UPSTREAM(u)
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.