Skip to content

Instantly share code, notes, and snippets.

@godDLL
Last active January 2, 2016 18:19
Show Gist options
  • Save godDLL/8342287 to your computer and use it in GitHub Desktop.
Save godDLL/8342287 to your computer and use it in GitHub Desktop.
Works for me on Mac OS X.
$ timer Boring Customer \#4
Name your timer? wordpress
14:12 Started timer wordpress
0s > wait
14:12 Paused timer wordpress
9s + ; 5-minute configuration
9s +
14:22 Started timer wordpress
22m15s > x
14:45 Total time wordpress 22m15s
; session time 32m57s
Name your timer?
14:55 Started timer
0s > x
14:56 Total time timer 18s
; session time 0m18s
Name your timer? x
2014-01-09 Boring Customer #4
wordpress 22m15s ; 5-minute configuration
timer 18s ;
22m33s Total time
$ _
#!/usr/bin/env MAIN= bash
# runs a named timer that you can pause, time after time
# will print a ledger-like entry on Ctrl-C
#
# http://www.gnu.org/software/bash/manual/bashref.html
#
timer () { # DEFAULT_ACCOUNT_NAME
time_fmt () { # prints SECONDS in 0h0m0s format
unset H M
local H M
[[ 60 -gt $1 ]] && printf "${1}s" \
|| (M=$(($1 / 60))
[[ 60 -gt $M ]] && printf "${M}m$(($1 - $M * 60))s" \
|| (H=$(($M / 60))
printf "${H}h$(($M - $H * 60))m$(($1 - $M * 60))s"))
}
START_TIME=$(date +%s)
date_fmt () { # prints SECONDS in YY-MM-DD format
date -j -r ${1:-$START_TIME} +%Y-%m-%d
}
sum_nums () { # sums up numbers from STDIN
awk -v RS=' ' '{sum+=$0} END {print sum}'
}
DEF_ACC=$@
COUNTS=() NAMES=() COMMENTS=()
MARK=`tput setaf 7` PARK=`tput setaf 13` BARK=`tput setaf 4` YELL=`tput setaf 3` UMRK=`tput sgr0`
print_result () {
echo
echo $MARK`date_fmt`$UMRK" $DEF_ACC"
local I=0 NAME
for AMT in ${COUNTS[@]}; do
NAME="${NAMES[$I]:-timer}"
while (( ${#NAME} < 16 )); do
NAME=" $NAME"
done
echo "$NAME "$MARK`time_fmt $AMT`$UMRK$'\t'\;${COMMENTS[$I]}
I=$(($I + 1))
done
echo $(time_fmt `sum_nums <<< "${COUNTS[@]}"`) ${YELL}Total time$UMRK >&2
unset START_TIME DEF_ACC COUNTS NAMES COMMENTS \
MARK PARK BARK YELL UMRK \
time_fmt date_fmt sum_nums input_loop print_result
}
trap "print_result" TERM EXIT
input_loop () {
echo $MARK`date +%H:%M`$UMRK Started timer $@ >&2
local TIME=$(date +%s) SHOW=0 COUNT=0 COMMENT
local TIME_DELTA=$TIME STOP PAUSE STATE=
while read -p `time_fmt $SHOW`$'\t'$BARK${STATE:->}$UMRK' ' CMD; do
[[ $CMD = [.xX]* ]] && STOP=1
[[ -n $CMD && $CMD != [.xX]* ]] && PAUSE=1 || PAUSE=
[[ $CMD = [\;#]* ]] && COMMENT+=$'\n'"${CMD#[\;#]}"
TIME=$(date +%s)
[[ $PAUSE ]] && {
[[ -z $STATE ]] && {
echo $PARK`date +%H:%M`$UMRK Paused timer $@ >&2
COUNT=$(($TIME - $TIME_DELTA + $COUNT))
}
STATE='+'
SHOW=$COUNT
} || {
[[ $STOP ]] && {
[[ -z $STATE ]] && COUNT=$(($TIME - $TIME_DELTA + $COUNT))
TIME=$@
TIME=$MARK${TIME:-timer}$UMRK
echo `date +%H:%M` Total time $TIME $YELL`time_fmt $COUNT`$UMRK >&2
COUNTS+=($COUNT)
NAMES+=( "$@" )
COMMENTS+=( "${COMMENT}" )
break
}
[[ $STATE ]] && {
echo $MARK`date +%H:%M`$UMRK Started timer $1 >&2
STATE=
TIME_DELTA=$TIME
} || tput cuu1
SHOW=$(($TIME - $TIME_DELTA + $COUNT))
}
done
}
user_interrupt () {
echo -n $'\nStop and exit the timer? ([y]/n) ' >&2
read ANS
[[ ${ANS:-y} = [yY] ]] && exit
}
trap 'user_interrupt' INT
local TIMEFORMAT='; session time %0lR'
while true; do
read -p 'Name your timer? ' TIMER || {
echo >&2 ; break
}
[[ $TIMER = [.xX] ]] && break
time input_loop "$TIMER"
done
}
## run if not sourced from other script
# TODO: make it function when sourced
[[ ${MAIN-RUN} ]] || {
(( $# == 1 )) && [[ $1 = *-h* ]] && {
cat <<HELP
Usage: `basename ${BASH_SOURCE[0]}` [DEFAULT_ACCOUNT]
Account name is optional; pause the timer by typing,
start it again with blank line, end it with . or x
To add a comment start line with ; or #, comments pause.
Will print ledger-style entry upon exiting.
HELP
exit
}
timer $@
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment