# terminal-punch

![](images/punch.png)

`terminal-punch` is a simple command-line time tracker.



Installation
----------------------------------------

    cabal new-install terminal-punch



Stability
----------------------------------------

Despite its early stage, `terminal-punch` seems to work very reliably. It has a [property-based test suite](https://github.com/emilaxelsson/terminal-punch/blob/master/tests/Tests.hs) that covers most aspects of its time measurement.



Basic operation
----------------------------------------

Start by running `punch` in a terminal.

(Since the name of the executable is `punch`, I will use that name for the program in the remainder of the text.)

The program listens to the following keys:

  * **space** to start or stop an interval.
  * **q** or **esc** to quit.
  * Any other key to update the summary.
      - This is useful if time has passed since `punch` was started or if the log file has been updated (see below).

Note that since the start/stop events are persisted in a log file (see below), `punch` doesn't need to be running in the background. It can just be opened temporarily for starting/stopping or viewing the summary. Personally, I use a keyboard shortcut to fire up a terminal with `punch` running in it.

By default, the summary will show the total time for the following periods:

  * Last week
  * This week
  * Yesterday
  * Today

Additional periods can be added by inserting period markers in the log file. We will explain how this is done later.



The log file
----------------------------------------

`punch` stores its time log in `$HOME/.punch`. Here is an example of what the file can look like:

```
Start 2019-01-17 12:29:13.80010349
Stop 2019-01-17 18:51:45.009426249
Start 2019-01-17 18:51:47.342016491
Stop 2019-01-17 19:10:45.566312123

Period "New job"
-- Started my new job
Start 2019-01-18 08:31:00
Stop 2019-01-18 13:40:00
Start 2019-01-18 16:16:00
Stop 2019-01-18 18:39:26.115783139
```

Each line must be one of:

  * A start event, using the keyword `Start`
  * A stop event, using the keyword `Stop`
  * A period marker, using the keyword `Period`
  * A comment, starting with `--`
  * An empty line

The syntax for time stamps should be self-explanatory from the above example. Note that the eight-digit number denoting fractions of a second is optional.

`punch` requires the `Start`/`Stop` events to appear in alternating order. That is, there must not be a sequence consisting of two `Start` events without a `Stop` in between, and vice versa. Moreover, the time stamps must appear in increasing order. If the log gets corrupted, it can only be fixed by manual editing.



Working with the log file
----------------------------------------

`Start`/`Stop` lines are automatically appended to the log when an interval is started or stopped. This is the only thing `punch` ever does to the log; it will never change the existing content of the file. This means that it is completely safe to edit the log file between start/stop events.

Users are expected to manually edit the log in the following situations:

  * To fix/add/remove incorrect or missing events (e.g. when the user forgot to start or stop an interval in time).
  * To insert period markers or comments.

Period markers are used to measure time over longer periods. For example, inserting the line

    Period "New job"

somewhere in the log tells `punch` to keep track of the total time from that point on. The result will be seen as an extra line in the summary:

```
-----------------------------------
New job    :  4 hours, 8 minutes
Last week  :  42 hours, 41 minutes
This week  :  9 hours, 43 minutes
-----------------------------------
Yesterday  :  8 hours, 3 minutes
Today      :  1 hours, 39 minutes
```

Any number of period markers can be inserted into the log.



Limitations and future work
----------------------------------------

`punch` doesn't currently have a way to distinguish between different kinds of work.

One idea for fixing this problem would be to support different "projects". Each project could have its own log file in the `.punch/` directory. Some ideas regarding this approach:

  * Need a better UI for switching between projects. Probably best to use [brick](https://hackage.haskell.org/package/brick) for this.
  * Switching project should automatically stop any running interval in the current project.
  * The current project should be remembered between runs.
  * Summary view could show totals both for the current project and for all projects combined.