How I Use Emacs To Manage a Project

Using Org Mode to Wrangle the Essentials of Tracking Time and Effort

Emacs is a text editor that is renowned for its almost comical levels of customizability and for espousing an extreme kitchen-sink attitude toward features. Chances are if you have a need for some desktop app, Emacs probably already has it, or is a small package away from including it. Calculator? Check. Calendar? Check. Connect to a database? Check. Play some Tetris? Check. You’re beginning to get the picture.

One workflow that I’ve found pretty useful for working on client projects falls somewhere in between the features of Harvest (time tracking) and Jira (project management). This post details how I use Emacs’ Org mode to replicate the essentials of these features in a way where I don’t have to leave my editor.

Getting Started

The first step is that I create a hidden org file somewhere in the client project. I don’t need to share my notes and scribblings with other developers on the project and so I’ll create a docs folder in the root:

cd project
mkdir docs
echo docs >> .git/info/exclude

If you haven’t ever seen the exclude file, it works just like git’s .gitignore file except it itself is not tracked in version control. You can add things here that nobody else has any interest in having to deal with. Maybe you’re the only developer using RubyMine. Just add the .idea directory and be on your way.

Org Mode

Now comes the fun part! I fire up Emacs and do an C-x C-f (or M-x find-file (see footnote)) then I type or paste the following into the buffer:

#+title: ACME Stories
#+author: Christopher Wilson
#+date: 2022-11-14
#+TODO: TODO PROG REVW BLOK | DONE

#+BEGIN: clocktable :scope file :block thisweek :maxlevel 2 :step day :stepskip0 t
#+END:

This is more or less boilerplate metadata. The clocktable is magic, we’ll get to that in a sec. But a few things to note: I add a custom series of TODO states on line 4. This matches what’s in Jira more closely for the project that I’m on. A story can be todo, in progress, in review, blocked, and lastly done. By default, Org mode just gives you a todo/done (or neither) state. States right of the vertical pipe are finished states. As with everything Emacs or Org mode, there’s a boatload of other customization possible.

After this block I add some stories that I’m working on. I just grab these story numbers directly from Jira. There’s probably… [puts finger to earpiece] I’m being told that there definitely is a Jira mode. Anyway, I don’t need that. I’ll take the story numbers:

* TODO ACME-2311

* TODO ACME-2075

* TODO ACME-2285

* TODO ACME-2452

As I work on a story, I cycle the status using C-c C-t.

* PROG ACME-2311

Ah, yes, now I’m in progress on 2311. Another thing that comes up is that I need to track my efforts through estimation. That’s easy, I use C-c C-x e (or M-x org-set-effort). I type in “6h” to indicate that I’ve estimated that this story should take me around 6 hours to complete. Emacs deals in hours as far as I have been able to tell. Maybe just think of these as story points if that irks you too much. Now my buffer looks like this:

* PROG ACME-2311
:PROPERTIES:
:Effort:   6h
:END:

Initially, Emacs has the so-called properties drawer collapsed. When I move the cursor over that line and press TAB, it expands open and I can see my estimate. Now as I work on stories at various times, I clock in and out on them. When I want to start working on something, I type C-c C-x C-i (or M-x org-clock-in). Once I do this, I’ll see a logbook drawer appear with a timestamp for when I clocked in:

* PROG ACME-2311
:PROPERTIES:
:Effort:   6h
:END:
:LOGBOOK:
CLOCK: [2023-02-01 Wed 15:12]
:END:

When I’m done with that story, or just want to change to working on something else, I clock out: C-c C-x C-o (M-x org-clock-out):

* PROG ACME-2311
:PROPERTIES:
:Effort:   6h
:END:
:LOGBOOK:
CLOCK: [2023-02-01 Wed 15:12]--[2023-02-01 Wed 15:16] =>  0:04
:END:

After I’ve worked on a bunch of stuff and finished some things off, here’s what my stories may look like:

* BLOK ACME-2311
:PROPERTIES:
:Effort:   6h
:END:
:LOGBOOK:
CLOCK: [2023-01-31 Tue 13:25]--[2023-01-31 Tue 15:05] =>  1:40
:END:

* DONE ACME-2075
:PROPERTIES:
:Effort:   6h
:END:
:LOGBOOK:
CLOCK: [2023-02-01 Wed 09:00]--[2023-02-01 Wed 09:30] =>  0:30
CLOCK: [2023-01-31 Tue 16:05]--[2023-01-31 Tue 16:35] =>  0:30
CLOCK: [2023-01-31 Tue 12:50]--[2023-01-31 Tue 13:25] =>  0:35
:END:

