This is my concluding post in a series of three posts.
- The first blog post contains my general thoughts on time tracking.
- The second blog post compares different time tracking software.
- When writing this last blog post I’ve been using Timewarrior together with ActivityWatch, Waybar and some home-brewed scripts to track my time as good as I could for a couple of months.
Executive summary
In this blog post I’ll give a short introduction to ActivityWatch (AW) and Timewarrior (TW, sometimes timew
), their differences and short-comings.
I have a working setup now that is tracking how I spend my time at the computer and making a timeline, allowing manual amendments and adjustments, and finally making it possible to make detailed reports on what tasks I’ve been working on. It’s based on AW, TW and quite some home-brewed scripts.
While the current setup is a major step forward from scratching my head while filling out time sheets at the end of the month, it’s far from perfect. I’d recommend to have a look at my work if you really fancy the idea of semi-automatic time tracking, or if you’re already using either ActivityWatch or Timewarrior but would like to improve on your time tracking. Otherwise, sadly my system is a jigsaw puzzle of different software, scripts and configurations - while I’ve tried setting up instructions at the bottom of this post, reproducing my setup is not going to be easy. I still hope this blog post may give some inspiration for anyone pursuing a better time tracking setup.
Comparing ActivityWatch with Timewarrior - and plann
Proactive, concurrent and retroactive time tracking
In the first blog post, I mentioned that the best approach probably is to do a combination of proactive planning ahead, concurrent note-writing or recording and retroactively figure out how time was spent.
As for the proactive planning, I have my plann calendaring tool which also handles tasks - I’ve added some ad-hoc integration towards TW into the latest master branch and I have more in the pipeline.
TW allows me to take concurrent notes, AW does concurrent recording. Both of them allows editing the story line after-the-fact, but none of them are optimized for retroactive time tracking. One note, editing a timeline involves specifying when I was working on things. At the end of the day the most important is to track how many hours did I spend on this task. As an example - quite often my day ends up with lots of slots marked up as “afk”. Say, I have five hours marked up as “afk” spread over multiple events. I estimate that I spent 2.5 hours varnishing, 0.5 hours on housework and 2 hours buying milk (running out of milk on a boat may be difficult sometimes). I’d like to squeeze in this information without having to manually edit the timeline, which involves figuring out when I did what, possibly splitting up events, and tagging multiple events.
At some point in the far future, maybe I’ll make time tracking an integral part of plann
and skip the TW dependency. After all, TW is not really rocket science - it’s merely logging timestamps and tags, and having a little bit extra functionality around it.
Automatic vs manual tracking
AW and TW are two quite different things. AW attempts to track all activity on the computer automatically and deduct from that what you’re spending time on, while TW is a CLI for manually populating a time tracking database. At least for me, neither is the “silver bullet” I need for tracking my working hours.
Automatic time tracking cannot be reliable for me. I suppose soon enough we’ll all chat real-time with an AI-companion who will keep track of everything automatically - but as for now I don’t feel comfortable with involving AI in my timetracking. Sometimes it’s really needed to manually make notes that “now I’m working on project A”, “now I’ve left the computer to work on project B” or “for a meeting with the customer”. AW does have a manual “stopwatch watcher” and it does have the possibility to edit data through the WebUI, but at least as of v0.13.2 it does not seem convenient to manually feed AW with activity data and get a nice report out. AW also a CalDAV watcher and a cellphone watcher, I haven’t tested it (the cellphone watcher didn’t want to work), but I believe neither would solve my problems fully.
Manual time tracking is difficult for me. Sometimes I’m just doing too much context switching. It’s often not enough time to type timew start ...
upon sudden Interrupts. Very often I just forget to use the start-command. I frequently end up having to check up various sources to backtrack my day and consider what I really spent my day on - for computer work, most of this information is now in the AW - and for quite much of this again, it may be automatically extracted.
I ended up with a hybrid approach; semi-automatic timetracking. I’m fairly happy with that.
Local vs Centralized vs Distributed - and standards
AW and TW is primarily designed to work locally from one device and I’ve been working from one laptop while testing those solutions. Sometimes I’m switching between two or more devices, including a telephone. Both AW and TW can easily be done centralized - having multiple devices feed one central database on one server device - but what if one is frequently offline? Although the AW watchers should be able to queue up events, a real distributed setup is not possible out of the box from any of them. It may be possible to write up some scripts for merging data from different sources, but I will not go deeper into that now.
Both AW and TW are sort of silos, with their own storage formats and export formats. Yes, both of them have some kind of APIs, but they don’t follow any standards. My long-term plan is to have plann put time tracking information on the calendar. While far from perfect, the calendaring standards does offer some kind of distributed storage. The calendaring standards aren’t optimized for tracking time, but there are workarounds - like having a dedicated calendar for time tracking, where tasks/events and their timestamps represent actual time spent.
Ease of use
TW comes as a command line interface, it is fairly easy to get started with - and fairly easy to continue using. Initially I was confused because TW does not follow the GNU conventions on options, but it seems like the interface is optimized for speed and ease. Order of arguments does not matter, one may mix time specifications, event IDs and tags, and TW will try to figure out what is what. Most of the time it’s verbose, particularly if it encounters a new tag (including if some time specification etc was mistaken for a tag), and it’s very easy to roll back by doing timew undo
. (I’d like timew undo
to be verbose about what it’s doing, and I’d like to have a timew redo
as well, but you can’t have them all).
While AW does have a CLI and an API, it’s designed to be operated through the WebUI. This lowers the threshold of getting started with it - but at the end of the day (at least for me) repeatedly doing the same or similar operations through a CLI will always be faster and easier (often a lot faster and easier) than to do the same by clicking through some WebUI.
Categorization and reporting in ActivityWatch
AW does have a “category builder” included in the box, it’s pre-populated with some hierarchical categories (like Work/Programming/ActivityWatch
), and it allows some reports to be taken out from the WebUI. I was quite excited to test out the “category builder” in AW after collecting data for two days, but it did not meet my expectations. Setting up all the watchers - and all that can be done by the “category builder” was to apply some regexp to the window title of the current active window (the report builder is also useless unless the “afk watcher” works - and the one included in the box did not work on Wayland, only on X11). I tried writing my own reporting script, but found it too difficult.
Categorization and reporting in Timewarrior
TW does not have categories, it has tags. At the end of the day I need to know how many hours I’ve spent on work, and those hours should again be split by project. For this purpose hierarchical “categories” seems to fit better than tags. Still, I do like the approach with tags. Everything is allowed. Hierarchical categories? Easy, can be made as tags with slashes (but it seems smarter to use multiple tags). Key-value storage? Easy, just add a colon between key and value and throw it into the tag system. The problem with “everything is allowed” is that it’s easily becoming a mess. It could be worse - it would become really messy if using it across a team or an organization. at least you don’t need to argue with anyone other than yourself on how to use the tagging system, nor remind anyone about the tagging rules.
Perfect usage of the tagging system involves putting a lot of thoughts into how to use the tags even before starting to use TW, and then very consistently follow the plan. That’s just not going to happen - your usage of tags will evolve over time. I find the possibilities for editing tags (not just remove or add one or more tags to one event, but like changing one tag into another across all the events in the database) to be rather lacking. It’s possible to do this directly in the raw data files, but one is not supposed to do it that way.
The tags is not a list, but a set - and the tags always come out in alphabetical order. In most collations numbers are sorted before letters, and with my collation all capital letters are sorted before any lower case letter. I started playing with prepending the number 4 to some upper case “main categories”, and (particularly for work projects) 4 prepended by lower letters for the customer project. Four is pronounced like “for”, so I’m doing for 4 my employer (and 4 customer acme), 4 myself, 4 the boat, etc. Admittedly, it looks silly - but there is some logic to it. And after that, arbitrary amount of tags to clarify what I’ve actually been working on. Tags may have space in them, I may add a full sentence describing what I’ve done to remind myself what I was working on.
Out of the box, TW has only one reporting command - timew summary
. Unfortunately, the word summary
is very misleading. It does not really give me a summary, it gives me a full plan of exactly when I did what. For me, with frequent context switching, this list can be rather long - on a typical day I have like 100 entries. Well, at least it does have a sum of hours at the bottom, and it is possible to filter. timew summary 4RL :yesterday | tail -n 2
will give me how many hours I spent doing work for my employer (Redpill Linpro = RL) yesterday. The filtering is very basic - it’s possible to filter by time interval and by tags, it will show only the lines with all tags present - so it supports only logical AND. I’m particularly missing logical NOT. It would be nice with magic happening if prepending a tag with -
or !
or ~
… but, no.
Here is an example on how the summary may look (slightly edited and shortened, using categories preceded with 4
as mentioned above):
$ timew summary 2025-06-15 :ids
Wk Date Day ID Tags Start End Time Total
W24 2025-06-15 Sun @3852 4BREAK, afk, bedtime 0:00:00 6:13:57 6:13:57
@3851 4BREAK, 4entertainment, entertainment, not-afk, nrk 6:13:57 6:20:00 0:06:03
@3850 4ME, kaufland, shopping 6:20:00 7:34:00 1:14:00
@3849 4BREAK, 4food, afk, tea 7:34:00 7:38:00 0:04:00
@3848 4BREAK, 4entertainment, entertainment, not-afk, nrk 7:38:00 7:38:13 0:00:13
(...)
@3792 4OSS, 4oss-contrib, caldav, caldav-issue-474, calendaring, not-afk, oss-contrib, python-caldav 22:33:53 22:41:09 0:07:16
@3791 4OSS, 4oss-contrib, caldav, caldav-issue-485, calendaring, not-afk, oss-contrib, python-caldav 22:41:09 22:56:00 0:14:51
@3790 4OSS, 4oss-contrib, caldav, caldav-issue-507, calendaring, not-afk, oss-contrib, python-caldav 22:56:00 23:02:49 0:06:49
@3789 4OSS, 4oss-contrib, caldav, caldav-issue-, calendaring, not-afk, oss-contrib, python-caldav 23:02:49 23:08:14 0:05:25
@3788 4OSS, 4oss-contrib, caldav, caldav-issue-485, calendaring, not-afk, oss-contrib, python-caldav 23:08:14 23:09:47 0:01:33
@3787 4BREAK, 4entertainment, entertainment, not-afk, nrk 23:09:47 23:21:01 0:11:14
@3786 4BREAK, afk, bedtime 23:21:01 23:30:23 0:09:22
@3785 4OSS, 4oss-contrib, caldav, calendaring, oss-contrib, python-caldav 23:30:23 0:00:00 0:29:37 24:00:00
24:00:00
As said, one can use tags and the last line will actually be a summary:
$ timew summary 2025-06-15 4BOAT
Wk Date Day Tags Start End Time Total
W24 2025-06-15 Sun 4BOAT, afk, boat-maintenance, varnishing 8:27:28 9:44:14 1:16:46
4BOAT, afk, boat-maintenance, varnishing 11:04:41 13:01:11 1:56:30
4BOAT, afk, boat-maintenance, epoxy 14:27:00 14:53:07 0:26:07
(...)
4BOAT, afk, boat-maintenance, varnishing 16:50:17 18:58:54 2:08:37 6:44:33
6:44:33
There is an totals.py
-extension that may be found in the git repository of TW and copied manually over to the ~/.config/timewarrior/extensions/
-directory. It still doesn’t do quite what I want it to do as it sums up totals for every tag. It’s marginally useful, since the tags comes out in alphabetical order my “main categories” comes out first, and I can drill down by doing a timew report totals.py 4RL
to limit it to work for my employer. I can even grep for all categories starting with 4
. It looks like this (quite some lines removed):
$ timew report totals 2025-06-15
Total by Tag, for 2025-06-15 00:00:00 - 2025-06-16 00:00:00
Tag Total
4BOAT 6:44:33
4BREAK 8:52:38
4CHORES 0:49:27
4ME 1:53:14
4OSS 4:36:41
4RL 0:59:49
4entertainment 1:49:23
4food 0:39:56
(...)
tea 0:17:38
theguardian 0:07:39
varnishing 5:22:54
Total 103:03:14
Observe that the total sum is not that useful (it was a quite efficient day, but not that efficient).
Testing and stitching things together
While working on my second blog post, I was using TW for a full day, and at the end of the day I concluded that it does not suit my needs. And yet … after looking through all the other solutions, and after a full day of not using any time tracking software, I decided to head back and utilize TW again, it is indeed better than nothing, and possibly better than all the other similar programs. I do like the concept to use the “start” command every time I’m changing focus, and I do like the idea of having any number of tags attached to the time tracking entry.
I did set up AW, I had it running for some days, I set up relevant extra “watchers” to collect more data, and then I tried to get useful information out of it. I discovered it was not really possible out of the box, so I continued using TW, consulting the AW web interface every now and then to correct my TW entries. So the natural thing to do was to keep using TW as my source of truth, but write some scripts to check up AW, and export things from AW to TW.
ActivityWatch to Timewarrior Exporter
The ActivityWatch exporter is available at GitHub
I set up some rules in a .toml
-file (not because I like toml, but because this seems to be the standard for AW), it takes out events from the AW database (using the proper API for it) working on window titles, editor events, browser events … so if using an editor and editing a file in the acme
-folder it will automatically consider that 4RL
and 4acme
are appropriate tags. Things gets a bit complex (and often incorrect) upon context switching (I may frequently switch between a browser, editor and command line while working at some customer project), but I’ve tried my best to get a relatively accurate tracking based on my work flow.
Quite a lot of work has been put down in the toml-file - it’s personal and will never be published, but I did add a default sample configuration in the project.
Script logs a lot to stdout, including everything it’s doing. Every now and then I use timew undo
and manually adjusting things using the timew
-CLI. Other times I consult the log to adjust the timeline (because the exporter script hasn’t recognized the task I’m working on and still believes I’m working on the previous task).
There are certainly room for improvements.
Here is a sample output (slightly edited):
20:44:52 / 20:35:11 - 10.942s duration, {'app': 'Chromium', 'title': 'Channel X - RL RL Mattermost - Chromium'} - tags found: {'4admin', 'not-afk', 'mattermost', 'communication', '4RL'} (0 smaller events skipped, total duration 0.0s)
20:44:52 / 20:35:10 - 461.531s duration, {'status': 'not-afk'} - tags found: {'not-afk'} (0 smaller events skipped, total duration 0.0s)
(...)
20:44:53 / 20:36:22 - 32.649s duration, {'app': 'Emacs', 'title': 'time-tracking3-timew-aw-plann.md - GNU Emacs at archlinux'} - tags found: {'techblog', '4admin', 'time-tracking3-timew-aw-plann', 'not-afk', '4RL'} (6 smaller events skipped, total duration 4.424s)
Running:
timew start techblog 4admin not-afk time-tracking3-timew-aw-plann 4RL 2025-08-19T20:35:11
Tracking 4RL 4admin "not-afk" techblog "time-tracking3-timew-aw-plann"
Started 2025-08-19T20:35:11
Current 44:53
Total 0:09:42
Use timew undo if you don't agree! You have 10.0 seconds to press ctrl^c
Timewarrior tools
As said, there are quite some things that I found missing in TW. I’ve scripted myself around some of the things I’m missing.
Advanced tag editing
As one start using TW, the ideas on how to use the tags in the best possible ways evolves. I did make a stand-alone script for changing a tag into another tag for all entries in the database - useful i.e. to correct typos, to make old entries consistent with newer entries, etc.
The elegance with TW is that it’s reasonably quick to write timew start varnishing
(I’m trying to track how much time I spend varnishing my boat. Answer: far too much! Never buy a wooden boat!). However, utilizing tags in a consistent and good way, I should be doing timew start 4BOAT afk varnishing "stern, 3rd layer"
. That does take some time to write. So I’ve written a script that adds extra tags, it will add 4BOAT
, afk
when it encounters varnishing
. This code has ended up in the aw-export-timewarrior
-project (although this logic has nothing to do with AW).
Reporting
I also mentioned that I found the reports lacking. Soon enough I copied totals.py
into myday.py
and started hacking on it. It takes options through environmental variables.
First of all, I wanted to sum up time usage for every unique tag combination. totals.py
does not do this, it sums things over every unique tag. By adding an environment CONCAT=1
to myday.py
it will give one line per combination of tags rather than one line of tags. So it will give one line for 4RL 4acme
and one line for 4BOAT varnishing afk "3rd layer stern
”`.
Example (This was before I considered to add “3rd layer stern”):
$ env CONCAT=1 timew report myday.py 2025-06-15
Total by Tag, for 2025-06-15 00:00:00 - 2025-06-16 00:00:00
Tag Total
4BOAT,afk,boat-maintenance,epoxy 1:21:39
4BOAT,afk,boat-maintenance,varnishing 5:22:54
4BREAK,4entertainment,baatplassen,entertainment,not-afk 0:30:59
(...)
Total 24:00:00
Note that the total now is correct - 24 hours of tracked time over a full day.
The amounts of lines from the CONCAT
-report (I should probably find a better name for it) may be quite big if lots of “noisy” tags are used - so I added an IGNORETAGS
option (again, should probably think out a better name for it). Example (slightly edited, and quite some removed):
$ env CONCAT=1 IGNORETAGS="varnishing epoxy not-afk dinner tea nrk baatplassen theguardian" timew report myday.py 2025-06-15
Total by Tag, for 2025-06-15 00:00:00 - 2025-06-16 00:00:00
Tag Total
4BOAT,afk,boat-maintenance 6:44:33
4BREAK,4entertainment,entertainment 1:49:23
4BREAK,4food,afk 0:39:56
4BREAK,afk,bedtime 6:23:19
4CHORES,admin 0:03:58
4CHORES,admin,plann 0:03:59
4CHORES,afk,dishwash 0:41:30
(...)
4OSS,4oss-contrib,caldav,caldav-issue-209,calendaring,oss-contrib,python-caldav 0:49:54
4OSS,4oss-contrib,caldav,caldav-issue-474,calendaring,oss-contrib,python-caldav 0:15:18
4OSS,4oss-contrib,caldav,caldav-issue-485,calendaring,oss-contrib,python-caldav 0:16:24
(...)
Total 24:00:00
As can be seen above, regexp/glob-expression is really missing in the IGNORETAGS-feature, would be nice to ignore caldav-issue-*
.
I mentioned the lack of logical NOT when filtering. Yes, I covered that too. KILLTAGS
is the environmental variable. If the report has lots of lines on what I’ve done for customer acme and I’ve already processed them and thrown it into the accounting system, then I can do KILLTAGS=4acme timew report myday.py :yesterday 4RL
. Example:
$ env CONCAT=1 KILLTAGS="4entertainment" timew report myday.py 2025-06-15 4BREAK
Total by Tag, for 2025-06-15 00:00:00 - 2025-06-16 00:00:00
Tag Total
4BREAK,4food,afk,dinner 0:22:18
4BREAK,4food,afk,tea 0:17:38
4BREAK,afk,bedtime 6:23:19
Total 7:03:15
The usage of environmental variables to send options to the report makes the commands quite ugly. It may be solved by using a wrapper script. I haven’t gone that route, but realizing that I would run the same reporting commands every day, I did a ~/bin/myday.py
(I really should figure out some better names) that takes out the reports I usually ask about. (This is personal and will never be published). Example (edited):
$ myday.py 2025-06-15
## Missing categories report
Total by Tag, for 2025-06-15 00:00:00 - 2025-06-16 00:00:00
Tag Total
RETAGME-0 0:01:28
afk 0:02:10
Total 0:03:38
## Main categories
Total by Tag, for 2025-06-15 00:00:00 - 2025-06-16 00:00:00
Tag Total
4BOAT 6:44:33
4BREAK 8:52:38
4CHORES 0:49:27
4ME 1:53:14
4OSS 4:36:41
4RL 0:59:49
Total 23:56:22
## Secondary categories
Total by Tag, for 2025-06-15 00:00:00 - 2025-06-16 00:00:00
Tag Total
4admin 0:58:44
4entertainment 1:49:23
4food 0:39:56
4oss-contrib 4:37:46
Total 8:05:49
RL sans admin report
Total by Tag, for 2025-06-15 00:00:00 - 2025-06-16 00:00:00
Tag Total
4RL,4oss-contrib,activitywatch,oss-contrib 0:01:05
Total 0:01:05
Waybar integration
While doing research on time tracking, I decided to adopt Waybar, and have the current tracked item on top of the Waybar - making it possible to spot if it’s way off, or possibly having it as a reminder on what one should be doing. I’m considering to make it red or blinking if I’m wasting time on some of the silly websites I shouldn’t be wasting time on.
I found a link to some existing Waybar integration project, without any documentation at all - I spent more time doing research on that one, than what I’ve spent on creating and debugging my own integration. A click will mark up that I’ve started at “something else”, but one will need to retag the entry through the CLI. I never used this feature though, as AW and the exporter script is watching things for me anyway.
While being at it, I also decided to throw calendar upcoming events up in the Waybar - which starts blinking just a minute before the event. Left-click to merely snooze the alarm, and I’m going to fix it so that a right-click will mark in TW that I’ve started attending the event.
Conclusion
Time tracking is for sure not trivial, I’ve spent lots of time on this without finding any “silver bullet”. The perfect tool for doing easy time tracking probably hasn’t been made yet. I’ve looked into different tools, experimented with two of them, and written a collection of small scripts and configuration to combine the strengths from both, get around some of the weaknesses and fix some time tracking that is more or less working for me.
Time tracking does take sobme effort and may steal the focus from the task one is supposed to be working at. A good system shouldn’t be in the way and should not require a lot of context-switching. I think I have found a relatively balanced approach here with semi-automatic tracking and simple CLI-commands to get things right.
At the end of the day, the most important thing is to get the work hours into the accounting system. Unfortunately said system does not have a working API, so it’s manual work. I’m probably not saving significant with time utilizing my current approach compared to my old, but at least I believe the time tracking is a bit more reliable, and I rarely end up in a situation where I have to try to recollect what I did Thursday last week.
The new system usually points out that I haven’t been by the laptop i.e. for a coffee or toilet break, and that I’ve spent time reading news, etc. Earlier such small breaks would easily be accounted into the task I was working at. I could take this as an encouragement to waste less time. At the other hand, ref XKCD 303, sometimes I’m not really wasting time, I’m just waiting for a GitLab pipeline, or the short walk for coffee is necessarily for thinking through some design decisions, etc.
Of course, I’m publishing what I can as open source, and I’d be thrilled if anyone would give my aw-export-timewarrior script a spin. My intention was to publish an enthusiastic blog post encouraging people to test it out. After using this setup for some months already, I’m a bit less enthusiastic. Everything together is a jigsaw puzzle of different scripts and configuration, and I’d be lying in your face if I would tell you it works perfectly. Reproducing all my work here may require lots of efforts. Some day perhaps I’ll deprecate all this and write up the perfect tool. It won’t happen this year. Probably the AI will happily do the timetracking for you before I’m done.
Steps to reproduce my setup
As said, my current setup may be compared with a jigsaw puzzle. Feel free to reach out if you’re trying to play with this - either you have questions, suggestions or contributions. GitHub issues are fine, GitHub Pull Requests even better, but I’m also available by email tobias@redpill-linpro.com.
Software and scripts
- Timewarrior and ActivityWatch should be installed
- Editor watchers and web browser watchers for ActivityWatch must be installed
- If you’re using Wayland, then aw-watcher-window-wayland should be used rather than the default afk and default window watchers.
- My aw-export-timewarrior should be installed and run. As for now I recommend to run it interactively in a window, where it’s possible to press “CTRL-C” and restart it when you need to manually adjust the Timewarrior timeline. It also includes the stand-alone script
retag.py
which will go through old data in timewarrior and ensure the tagging rules, like for me it will ensure anything tagged withvarnishing
also gets the4BOAT
andafk
tags. - Auxiliary tools have been published at GitHub
- There is the
timew-change-tag
-script in case you want to change all instances of a tag to something else. - I’m using Waybar. The
timew-short
-script will create a short textual entry for the status bar. You’ll find relevant sections of my Waybar configuration below. timew-start-afk
will dotimew start afk
unless the afk tag is already present. This logic is run automatically upon suspend (I should fix that it’s run on shutdown as well).myday.py
is a reporting script that should be copied into~/.config/timewarrior/extensions/
- I also made a
~/bin/myday.py
taking out the reports I’d like to see when doing reconciliation. This one is quite private, but I’m considering to change parts of it and publish it as an example.
- There is the
- My plan is to use plann more actively for planning my day in advance, and there are some work in the master branch for exporting stuff to timewarrior. For “upcoming calendar”-notifications in Waybar (and in the future, possibility to right-click on the event to indicate that you’ve started with it) you will need to install
plann
.
Configuration
ActivityWatch, with the relevant watchers must be started. While it’s possible to configure it through toml-files and also through the WebUI, there is no need to configure anything. Timewarrior must be installed, it also has some few configuration options, but it’s not needed to touch them.
The aw-export-timewarrior
script will generate a default configuration file under $HOME/.config/activirtywatch/aw-export-timewarrior/aw-export-timewarrior.toml
first time it’s run. This one needs to be edited extensively to get something useful out of the exporting script. My own configuration file is now 285 lines long, but it’s becoming relatively stable. I’m considering to edit it a bit and release it as an example. Here are some of the rules (lightly edited):
[tags.housework]
source_tags = [ "housework", "dishwash", "cooking", "laundry" ]
add = [ "4CHORES", "afk" ]
[tags.afkfood]
source_tags = [ "tea", "breakfast", "dinner", "lunch" ]
add = [ "4food", "afk" ]
[tags.customer]
source_tags = [ "4acme", ... ]
add = [ "4RL" ]
[rules.app.comms]
app_names = ["Signal", "DeltaChat"]
timew_tags = [ "personal_communication", "$app" ]
[rules.app.term_customer]
app_names = ['foot', 'xterm', 'terminology']
title_regexp = "(acme|...)"
timew_tags = [ "4$1" ]
[rules.browser.entertainment]
url_regexp = "^https://(?:www\\.)?(theguardian|(...))\\.(?:no|com|org)/"
timew_tags = [ "4entertainment", "$1" ]
[rules.browser.caldav1]
url_regexp = "https://github.com/python-caldav/caldav(?:/(?:issues|pull)/([0-9]*))"
timew_tags = [ "python-caldav", "caldav", "4OSS", "oss-contrib", "caldav-issue-$1", "calendaring" ]
[rules.editor.caldav]
path_regexp = "/caldav"
timew_tags = [ "python-caldav", "4OSS", "oss-contrib", "calendaring" ]
[exclusive.keyboard]
tags = [ "afk", "not-afk" ]
[exclusive.main_category]
tags = [ "4CHORES", "4BREAK", "4BOAT", "4ME", "4RL", "4OSS" ]
[exclusive.secondary]
tags = [ "4acme", "4food", ... ]
For the Waybar integrations, I have this in my ~/.config/waybar/config.jsonc
-file (calendar-upcoming.sh is included in the plann project, examples folder):
"custom/timew": {
"exec": "~/bin/timew-short.sh",
"interval": 5,
"on-click": "~/bin/timew-short.sh start",
"on-click-right": "timew stop",
"tooltip": true
},
"custom/agenda": {
"exec": "~/bin/calendar-upcoming.sh waybar",
"on-click": "~/bin/calendar-upcoming.sh click",
"return-type": "json",
"interval": 1,
"tooltip": true
},
I did not find a way to intercept suspend-events without root access, I threw in this - quite ugly as it includes my username, I should redo it into a systemd template service:
# /etc/systemd/system/tobias-afk.service
## apparently it's not possible to make this as a user systemd service. User units can't depend on system units
[Unit]
Description=User suspend actions
Before=sleep.target
[Service]
User=tobias
Type=simple
ExecStart=/home/tobias/bin/timew-start-afk
[Install]
WantedBy=sleep.target
I also tried to make a tobias-not-afk.service
, but failed on it. It doesn’t matter, either the aw-export-timewarrior
-tool will catch up, or one should run timew start mytask
manually as soon as one sits down by the computer. I also try to remember to first of all do a timew tag
or timew retag
to record what I’ve been up to since I left the computer.
… and that’s all for now.