A TUI Habit Tracker

e6943b0 Update README: add nix build instructions and fix wording

2 months ago

df46d23 add default.nix and a NixOS build

4 months ago


builds.sr.ht status

Sandglass is a minimalistic habit tracker. It lets you record the time you invested in a habit as well as some events associated with that habit. An event could be marking some progress or achievement, or anything you see as important to your commitment to the habit.

It visualizes the data in two ways.

  • Calendar. This is the most traditional visualization most habit trackers support: show for each day whether the habit was followed. Broken down into weeks, it's similar to Github's contribution chart.

  • Progress bar. This draws all the time you invested in a given habit as one continuous segment, not scaled with respect to the actual calendar time. And then adds the events associated with it as points on that segment. This way you can see how your investment in the habit corresponded to the outcomes so far. It serves as level bars often used in RPG games that show how much do you need to “farm” until the next “level up”.

Sandglass doesn't aid you in tracking the habits, it merely visualizes the data you put into a text file. It expects you to track your habits on paper (no devices, no distractions) and enter it into Sandglass once every few days.

Some of this was inspired by James Clear's Atomic Habits book, some with my own experience of building habits.


Pick one of the two options:

  1. Using Stack: run stack run and stack install.

  2. Using Archlinux package: run makepkg -si. This builds and installs the package with all the necessary dependencies.

  3. Using Nix: run nix-env -i -f default.nix.


Sandglass reads

  • habit definitions from ~/.config/sandglass/activities.txt and
  • the tracking entries from ~/.config/sandglass/log.txt.

Below are examples of syntax for these files. Parsers for these configs are very friendly, if you get something wrong, they'll help you fix it.


# this is a comment

# Short unique habit identifier followed by a colon starts habit definition.
  description: Reading good books   # ← Abritrary string
  goal: 01:00                       # ← Daily goal, 1h in this example

  description: Running outside
  goal: 00:30                   # ← Goal is to run for 30min each day
  archived: true                # ← This hides the habit from menus, in case
                                # you've quit it for now, but may get back
                                # to it later


# this is a comment

# Following entry means "read for 25min and ran for 1:10 on Jan 1":
  00:25 reading
  01:10 running
  # ^ The syntax for time entry is <duration> <habit identifier>
  02:00 reading tried Crime and Punishment, liked very much
  # ^ You can optionally add note after <habbit identifier>
  reading finished Crime and Punishment
  # ^ This declares an event/archivement associated with the habit
  # The syntax is <habit identifier> <event description>
  01:05 reading
  00:25 running
  00:15 reading a bit more reading before bed
  # ^You can arbitrarily mix time entries and events inside the same day
  # multiple entries for the same habit are supported

#Vty config gotchas

This program uses vty Haskell library for terminal interaction. You can customize its behavior through the standard config file (in my case it was ~/.vty/config).

One useful thing you can do is setup a multi-column character tables for proper rendering of unicode emojis and Japanese symbols in your terminal. Run vty-build-width-table and put widthMap "$TERM" ".dat file produced by vty-build-width-table" in your ~/.vty/config.

If you're not using any odd symbols like emojis, you likely won't need this.

#Similar projects