* DONE ACME-2285
:LOGBOOK:
CLOCK: [2023-01-31 Tue 12:05]--[2023-01-31 Tue 12:50] =>  0:45
CLOCK: [2023-01-30 Mon 15:55]--[2023-01-30 Mon 18:00] =>  2:05
CLOCK: [2023-01-30 Mon 11:35]--[2023-01-30 Mon 12:35] =>  1:00
:END:

* DONE ACME-2452
:LOGBOOK:
CLOCK: [2023-01-31 Tue 09:00]--[2023-01-31 Tue 10:00] =>  1:00
CLOCK: [2023-01-30 Mon 15:10]--[2023-01-30 Mon 15:55] =>  0:45
CLOCK: [2023-01-30 Mon 10:40]--[2023-01-30 Mon 11:35] =>  0:55
CLOCK: [2023-01-30 Mon 09:00]--[2023-01-30 Mon 09:20] =>  0:20
CLOCK: [2023-01-26 Thu 09:00]--[2023-01-26 Thu 09:15] =>  0:15
CLOCK: [2023-01-25 Wed 13:15]--[2023-01-25 Wed 13:40] =>  0:25
CLOCK: [2023-01-25 Wed 11:15]--[2023-01-25 Wed 11:55] =>  0:40
:END:

It’s a lot, but you can see that it’s all pretty mechanical and Emacs keeps track of times as I clock in or out. I can also adjust timestamps by holding shift and pressing up/down to move in 5 min increments. But now let’s look at the clocktable line.

The Clocktable

Remember the somewhat cryptic line:

#+BEGIN: clocktable :scope file :block thisweek :maxlevel 2 :step day :stepskip0 t

Well here’s where that becomes super useful. I’ve set this up so that every first and second level heading is turned into a time report. If I hit C-c C-c on this line, Emacs fills in the area between that and the #+END:

#+BEGIN: clocktable :scope file :block thisweek :maxlevel 2 :step day :stepskip0 t

Daily report: [2023-01-30 Mon]
| Headline     |   Time |
|--------------+--------|
| *Total time* | *5:05* |
|--------------+--------|
| ACME-2285    |   3:05 |
| ACME-2452    |   2:00 |

Daily report: [2023-01-31 Tue]
| Headline     |   Time |
|--------------+--------|
| *Total time* | *4:30* |
|--------------+--------|
| ACME-2311    |   1:40 |
| ACME-2075    |   1:05 |
| ACME-2285    |   0:45 |
| ACME-2452    |   1:00 |

Daily report: [2023-02-01 Wed]
| Headline     | Time   |
|--------------+--------|
| *Total time* | *0:30* |
|--------------+--------|
| ACME-2075    | 0:30   |

#+END:

The stories that I worked on are itemized for each day in this table. At the end of the week, I may want a slightly different table, so I change :step day to :step week. I then hit C-c C-c again and the table regenerates:

#+BEGIN: clocktable :scope file :block thisweek :maxlevel 2 :step week :stepskip0 t

Weekly report starting on: [2023-01-30 Mon]
| Headline     |    Time |
|--------------+---------|
| *Total time* | *10:05* |
|--------------+---------|
| ACME-2311    |    1:40 |
| ACME-2075    |    1:35 |
| ACME-2285    |    3:50 |
| ACME-2452    |    3:00 |
#+END:

I’m then able to use these two tables to fill in a detailed timesheet like in Harvest. I also have a good idea of where I came out on my estimates for effort.

Now You’re Thinking with Emacs

Emacs, of course, possess a stupefying amount of detail in exactly how each of these features works. You can develop your own workflow or use mine as a starting point. At its core, Org Mode is really a toolkit for building hierarchy-oriented documents. There are tables, formatting, export to HTML/PDF, structure editing, and lots more. You can think of this as very general note-taking software that has had many other features bolted on. And even if you’re not familiar, nor interested in, Emacs as a text editor, you may still get some great usage out of it as a non-programming personal productivity tool. In fact one writer does just that. Good luck!


  1. A brief note for anyone not familiar with Emacs hotkeys. When I say “C-x” that means hold “Ctrl” and press “x”. “M-x” similarly means hold “Alt” (or Option on Mac) and then press “x”. For example, the M-x emacs key command would be written like ⌥X elsewhere in Mac OS. After pressing M-x you can then type the named function, like “find-file” to execute the command. In emacs all keys are actually bound to functions and so have an equivalent way to say “M-x name-of-function” as well as any key combo that the function may be bound to.

If you’re looking for a team to help you discover the right thing to build and help you build it, get in touch.

Published on February 16, 2023