Clocking time with Org-mode
Table of Contents
Author | Lee Hinman (leehinman@fastmail.com) |
Date | 2023-03-19 18:07:09 |
Introduction
Org-mode is pretty large, there is a lot of things you can do with it. Check out the previous meetup about it. This assumes you've using Org-mode at least a little bit (headlines and TODOs) before.
I'd like to thank Bernt Hansen, whose org-mode configuration I have heavily borrowed and tweaked to make my own.
Tracking time with Org-mode
So, you want to track time in tasks in Org-mode? First, you need a task, any headline can be clocked
in to. In order to clock in to a task, hit C-c C-x C-i
, and hit C-c C-x C-o
to clock back out.
When you clock in to a headline a drawer appears, a drawer looks like this:
You can expand and collapse the drawer with TAB
. Time tracking goes into the :LOGBOOK:
drawer
(you might have already seen the :PROPERTIES:
drawer) and looks like:
:LOGBOOK: CLOCK: [2017-04-10 Mon 15:18] CLOCK: [2017-04-10 Mon 15:16]--[2017-04-10 Mon 15:17] => 0:01 CLOCK: [2017-04-07 Fri 16:05]--[2017-04-07 Fri 16:35] => 0:30 CLOCK: [2017-04-05 Wed 16:42]--[2017-04-05 Wed 16:52] => 0:10 :END:
(the first one is a currently open clock)
That's it! Keep clocking away and capturing where your time went. You will also see a notification in the modeline with your current task and how long it's been going for.
Important Keys
Here are the most important keys to know when dealing with clocks
Key | Calls | Action |
---|---|---|
C-c C-x C-i |
org-clock-in | Clock in to the section you're currently in |
C-c C-x C-x |
org-clock-in-last | Clock in to the last clocked task |
C-c C-x C-o |
org-clock-out | Clock out of whatever you're clocked in to |
C-c C-x C-j |
org-clock-goto | Jump to whatever headline you are currently clocked in to |
C-c C-x C-q |
org-clock-cancel | Cancel the current clock (removes all of it's current time) |
C-c C-x C-d |
org-clock-display | Display clock times for headlines in current file |
C-c C-x C-r |
org-clock-report | Generate a report for clock activity |
C-c C-x C-z |
org-resolve-clocks | Resolve any half-open clocks |
In the Agenda
If you use the agenda, the task that is currently highlighted will be highlighted also, and you can
clock in and out of tasks with I
and O
respectively.
Reporting time with a clock report
For a quick overview C-c C-x C-d
provides a quick summary of clocked time for the current org
file.
C-c C-x C-r
starts generating a new clock report/table, or you can manually add this line to a
file and hit C-c C-c
on it:
#+BEGIN: clocktable #+END:
And then you can put options on the BEGIN
line:
#+BEGIN: clocktable :maxlevel 4 :scope agenda :block thismonth #+END:
Here's a large example (I left a lot out for sensitivity):
File | Headline | Time | |||
---|---|---|---|---|---|
ALL Total time | 3d 12:48 | ||||
refile.org | File time | 0:00 | |||
todo.org | File time | 3d 12:48 | |||
Support | 0:01 | ||||
CANCELLED OOME not caught by circuit… | 0:01 | ||||
Meta | 10:50 | ||||
NEXT [#C] Answer questions on… | 0:51 | ||||
NEXT [#B] Review PRs | 0:27 | ||||
NEXT Test triage | 4:20 | ||||
Open Source Software | 2:42 | ||||
TODO clj-http | 0:08 | ||||
DONE Remove reflection warnings | 0:07 | ||||
NEXT Invalid 'expires' attribute for… | 0:01 | ||||
TODO cheshire | 0:02 | ||||
TODO es-mode | 2:30 | ||||
TODO Fix unicode issue for es-mode | 2:30 | ||||
DONE Fix unicode for .es files | 0:29 | ||||
TODO No margin or footnote in side… | 0:01 | ||||
TODO Investigate the now YaCY 2 | 0:01 | ||||
Tech | 14:51 | ||||
TODO Emacs | 3:11 | ||||
NEXT EOS Configuration | 0:42 | ||||
DONE Update org-skeletons to not… | 0:01 | ||||
TODO Investigate org-protocol | 0:13 | ||||
DONE Write presentation about… | 2:10 | ||||
DONE Review Mike's Ivy presentation | 0:05 | ||||
TODO Git-annex | 3:22 | ||||
DONE Set up git-annex-gcrypt for… | 2:07 | ||||
TODO Set up home NAS | 0:46 | ||||
NEXT Determine parts for FreeNAS machine | 0:28 | ||||
TODO Design studio meeting | 0:01 | ||||
NEXT Rebuild ivalice as proxmox host | 6:20 | ||||
DONE Build Jenkins proxmox container | 5:17 | ||||
DONE Build pi-hole proxmox container | 0:18 | ||||
DONE Investigate proxmox | 0:26 | ||||
DONE Add insurance docs to lockbox | 0:01 | ||||
NEXT Learn PureScript | 1:11 |
You can change the default clocktable options with:
;; Agenda clock report parameters (setq org-agenda-clockreport-parameter-plist '(:link t :maxlevel 6 :fileskip0 t :compact t :narrow 60 :score 0))
My agenda org clock report settings show 6 levels of detail with links to the tasks. I like wider
reports than the default compact setting so I override the :narrow
value.
Want to see a clock table in the Agenda? Simply press v R
to show it, then hit v R
again to turn
it off.
Options for a clock report
Option | Description |
---|---|
:maxlevel | Maximum level depth to which times are listed in the table |
:scope | What scope to consider for the report |
:block | The time block to consider |
:tstart | Like block, but when to start considering clocks |
:tend | When time considering should end |
:wstart | The starting day of the week, 1 means Monday |
:mstart | The starting day of the month, 1 means the first day of the month |
:tags | Only include clocks matching these tasks |
A few of these need special explanation
:scope
The scope is what should be considered for a report, if you don't specify it, you mean the current
buffer or narrowed region (nil
).
file
and subtree
are exactly what they sound like. If you want to manually specify which files,
you can use ("file1.org" "file2.org" "..etc")
.
If you archive tasks, you may also want file-with-archives
, which includes any tasks that have
already been archived into a different org-mode file.
Finally, if you use the agenda, you can get clock reports for all agenda files with agenda
or
agenda-with-archives
.
:block
The :block
specifies the time block to consider, it also supports "human"-like dates. These are
taken straight from the org-mode clock-table documentation.
Text | Description |
---|---|
2007-12-31 | New year eve 2007 |
2007-12 | December 2007 |
2007-W50 | ISO-week 50 in 2007 |
2007-Q2 | 2nd quarter in 2007 |
2007 | The year 2007 |
today | Everything from today |
yesterday | Everything from yesterday |
today-N (today-3) | Everything from today back 3 days |
thisweek | This week |
lastweek | Last week |
thisweek-N (lastweek-2) | Last two weeks |
this year | This year |
last year | Last year |
thisyear-N (lastyear-2) | Last two years |
untilnow | Everything until now |
You can use the S-<left>/<right>
keys on the :block
line to shift the time interval.
Adjusting clock times
Sometimes you need to manually make changes to a clock, because it's wrong, or you forgot to clock in, or your cat jumped on to your keyboard and clocked in to an embarrassing task.
Dealing with idle time
What happens when you walk away from your desk? Or leave yourself clocked in overnight on accident? In that case, Emacs can detect that you have been idle for some amount of time, and prompt you about what to do when you come back to your computer:
;; If idle for more than 15 minutes, resolve the things by asking what to do ;; with the clock time (setq org-clock-idle-time 15)
You'll get a prompt when you come back, and you get hit:
Key | Action |
---|---|
k | keep some or all minutes and stay clocked in |
K | keep some or all minutes and clock out |
s | keep 0 minutes, and subtract some amount from the clock, clocking back in |
S | keep 0 minutes, subtract some amount from the clock, and clock out |
C | cancel the clock altogether |
Adjusting the clock after the fact
Sometimes though, you make mistakes and need to adjust things. By placing your cursor on a
particular number you can shift up and down by 5 minute increments with Shift-UP
and Shift-DOWN
.
For example, with the cursor where the |
is, hitting S-Down
would change this to 15:15 (round
down to nearest 5 increment).
CLOCK: [2017-04-10 Mon 15:18|]--[2017-04-10 Mon 15:28] => 0:10
You can change the increments by setting org-time-stamp-rounding-minutes
:
(setq org-time-stamp-rounding-minutes (quote (0 5)))
Want to see where in your day you have a clocking gap?
Hit v c
in the daily agenda and clock gaps and overlaps are identified.
You can set how strict these gaps should be by setting:
(setq org-agenda-clock-consistency-checks '(:max-duration "4:00" :min-duration 0 :max-gap 0 :gap-ok-around ("4:00")))
Estimating task time
Okay, you can clock in to tasks and generate reports, but what about estimating the amount of time a task will take, and seeing how well you line up in actual time?
Well, you can hit C-c C-x e
to be prompted to set the "effort" for a particular headline, which
will go into the :PROPERTIES:
drawer. Something like "30" for 30 minutes, or "1:30" for an hour
and a half. Now when you clock in to a task, instead of seeing [1:04] Do some stuff
you'll see
[1:04/2:00] Do some stuff
where the effort is displayed next to the clock time.
A speedier way of doing this though, is to have some "presets" that you can easily hotkey for
effort, you can add these to org-global-properties
:
;; global Effort estimate values (setq org-global-properties '(("Effort_ALL" . "0:15 0:30 0:45 1:00 2:00 3:00 4:00 5:00 6:00 0:00"))) ;; 1 2 3 4 5 6 7 8 9 0 ;; These are the hotkeys ^^
Then, you can hit C-c C-x e
on a headline and be prompted for the "quick" efforts. So C-c C-x e
3
would select 45 minutes.
Cool, so you estimated (poorly, remember, we are in software, no good estimates allowed!) the time for all your tasks now to compare. For comparing, we're going to use Org-modes column view mode.
We need to define some columns to see, I like to define mine as the task, then the priority, the effort, and finally the sum of time taken for the task:
;; Set default column view headings: Task Priority Effort Clock_Summary (setq org-columns-default-format "%50ITEM(Task) %2PRIORITY %10Effort(Effort){:} %10CLOCKSUM")
You can now turn on org-columns
with C-c C-x C-c
, you should see something like the following
screenshots.1
Before:
After:
You can move to the "Effort" column and hit 0-9 to fast-choose the amount of effort for a task also, instead of adding effort to each individual headline one at a time.
You can exit org-columns
view by hitting q
Or, generate a local column view with C-c C-x i
(select "local" to see the local column table).
Task | PRIORITY | Effort | CLOCKSUM |
---|---|---|---|
Estimating task time | B | 1:00 | 0:04 |
Helpful functions and bindings
I like to have a helpful history of tasks to pick from when I clock in to things. Which is what this
does. I bind it to C-c I
and C-c O
so they can be invoked globally (not just in org-mode files).
;; Show lot of clocking history so it's easy to pick items off the `C-c I` list (setq org-clock-history-length 23) (defun eos/org-clock-in () (interactive) (org-clock-in '(4))) (global-set-key (kbd "C-c I") #'eos/org-clock-in) (global-set-key (kbd "C-c O") #'org-clock-out)
Customizing your setup
Sometimes you may want to resume the clock that was running when Emacs was stopped, you can make org do that with these settings:
;; Resume clocking task when emacs is restarted (org-clock-persistence-insinuate) ;; Save the running clock and all clock history when exiting Emacs, load it on startup (setq org-clock-persist t) ;; Resume clocking task on clock-in if the clock is open (setq org-clock-in-resume t) ;; Do not prompt to resume an active clock, just resume it (setq org-clock-persist-query-resume nil)
And here are a few other settings you might want to check out:
;; Change tasks to whatever when clocking in (setq org-clock-in-switch-to-state "NEXT") ;; Save clock data and state changes and notes in the LOGBOOK drawer (setq org-clock-into-drawer t) ;; Sometimes I change tasks I'm clocking quickly - this removes clocked tasks ;; with 0:00 duration (setq org-clock-out-remove-zero-time-clocks t) ;; Clock out when moving task to a done state (setq org-clock-out-when-done t) ;; Enable auto clock resolution for finding open clocks (setq org-clock-auto-clock-resolution (quote when-no-clock-is-running)) ;; Include current clocking task in clock reports (setq org-clock-report-include-clocking-task t) ;; use pretty things for the clocktable (setq org-pretty-entities t)
Footnotes:
You can also do this inside of the org agenda and it's pretty awesome