A time tracker in Emacs with a nice interface
Largely modelled after the Android application, A Time Tracker
Benefits
Limitations
IMPORTANT: with version v0.3, chronometrist no longer uses timeclock as a dependency and will use its own s-expression-based backend. A command to migrate the timeclock-file, chronometrist-migrate-timelog-file->sexp-file
, is provided.
Compared to timeclock.el, Chronometrist
Chronometrist and Org time tracking seem to be equivalent in terms of capabilities, approaching the same ends through different means.
Set up MELPA - https://melpa.org/#/getting-started
(Chronometrist uses semantic versioning and only releases are pushed to the master branch, so using MELPA Stable is recommended and has no effect on frequency of updates.)
M-x package-install RET chronometrist RET
You can get chronometrist
from https://github.com/contrapunctus-1/chronometrist
chronometrist
requires
The optional extension chronometrist-key-values
requires choice.el
, apart from chronometrist
itself.
Add the "elisp/" subdirectory to your load-path, and (require 'chronometrist)
.
In the buffers created by the following three commands, you can press l
(chronometrist-open-log
) to view/edit your chronometrist-file
, which by default is ~/.emacs.d/chronometrist.sexp
.
All of these commands will kill their buffer when run again with the buffer visible, so the keys you bind them to behave as a toggle.
Run M-x chronometrist
to see your projects, the time you spent on them today, which one is active, and the total time clocked today.
Hit RET
(chronometrist-toggle-task
) on a project to start tracking time for it. If it's already clocked in, it will be clocked out. This command runs some hooks, which are useful for a wide range of functionality (see Adding more information below). In some cases, you may want to skip running the hooks - use M-RET
(chronometrist-toggle-task-no-hooks
) to do that.
You can also hit <numeric prefix> RET
anywhere in the buffer to toggle the corresponding project, e.g. C-1 RET
will toggle the project with index 1.
Press r
to see a weekly report (see chronometrist-report
)
chronometrist
keeps itself updated via an idle timer - no need to frequently press g
to update.
Run M-x chronometrist-report
(or chronometrist
with a prefix argument of 1, or press r
in the chronometrist
buffer) to see a weekly report.
Press b
to look at past weeks, and f
for future weeks.
chronometrist-report
keeps itself updated via an idle timer - no pressing g
to update.
Run M-x chronometrist-statistics
(or chronometrist
with a prefix argument of 2) to view statistics.
Press b
to look at past time ranges, and f
for future ones.
Part of the reason Chronometrist stores time intervals as property lists is to allow you to add tags and arbitrary key-values to them.
To be prompted for tags, add chronometrist-tags-add
to any hook except chronometrist-before-in-functions
, based on your preference (see Hooks). The prompt suggests past combinations you used for the current task, which you can browse with M-p
/M-n
. You can leave it blank by pressing RET
, or skip the prompt just this once by pressing M-RET
(chronometrist-toggle-task-no-hooks
).
Similarly, to be prompted for key-values, add chronometrist-kv-add
to any hook except chronometrist-before-in-functions
. To exit the prompt, press the key it indicates for quitting - you can then edit the resulting key-values by hand if required. Press C-c C-c
to accept the key-values, or C-c C-k
to cancel.
If you wish to be prompted when you exit Emacs while tracking time, you can use this -
(add-hook 'kill-emacs-query-functions 'chronometrist-query-stop)
If you wish you could define time goals for some tasks, and have Chronometrist notify you when you're approaching the goal, completing it, or exceeding it, check out the extension chronometrist-goal.el.
See the Customize groups chronometrist
and chronometrist-report
for variables intended to be user-customizable.
Chronometrist currently has the following hooks -
chronometrist-mode-hook
chronometrist-before-in-functions
chronometrist-after-in-functions
chronometrist-before-out-functions
chronometrist-after-out-functions
chronometrist-list-format-transformers
chronometrist-entry-transformers
chronometrist-file-change-hook
The hooks whose names end with -functions
are abnormal hooks - each function must accept exactly one argument, which is the name of the project which is being started or stopped, as a string.
chronometrist-before-out-functions
is different from the other three, in that it runs until failure - the task will be clocked out only if all functions in this hook return t
.
An idea from the author's own init -
(defun my-start-project (project)
(pcase project
("Guitar"
(find-file-other-window "~/repertoire.org"))
;; ...
))
(add-hook 'chronometrist-before-in-functions 'my-start-project)
Another one, prompting the user if they have uncommitted changes in a git repository (assuming they use Magit) -
(autoload 'magit-anything-modified-p "magit")
(defun my-commit-prompt ()
"Prompt user if `default-directory' is a dirty Git repository.
Return t if the user answers yes, if the repository is clean, or
if there is no Git repository.
Return nil (and run `magit-status') if the user answers no."
(cond ((not (magit-anything-modified-p)) t)
((yes-or-no-p
(format "You have uncommitted changes in %S. Really clock out? "
default-directory)) t)
(t (magit-status) nil)))
(add-hook 'chronometrist-before-out-functions 'my-commit-prompt)
(defun my-activity-indicator ()
(thread-last (plist-put (chronometrist-last)
:stop (chronometrist-format-time-iso8601))
list
chronometrist-events-to-durations
(-reduce #'+)
truncate
chronometrist-format-time))
(setq chronometrist-activity-indicator #'my-activity-indicator)
make-thread
in v26 or the emacs-async library for chronometrist-entries
/chronometrist-report-entries
chronometrist-report-weekday-number-alist
whatever variables like initial-frame-alist
use to get that fancy Custom UI for alists.Feedback and MRs are very welcome. 🙂
If you have tried using Chronometrist, I'd love to hear your experiences! Get in touch with the author and other Emacs users in the Emacs channel on the Jabber network - xmpp:emacs@salas.suchat.org?join (web chat)
(For help in getting started with Jabber, click here)
I dream of a world where all software is liberated - transparent, trustable, and accessible for anyone to use or improve. But I don't want to make demands or threats (e.g. via legal conditions) to get there.
I'd rather make a request - please do everything you can to help that dream come true. Please Unlicense as much software as you can.
Chronometrist is released under your choice of Unlicense or the WTFPL.
(See files UNLICENSE and WTFPL).
wasamasa, bpalmer, aidalgol, pjb and the rest of #emacs for their tireless help and support
jwiegley for timeclock.el, which we used as a backend in earlier versions
blandest for helping me with the name
fiete and wu-lee for testing and bug reports