Back in 2011 I started tracking the minutiae of my work days using VoodooPad. It was partly for record keeping, but mostly to be able to walk away from my computer and still be able to remember what I was doing when I got back. I can be very, very scatterbrained. After VoodooPad, I had a system going using QuickQuestion and nvALT. Then it was Day One. By 2014 I’d come up with a solution in the form of a command line utility called
doing. The journey was well documented up to that point in a series called, appropriately enough, “Scatterbrained.”
I haven’t written much about
doing since then, but I continue to use it daily. It’s come a long way. It not only creates rich logs of my time at my computer, it also handles time tracking and reporting and integrates with my system via LaunchBar, various automations, and GeekTool. You know how
git log can be really useful after a long night of hacking, or a few days of being away?1 This is that, but for everything else, and it’s brimming with handy features.
Given I’ve been working on this as needed for 5 years now, it hasn’t felt like a descent into madness as much as a gentle slide into areas of questionable judgment. I find it a very useful tool, though, as long as I don’t think too much about how much time I’ve put into it.
After publishing a few new versions over the last couple of months, I thought it might be time to remind potential users (people who read this blog and enjoy my brand of madness) that it exists. This is going to be a longish post where I get to talk giddily about all the cool stuff this little tool can do. If you’re already sold — or at least enough to skip the spiel — and want to skip right to the documentation and the latest version, just head straight to the
doing project page.
Before we go much further, I should make something clear.
doing is primarily designed for use from the command line in your terminal of choice. It’s by a nerd, for nerds. I have, however, integrated it with LaunchBar and other systems over the years. It’s flexible. The LaunchBar action is included below, if you’re interested.
The basic idea of
doing is to provide a way to keep track of the little things I work on over the course of a day, both as a reminder after I leave and forget what I was working on, and as a way to track my productivity.
It does this using a terminal command with an intuitive syntax. The command updates a simple TaskPaper-formatted text file. (You may be aware of my love of plain text…) It does some automatic time tracking, has a variety of tools for viewing your entries, and includes a few ways to do things like filtering, flagging, or archiving them. More tools than I’ll be able to fit into a blog post, even a long one, but the documentation is detailed and up-to-date.
If you’ve used Git before, the concept will be familiar. Just type in what you were working on, like you would for a commit, including as many notes as needed, and hit Enter to add it to the log. Doing even has query features that I dare say make it even more useful than
git log. Sometimes. It depends on the situation. How about this: “in a very particular set of circumstances for a very specific set of needs,
doing is more useful than
You can install
doing using Rubygems, i.e.
gem install doing (you might need
sudo gem install doing depending on your configuration). Once that’s successful, you can start recording entries right away, but I’d wait until you’ve read through the configuration section of the docs before going overboard. There are a few things you’ll want to adjust, including the location and name of your “doing file.”
doing uses subcommands, meaning you call
doing and the next word in the command will determine what action it performs. This allows for (almost) natural syntaxes for most actions. The main command for adding a new entry is
doing now [what you are doing].
now is also aliased as
next as of recent versions, just because that sometimes makes more semantic sense. Like I said, almost human syntax.
You only need quotes around the entry if it contains characters the shell needs escaped, so I can just type
doing now writing about doing. An entry will be created with the current time as the start time. There are features for modifying the start and finish times using natural language, but we’ll get to those in a bit.
You can add @tags in the text of an entry to allow for future sorting and filtering fun. (Tags use
@ instead of
#, first because that’s a TaskPaper standard, and second because
# causes a lot of extra work on the command line.) You can also include notes with a
-n "[Note Text]" flag.
If you want to modify tags and notes after the fact, just run
doing tag writing to add @writing to the last entry, or
doing note to open an editor, the results of which are appended as a note. And when you’re done doing what you’re doing, you can just run
doing finish to add a stop time to the last task. Remember, all of this is stored in a TaskPaper file that you can manually edit at any time. Just run
doing open to open the file in your default text editor.
You can see all of
doing’s commands by running
doing help. That will show you something like:
You can get help for any subcommand by running
doing help [command], e.g.
doing help meanwhile.
Seeing What You’re Doing
There are myriad ways to filter and view your tasks. Commands like
yesterday are pretty self-explanatory, but the real workhorses are the
doing show and
doing view commands. Combined with custom templates, you can do everything from terminal time tracking to viewing HTML-formatted work logs in the browser. You can even get CSV and JSON output for passing to other tools.
doing show accepts a section name and/or tag names. By default
doing creates sections (what would be projects in TaskPaper) for “Currently” and “Archive”. If you use
doing later, it automatically adds a “Later” section. You can add as many custom sections as you want, either by editing the file directly (
doing open) or by using
doing add_section [Section Name].
For example, I keep a running list of random ideas in a separate section (called “Ideas,” obviously). It lets me get ideas out of my head without going down rabbit holes or worrying that I’ll forget about them. I can add to that section using
doing done -s Ideas My great @idea. Note that I used
done because I’m not time tracking these, so it makes sense to add them as finished entries right away, and I also included an @idea tag. I actually have an alias for this that lets me just type
idea My great idea, and the word “idea” is always automatically tagged using a tagging whitelist in my configuration file. (See the section on autotagging further down.)
Now I can just run
doing show Ideas and see all of my ideas listed out. I can also run
doing show @idea to show entries tagged with @idea across all of my sections. And I can combine the two to show just entries with a particular tag within a particular section, e.g.
doing show Ideas @coding. You can even include multiple tags and use the
-b [AND|OR|NONE] flag to define the boolean used to search. So
doing show -b OR @idea @brainstorm @thinking would show any entry tagged with any of @idea, @brainstorm, or @thinking.
view command is similar to
show, but allows you to customize all of the aspects of the view, from what section/tags to include to the output template. Using the
.doingrc config file (documentation), you can define named views with custom parameters and templates. I have a view set up called “ideas” that lets me run
doing view ideas and have my ideas shown like this:
This is accomplished with a section in the YAML-formatted config file:
Among my other views is one for GeekTool2 which puts my three most recent entries across all sections on my Desktop, formatted as single lines with no notes, and a date format string that keeps everything aligned nicely (when used with a mono font).
The view for that one:
There are a ton of options for the view and show commands, so run
doing help show and
doing help view to get a feel for them. There’s even an HTML output option (
doing show [section/tag] -o html) you can pipe to
hcat. It works with any view or show command, just add
-o html anywhere after the subcommand, e.g.
doing show Archive @marked -o html|bcat. You can also output any
view command as JSON or CSV, overriding the template to provide structured data.
At the outset I had no intention of using
doing for time tracking. Time tracking kind of evolved over time. It’s still not going to beat an actual time tracking app, nor any automated time tracking like Timing. Nonetheless,
doing has some handy tools.
All of these commands operate on the “Currently” section by default, and can be pointed at other sections using
-s SECTION_NAME. The section name is fuzzy matched and case insensitive.
As I mentioned previously, commands like
done allow various combinations of
--back for fudging times if you haven’t been religiously logging every step. Using
--back lets you modify the start date with natural language, e.g.
doing now --back 30m Starting the thing to start it 30 minutes ago. Similarly,
doing done --took 1h will finish the last task by adding an hour to whatever the start date was. You can also add a task complete with retrospective time tracking using a single command, e.g.
doing done --took 2h working on website typography.
There’s also a
meanwhile command that lets you maintain an overarching task, like a major project, while you knock off smaller items within it. You can start a meanwhile task with
doing meanwhile Working on the @ACME job, optionally with a
--back 2h, and then next time you run
doing meanwhile it will finish that task, even if it wasn’t the last thing added. Starting a meanwhile task always finishes any currently-running “meanwhile”.
You can finish your last task with
doing done (with no entry text), or
doing finish, both of which accept both
--took. Supply a count with
finish to finish the last X tasks, i.e.
doing finish 5. One useful feature of
finish is the
--auto flag which will go through the last X entries and add finish times to each one based on the start time of the next one. It comes in handy.
Similar to the
doing finish --auto trick, if you use
--finish_last) with the
now command, it will check the previous item and see if it’s been tagged @done yet. If not, it will finish the previous entry with a timestamp matching the start time of the new item. When you’re in a mode where you’re logging each task as you start it, rather than retroactively (as I often do), this feature just allows you to skip the step of completing a task before starting a new one.
All of the view commands can show how long tasks took. In the default views, any task that has an interval between its start and end times will show a HH:MM:SS token at the end of the task. This can be modified in the various templates. Running a
show command with
--totals will add up total times by tag, and you can use
--only_timed with the
show command to only output entries with elapsed times.
Tagging and Time Tracking
Total times are displayed by tag. Adding a project tag allows you to see how much time went into each project. You can have multiple tags, of course, so you can have three different project tags but all of them get a @coding tag, so you can see each project but also a total for time spent in the coding context.
When it comes to tagging projects for time tracking, there are a couple of approaches. First, you can just manually add a tag to denote what the time should be attributed to, and you can overlap tags as needed. But you can automate this by using a “local”
.doingrc file in your project directory. Configuration files found anywhere between the current directory and the root are applied on top of the main configuration, cascading such that the closest one takes precedence. Only the keys you want to override are needed.
For example, in the directory for Marked development (~/Code/Marked) there’s a
.doingrc file that just contains:
--- default_tags: [marked]
And one in the parent directory (~/Code) with:
--- default_tags: [coding]
Any entry I make from the Marked directory (or any of its subdirectories) will get tagged “@marked @coding” automatically.
You can also tag the last task retroactively using
doing tag TAGNAME. Or just run
doing open and edit the file directly.
doing consists of “whitelisting” and “synonyms”. The synonyms feature is pretty cool: you can add a tag and then list all of the keywords that should trigger that tag. If a keyword appears in an entry, that tag gets added automatically.
The whitelist, on the other hand, is a list of words that should be directly turned into tags. If the list contains “design” and I type “Working on site design,” that gets converted to “Working on site @design.” Whereas if I had “design” set up with synonyms which include “typography,” I could write “Working on site typography” and it would become “Working on site typography @design.” Handy.
Automatic tags will never be repeated within an entry, so if you manually tag any of the defined tags it will skip adding them, and only the first occurrence of a keyword is converted into a tag.
You can include time intervals in any template or view using the
%interval template key. If a project has no time between the start and finish timestamp then nothing will display. This is great for seeing how much time you’ve put into things over the day.
To get a real report you can use
doing show or
doing view with
--totals. With the
show command you can use
--from to specify a date or date range, and then provide @tags to show only the time spent on a specific project within a specific range.
Any project or activity you have a tag for is easily reported. An example command would look like:
doing show -t --totals --from="saturday to sunday" @writing
This gives me a report of what I’ve spent my time writing about this weekend. In this case, it’s all about this post. It will show all of the pertinent entries, with a block at the end containing totals for each tag and total elapsed time. Here’s what the above results look like for the weekend:
--- Tag Totals --- doing: 00:02:15 writing: 00:02:15 Total tracked: 00:02:15
The more tags you have, the more detailed and flexible the reporting results are. And, as with any of the views, you can output this to nicely formatted HTML by adding
-o html to the command.
By having overarching project tags as well as tags for various contexts like @designing, @coding, @writing, it’s easy to see how much total time went into a project, as well as exactly where the time was allocated. You can tag for anything. And if you make good use of the autotagging features, most of the work is done automatically.
Side note, when I forget to add a
doing entry but wished I had, I load up Timing.app and am able to see what files I had open, when, and for how long. It’s the other half of my “too-scatterbrained-for-time-tracking” time tracking system.
Even More Natural Language
I’ve created a few aliases and functions as
doing shortcuts over the years, but it’s all pretty simple. A verb with a function that specifies a section or adds tags, etc. Something as simple as
alias thinking="doing now -s Ideas Thinking " means I can type
thinking about digging back into React again and have that added to my Ideas list.
You can also use a wrapper function to handle all kinds of natural language. Here’s an example for Bash:
Working with entries
The beauty of the whole system is that you can open the doing file in your text editor or in TaskPaper at any time to make quick work of modifying your entries. You can specify an editor app in your
.doingrc and then run
doing open at any time to open the file.
In an effort to make things simpler, though,
doing includes commands for flagging entries, archiving them, and batch moving them between sections. Want to archive everything in your Ideas section, keeping only the last three?
doing archive --keep=3 Ideas. The archive command also accepts
--to=[Section] to move entries to a section other than Archive. You can also specify a @tag to archive or move entries matching a tag, rather than just the last entries chronologically.
I won’t dig deep on automating, but I’ll point out that I’ve had great results using git hooks to update doing. You’ll also find scripts for LaunchBar and Alfred, as well as Bash, Fish, and Zsh completion on the project page. Whether it’s GeekTool, browser pipes with bcat, LaunchBar, or just the terminal,
doing is designed to work with other tools as much as possible.
That got long, and it’s just an overview — I didn’t even cover all of the features. Or this is just the rantings of a madman. Hard to say sometimes. As mentioned previously, the documentation is complete and the built-in help system is verbose enough to fill in any gaps.
Like Marked 2, SearchLink, Reiki,
na, or any of my pet projects,
doing is one of my babies. I use it every day, and I bend it to fit my needs as they arise. I don’t need a large user base or an influx of donations to make it worthwhile, it’s fun to work on and I find it consistently useful. That said, feel free to try it out!