#!/bin/sh [ "$skip_libraries" ] && return export now="$(date +%s.%N)" # export state state() { echo "$lap $running $time" ; } # load original_state once per invocation of dppt if [ -z "$original_state" ] ; then # import state mkdir -p "$POMODORO_STATE_PATH" if [ -e "$POMODORO_STATE_PATH/current" ] ; then read -r lap running time < "$POMODORO_STATE_PATH/current" fi # ensure state variables are always initialized lap=${lap:-0} running=${running:-0} time=${time:-0} # save original state (see save_state function) original_state="$(state)" fi # allow overriding this value manually [ -z "$update_time" ] && update_time=0 # calculate remaining time on timer if [ -z "$remaining" ] ; then remaining="$time" [ $running -eq 1 ] && remaining="$(echo "( $time - $now ) / 1" | bc)" fi # go to next lap if this timer expired if [ $running -eq 1 ] && [ "${remaining#-}" != "${remaining}" ] ; then lap=$(( $lap + 1 )) state='paused' update_time=1 fi if [ $update_time -eq 1 ] ; then # skip_libraries is used to prevent endless loop (see top of this file) time=$(skip_libraries=y "$prog" lap $lap) remaining=$time fi save_state() { new_state="$(state)" # do not save files if state didn't change [ "$original_state" = "$new_state" ] && return # The state update needs to be atomic since other instances may access the # state during an update. This is accomplished by replacing a single symlink, # which should be atomic on most POSIX-compatible platforms, and is less # complicated than a lockfile. $POMODORO_STATE_PATH contains three items: # # 1. current -- a symlink to `primary` or `secondary` # 2. primary -- file containing current state* # 3. secondary -- temporary file used write new state # # * `primary` will only contain stale state during an update (i.e. while # `current` is pointing to `secondary`) # save state and create replacement symlink for `current` echo "$new_state" > "$POMODORO_STATE_PATH/secondary" ln -sf "secondary" "$POMODORO_STATE_PATH/current~" # this is the atomic update that replaces the `current` symlink with the new # state mv "$POMODORO_STATE_PATH/current~" "$POMODORO_STATE_PATH/current" # next, replace the old `primary` state with the new state from `secondary` cp "$POMODORO_STATE_PATH/secondary" "$POMODORO_STATE_PATH/primary" # and update the symlink a second time to now point to `primary` again (this # does not change the state) ln -sf "primary" "$POMODORO_STATE_PATH/current~" mv "$POMODORO_STATE_PATH/current~" "$POMODORO_STATE_PATH/current" } # state variables export lap running time # calculated variables export remaining