Saving Blog Comments in Org-Mode with Clocking

After using </emacs/org-mode/saving-blog-comments-in-org|my mix of edit-server and org-capture for blog comments> for a while (see that page for instructions on setting up the org-mode template), I realized I’d like to have org-mode clock the time I spend commenting on blogs. I already have a ‘Reading Blogs’ task that I clock in for that, but it’d be nice to clock commenting separately, since that’s creating content. Plus, org-mode’s clocking is so nice that I like to use it as well as possible.

At first I wasn’t sure how to do it, though. Org-capture has clocking built-in, but I couldn’t use that, because I’m not editing in the org-capture buffer. Editing the comment is done in an edit-server buffer, then passed to org-capture. So clocking in the org-capture buffer would only count the split-second it takes to file the task.

I dug through the source of both edit-server.el and org-capture.el, looking for a way to tie the two together. I thought I might be able to get edit-server.el to do the clocking itself. Then I thought maybe edit-server.el could pass the text on to be edited in the org-capture buffer, which could then send it back to edit-server to be sent back to the browser. I think either of those would be doable, but they’d require hacking on the source of one or both modes, which I wanted to avoid if possible.

Then I had a new thought: I don’t actually need to clock the individual comments. In fact, I’d rather not break it down that fine; I just want to keep track of time spent on blog commenting in general. That gave me the answer: create a new task called ‘Blog Commenting’, and clock that task in while I’m working in the edit-server buffer, and clock out that task when I exit it. That turned out to be fairly easy to do.

First, I needed the ‘Blog Commenting’ task, and a way to clock it in from anywhere else in Emacs. I created it as a task in comments.org, above the datetree section, and gave it a unique ID property with org-id-get-create (creates an ID for the current task if one doesn’t already exist). That gave me this (your ID value will be different):

* NEXT Blog Commenting
:PROPERTIES:
:ID:       0312e0bf-6c55-4657-b2aa-5d92817d4d3f
:END:

Now I need to add a function to the hook that edit-server runs when starting an edit buffer on a new comment. This code in my .emacs does that. org-id-find returns a marker to the task containing the ID I just created in the Blog Commenting task (and copy-pasted to this code), and org-with-point-at runs org-clock-in on that task:

(defun ajb/clock-in-blog-commenting-task ()
  "Clock in the special commenting task while editing a blog comment
via edit-server."
  (org-with-point-at (org-id-find "0312e0bf-6c55-4657-b2aa-5d92817d4d3f" 'marker)
    (org-clock-in)))
(add-hook 'edit-server-start-hook 'ajb/clock-in-blog-commenting-task)

Now to clock-out the task when I close the buffer. I just needed to add two lines to the function I’d already written, but here’s the whole thing for simplicity’s sake, again from my .emacs:

(defun ajb/save-edit-server-buffer ()
  "Save the edit-server buffer as an org-mode entry via org-capture
   when it is saved with C-c C-c.
   Should be called from edit-server-done-hook."
  (when (not (string-match "edit-server" (buffer-name)))
    (goto-char (point-min))
    (insert (buffer-name) "\n")
    (mark-whole-buffer)
    (org-capture nil "e")
    (goto-char (point-min))
    (kill-line 1)
    (if (equal org-clock-current-task "Blog Commenting")
        (org-clock-out))))
(add-hook 'edit-server-done-hook 'ajb/save-edit-server-buffer)

The new part is the if statement near the end. I have it check to make sure the current task is the Blog Commenting task before clocking out of it. That way, if I’ve already closed the task, or if I’ve switched to some other task in the middle of writing a comment, I won’t be clocking-out of some other task without meaning to.

It works just like it did before, except now I have a running total of how much time I spend writing blog comments, which can be included in my daily/weekly/monthly time reports and other stats. I look forward to seeing how much time I spend writing comments, compared to reading blogs and other work-related activities.

If you have questions or need help getting this working, please contact me.