π

UOMF: On How to Define Projects in Org Mode

Show Sidebar

Update 2019-11-09: my-mark-as-project()

This is an article from a series of blog postings. Please do read my "Using Org Mode Features" (UOMF) series page for explanations on articles of this series.

In my world, I tend to define "projects" as a construct that contains a set of tasks in order to reach a common project goal.

Within Org mode, I need a syntax element to decorate my projects as such in order to make sure Org recognizes projects in case I need Org mode support for projects.

Why Defining Projects in Org Mode?

For a long period of time, I was using Org mode without any construct of a project. Whenever there was a TODO keyword, it was a task. Whenever there were tasks below a heading, this was a project.

This resulted in some more or less subtle issues. For example, if the project heading also features a TODO keyword, I do have issues. A few questions I could not answer clearly for myself were:

A technical issue arises when projects were marked as DONE when sub-tasks were still open. While org-enforce-todo-dependencies enables me to prevent this, I am ambivalent here.

On the one hand side, I do want to make sure that projects are only DONE when each task is done as well. On the other hand side, there are projects that are DONE where single tasks that were created during the project are still open for good reasons. One example would be a re-check task after a certain period of time. By default, these tasks never show up on my agenda because tasks within a DONE sub-hierarchy are ignored on my agenda. See org-agenda-todo-list-sublevels for details.

I somehow get the feeling that finding a technical solution for this last issue would only bring new issues: archiving, re-filing tasks to a finalized project, ...

Therefore, I started to sit down and think of how I want to work with projects within Org mode.

If you can not think of using Org mode project agendas or similar, you do not even have to continue reading this article. If it works for you how you do it currently, it's perfectly fine - as always. However, you should be aware of the potential consequences for your future self.

Using Tags to Define a Project

My Org manual says in the section about "stuck projects" that the default definition of "project" is that they are level-2 headlines with some sub-headings.

I personally do not have this situation: my projects can occur on any level of heading from top-level down to probably level ten or even more.

The manual further mentions as an example: "Let’s assume that you, in your own way of using Org mode, identify projects with a tag PROJECT [...]".

In my opinion, this does not work as soon as I am using tag inheritance. In this case, all associated TODO headings would be tagged with PROJECT in my agenda. While some people might be OK with that, I do find this a redundant agenda information I want to get rid of. Now there is org-tags-exclude-from-inheritance which is able to exclude the tag PROJECT from being inherited to its associated tasks.

Following this rationale, the first possible syntax for a project is a tag which is excluded from inheritance.

Using Todo Keywords to Define a Project

John Wiegley showed us, that he is using a TODO keyword to define a project: PROJECT. To be fair, John also has a slightly different definition of a "project". See minute one and thirty seconds of the linked video.

While I generally do think that John has excellent choices on how he is doing things, I tend to disagree here about the use of TODO keywords for projects.

The variable org-todo-keywords defines "TODO keywords" and "DONE states". Ignoring the included semantic conflict ("keywords" versus "states" for the same thing), this means that a TODO keyword is either an undone one or a done one.

By the way, I would never use TODO keywords to mark a task being done by somebody else as "TODO keywords as types" suggests. I recommend multi-classification using tags instead. But I'm drifting off.

Back to our PROJECT keyword. Since we only got two classes of TODO keywords (undone/done), we would need to assign the PROJECT keyword to one of the two classifications.

For obvious reasons, PROJECT can not be part of the done TODO keyword class. If I'd choose that PROJECT is an undone TODO keyword class, I'd lose the notion that the resolved project once was actually a project. I'd have to probably introduce an additional TODO keyword for the done class: DONEPROJECT or similar.

If I want to use TODO keywords to define a project, I'd have to introduce two TODO keywords such as PROJECT and DONEPROJECT.

And this is why I don't think that TODO keywords are the first choice to define projects. They would interfere with cycling through TODO keywords on simple tasks. Dozens of time each day I'd have to make sure that I don't accidentally cycle to one of the two project keywords for a simple task.

Using Progress Cookies to Define a Project

Progress cookies are explained in the manual section "Breaking tasks down into subtasks". It's very easy to use. You just have to enter [/] or [%] within any given heading line. When you add a new sub-task, this then gets changed by Org mode to [0/1] or [0%] respectively. Having four sub-tasks with three of them done, this then turns into [3/4] or [75%] respectively.

For the most recent years, I gradually switched to mark projects with [/] as the very first part of the heading line without any TODO keyword or tag.

This way, I got a good overview while navigating through my Org mode files, on how many open and closed tasks the next level of heading contains. So far, I did not have the urge to include projects into my agenda as long as it did not happen when I assigned TODO keywords to them.

In practice, using progress cookies could get complicated. You have to learn about the behaviour related to checkboxes versus tasks which is controlled via the property COOKIE_DATA. Further more, you need to decide if you would also like to include the open tasks in a recursive way which is controlled by org-hierarchical-todo-statistics.

To be honest, I should have used the property :COOKIE_DATA: todo recursive right from the start for projects. I was not aware of the implications on not doing this when I started it.

So far, I tend to like progress cookies as project indicator. However, if you rely on stuck project agendas or similar, you might not find suitable support within Org mode with progress cookies alone.

My Approach

Having thought about my formal way of handling Org mode projects, I will probably continue using progress indicators but with the COOKIE_DATA property set to todo recursive. As a matter of fact, I'd prefer to use an elisp setting in my init.el instead of having to add this property to all of my scattered project headings. If you know how to do this via elisp, please write me a comment.

I was not aware of org-tags-exclude-from-inheritance any more. Therefore, I thought that tags do not qualify for project indicators. Having changed this, I'm now open to try a hybrid approach. Additionally to the progress cookies, I could tag my projects with :project: in order to help Org mode. Following function is doing a great job in simplifying this approach:

(defun my-mark-as-project ()
"This function makes sure that the current heading has
(1) the tag :project:
(2) has property COOKIE_DATA set to \"todo recursive\"
(3) has any TODO keyword and
(4) a leading progress indicator"
    (interactive)
    (org-toggle-tag "project" 'on)
    (org-set-property "COOKIE_DATA" "todo recursive")
    (org-back-to-heading t)
    (let* ((title (nth 4 (org-heading-components)))
           (keyword (nth 2 (org-heading-components))))
       (when (and (bound-and-true-p keyword) (string-prefix-p "[" title))
           (message "TODO keyword and progress indicator found")
           )
       (when (and (not (bound-and-true-p keyword)) (string-prefix-p "[" title))
           (message "no TODO keyword but progress indicator found")
           (forward-whitespace 1)
           (insert "NEXT ")
           )
       (when (and (not (bound-and-true-p keyword)) (not (string-prefix-p "[" title)))
           (message "no TODO keyword and no progress indicator found")
           (forward-whitespace 1)
           (insert "NEXT [/] ")
           )
       (when (and (bound-and-true-p keyword) (not (string-prefix-p "[" title)))
           (message "TODO keyword but no progress indicator found")
           (forward-whitespace 2)
           (insert "[/] ")
           )
       )
)	  

By trying this approach, I might as well think of testing "stuck project" agendas although I don't think I'd use them a lot. I simply have too many stuck projects I won't be able to finish during my life-time already given the rate of projects and tasks I'm adding to my system.

So this journey is not over for me. As always, that's just my current point of view using my current knowledge on Org mode. The thing you should take away from this article is that you might want to sit down and think a couple of minutes before creating projects that are not defined as such when you might regret this in a later stage. If not, you learned a bit here or there about Org mode, I hope.


Related articles that link to this one:

Comment via email or via Disqus comments below: