Skip to content

Instantly share code, notes, and snippets.

@godDLL
Last active December 24, 2023 16:02
Show Gist options
  • Save godDLL/b4a43505b0dac4f12dcd73046efae5ee to your computer and use it in GitHub Desktop.
Save godDLL/b4a43505b0dac4f12dcd73046efae5ee to your computer and use it in GitHub Desktop.
Interactive time-logging calculator on console. Kinda like pomodoro with soulver/numi inside, but in your terminal.

Time Log Fish

Download Latest v0.3  |  HackerNews  |  Bugs & Suggestions

A utility to log time on the terminal.
It's like a task list that can be saved.
Has a calculator built-in.

Marks current time automatically, has some editing features.
demo

Plays nice with terminal themes.
Integrates with user (meaning Your's) status-line scripts. Please post your own screenshots.


=calc demo

Installation and Usage

This script depends on the FISH shell, as well as a decent date command.
The ANSI-colors stripping requires a sed command.

To use it copy time-log.fish anywhere in your PATH and chmod +x the script.
Run it, optionally followed by a HEADING.

If you want to use your own scripts for STATUS or TITLE you can do so:

STATUS='df -h / |tail -1 |cut -d" " -f13' \
TITLE=date\ +%Y/%d/%m \
time-log.fish HEADING

Screen Shot 2021-11-06 at 20 37 08

Saving to File

Time Log Fish can write to a file with the !w command.
This file has all the movement and colors.

If you'd like to see the file use cat FILE.
The colors can be removed with cat FILE | time-log.fish -

Marking notes with Time-stamps

Every line in Time Log Fish is time-stamped by default.
Use / to see the difference between last time-stamp and current time.
Enter an empty line to refresh current time, and show STATUS below.
To keep note of this status line enter ++ (this does not update last time-stamp).

To enter a note without updating last time-stamp start the line with +,
or with - to replace the contents of the line above.

Lines can be deleted and edited with --, and auto-stamped with -+

Calculations, maths

Simple math expressions =1+1= 2 are available
help math

To use the last result in a new expression start the line with . instead of =
Going back to the result before last is done with ..

Use ? to summon a HELP cheat-sheet.

     <Enter> to refresh the time
  ⋯  type anything and TIME stays
 --  edit last line, replacing it
 +⋯  add a NOTE                   (default: empty line)
 -⋯  replace last NOTE      (default: delete last note)

 -+  prepend current TIME to the last line     (+- too)
 /   append time difference to the last line   (* also)
 ++  insert weekday & STATUS          (default: HH:MM.)

 =⋯  calculate and note down the result    (default: 0)
 .⋯  use last result                 (default: show it)
 ..  discard last result, use one before (or 0 if none)

 !w  (over)write to file     (default: DATE HH:MM.plog)
     to strip ANSI coloring use `cat FILE | time-log -`

 tag: note
 mark:specific.time

CHANGELOG

* calculator changed to use = instead of :
+ see the time difference with just /
* status adding changed from just + to ++
* a + adds an empty line
+ added facility to strip ANSI colors (keeps motions tho)
+ previous line can now be time-stamped with -+
+ previous line can now be edited with --
+ calculate using last calc result with ./3
+ zero out last result with just :
+ TITLE env variable for custom command hooks
+ setting STATUS command, and ovrerriding it with ARGV
+ deleting and replacing lines interactively
+ adding lines interactively
+ refreshing TIME in prompt with Enter, runs STATUS below
+ adding STATUS as a line with just +
+ adding empty lines with +SPACE
+ writing ANSI file with !w (use cat to view)
+ tagging a line
+ back-dating HH:MM. lines
+ calculate math with :5/13
+ exit with Ctrl-C or Ctrl-D

License MIT, free to do whatever. Yours to fuck up.
USAGE demo (old by now)

TODO

- FIXME: use manually backdated items for time diff calc when refreshing with /
- accept filename for !w
- FIXME: lines after ? are not lines in the PLOG, don't delete when deleting or whatever
#!/usr/bin/env fish
# v0.3 gist.github.com/godDLL/b4a43505b0dac4f12dcd73046efae5ee
#
# works with the files !w writes
if test '-' = "$argv"
set -l ansi 's/'\e'\[[0-9;]*[m]//g'
while read -l N
echo -e -- "$N" |sed $ansi
end
exit
end
if set -q TITLE
set -- TITLE (fish -c "$TITLE")
else
set -- TITLE (date +%d\ %m-%Y)
end
set TITLE_len (string length -- " $TITLE")
set -l PLOG ## up go to end back up left white on black rst
set -a -- PLOG (echo -e -- '\e[A\e['$COLUMNS'G\e['$TITLE_len'D\e[37;40m '"$TITLE" '\e[m')
echo -- $PLOG[-1]
set -l -- S (date +%H:%M.)
set -l -- ST
if test -n "$STATUS"
if test -n "$argv"
set -- ST "$argv"
else
set -- ST (fish -c "$STATUS")
if test -z "$ST"
set -- ST "$S"
end
end
else
if test -n "$argv"
set -- ST "$argv"
if test -z "$ST"
set -- ST "$S"
end
else
set -- ST "$S"
end
set -- STATUS 'date +%H:%M.'
end
set -l cl '\e[K'
set -l upcl '\e[A'$cl
set -a -- PLOG (echo -e -- $cl'\e[2m' (date +%A) "$ST"'\e[m')
echo -- $PLOG[-1]
#clear
set -e S
set -e ST
set -l ansi 's/'\e'\[[0-9;]*[m|K|G|A|B|C|D]//g'
set -l ripcl '\e[K\e[B\e[K\e[2A\e[K'
set -l ANS ' 0'
# use N > set R, T, P, echo & PLOG > do R, show T, suggest P
set -l P
set -l R
set -l TIME_fmt +\e\[1m'%H:%M'\e\[2m'.%S'\e\[m\
set -l -- T (date $TIME_fmt)
set -l -- EPH (date +%s)
while read -c (echo -e -- "$P") -P (echo -e -- "$R$T") -l N
# simple commands
if test 2 -ge (string length -- "$N"); and string match --invert --quiet -- '=*' "$N"
if test -z "$N"
if test -z "$P"
# don't advance line
set R '\e[A'
else
set R ''
end
set P ''
# do refresh clock
set -- T (date $TIME_fmt)
# where am i?
echo -ne -- $cl'\e[2m' (date +%A\e\[m ; fish -c "$STATUS")'\e[m'
else if test '///' = "/$N/" -o '/*/' = "/$N/"
set P ''
set R '\e[A'
set -l -- TT (math -s0 -- '('(date +%s)' - '$EPH') /60')' min'
echo -ne -- $cl'\e[4m '$TT' \e[m'
set -- T (date $TIME_fmt)
set -e TT
else if test '/--/' = "/$N/"
set -- P (echo -e -- "$PLOG[-1]" |sed $ansi)
if test -z "$P"
set P ' '
end
set R $ripcl'\e[A'
set T ''
set -- PLOG $PLOG[1..-2]
# deleted lines are not logged
else if test '/-+/' = "/$N/" -o '/+-/' = "/$N/"
set P ''
set R ''
set -- PLOG[-1] "$T"(string trim --left -- "$PLOG[-1]")
echo -e -- '\e[A'$ripcl$PLOG[-1]
set -- EPH (date -j -f %H:%M.%S\ (echo -e -- $T |sed $ansi) +%s)
else if test '/-/' = "/$N/"
set P ''
set R $ripcl'\e[A'
set -- PLOG $PLOG[1..-2]
# deleted lines are not logged
else
set P ''
set R ''
if test '/../' = "/$N/"
set -- ANS $ANS[1..-2]
if test -z "$ANS[-1]"
set -- ANS ' 0'
end
set -a -- PLOG "=$ANS[-1]"
echo -e -- $ripcl$PLOG[-1]
else if test '/./' = "/$N/"
set -a -- PLOG "=$ANS[-1]"
echo -e -- $ripcl$PLOG[-1]
else if test '/++/' = "/$N/"
set -a -- PLOG (echo -e -- $cl'\e[2m' (date +%A\e\[m ; fish -c "$STATUS")'\e[m')
echo -e -- $ripcl$PLOG[-1]
set -- T (date $TIME_fmt)
else if test '/+/' = "/$N/"
set -a -- PLOG ''
echo -e -- $ripcl
# prompt commands
else if test '/!w/' = "/$N/"
# works with `cat FILE | time-log -`
set -l FILE (date +%Y-%m\ %d\ %H-%M).plog
if touch "$FILE"
string join -- \n $PLOG \n >"$FILE"
echo -e -- $upcl"\e[3m$FILE now saved\e[m"
else
echo -e -- ' \e[1;31mErr\e[m: write to file '$FILE
end
else
# WONTFIX: don't care if this part slow, you're not running it 10K times
if test '/?/' = "/$N/" -o '/!/' = "/$N/"
echo -ne '\e[3m'
echo -e -- ' <Enter> to refresh the time'
echo -e -- ' ⋯ type anything and TIME stays'
echo -e -- ' -- edit last line, replacing it'
echo -e -- ' +⋯ add a NOTE (default: empty line)'
echo -e -- ' -⋯ replace last NOTE (default: delete last note)\n'
echo -e -- ' -+ prepend current TIME to the last line (+- too)'
echo -e -- ' / show time difference to the last line (* also)'
echo -e -- ' ++ insert weekday & STATUS (default: HH:MM.)\n'
echo -e -- ' =⋯ calculate and note down the result (default: 0)'
echo -e -- ' .⋯ use last result (default: show it)'
echo -e -- ' .. discard last result, use one before (or 0 if none)\n'
echo -e -- ' !w (over)write to file (default: DATE HH:MM.plog)'
echo -e -- ' to strip ANSI coloring use `cat FILE | time-log -`\n'
echo -ne -- ' tag: note\n mark:specific.time'
echo -e '\e[m\n'
else if string match --quiet -- '+*' "$N"
set -l -- M (string sub -s 2 -- "$N")
set -a -- PLOG " $M"
echo -e -- $upcl$PLOG[-1]
# added lines are logged
else if string match --quiet -- '-*' "$N"
set -l -- M (string sub -s 2 -- "$N")
set -- PLOG[-1] " $M"
echo -e -- $upcl$upcl" $M"
# overwritten lines are overwritten in log
# just a short note
else
set -a -- PLOG "$T$N"
end
set -- EPH (date -j -f %H:%M.%S\ (echo -e -- $T |sed $ansi) +%s)
set -- T (date $TIME_fmt)
end
end
# not simple commands
else
set R ''
if string match --quiet -- '=*' "$N"
set -- N (string sub -s 2 -- "$N")
if test -z "$N"
set N ' 0'
end
set -a -- ANS ' '(math -s2 -- "$N")
set -l -- ANS_len (string length -- " =$ANS[-1]")
## dim go to end back up left bold on cyan rst
set -a -- PLOG (echo -e -- '\e[2m=\e[m'$N'\e['$COLUMNS'G\e['$ANS_len'D\e[1;46m ='$ANS[-1]' \e[m')
echo -e -- $upcl$PLOG[-1]
if test -n "$P"
set P ''
set -- T (date $TIME_fmt)
end
set -e ANS_len
else if string match --quiet -- '.*' "$N"
set -- N (string sub -s 2 -- "$N")
set -a -- ANS ' '(math -s2 -- "$ANS[-1] $N")
set -l -- ANS_len (string length -- " =$ANS[-1]")
## dim go to end back up left bold on cyan rst
set -a -- PLOG (echo -e -- '\e[2m.\e[m'$N'\e['$COLUMNS'G\e['$ANS_len'D\e[1;46m ='$ANS[-1]' \e[m')
echo -e -- $upcl$PLOG[-1]
if test -n "$P"
set P ''
set -- T (date $TIME_fmt)
end
set -e ANS_len
else if string match --quiet -- '*:*.*' "$N"
set -l -- M (string split --max 1 -- ' ' "$N")
set -a -- PLOG (echo -e -- "\e[m\e[4m$M[1]\e[m $M[2]")
echo -e -- $upcl$PLOG[-1]
if test -n "$P"
set P ''
set -- T (date $TIME_fmt)
end
set -e M
else if string match --quiet -- '*:*' "$N"
set -l -- M (string split --max 1 -- ':' "$N")
set -- M[2] (string trim --left -- "$M[2]")
set -- M[1] (string upper -- "$M[1]")
set -l -- TT (date +%H:%M.)
## hide dim hide
set -a -- PLOG (echo -e -- "\e[8m$TT.\e[m\e[2m$M[1]\e[m\e[8m:\e[m $M[2]")
echo -e -- $upcl$PLOG[-1]
if test -n "$P"
set P ''
set -- T (date $TIME_fmt)
end
set -e M
set -e TT
else
if string match --quiet -- '+*' "$N"
set P ''
set -l -- M (string sub -s 2 -- "$N")
set -a -- PLOG " $M"
echo -e -- $upcl$PLOG[-1]
set -- T (date $TIME_fmt)
# added lines are logged
else if string match --quiet -- '-*' "$N"
set P ''
set -l -- M (string sub -s 2 -- "$N")
set -- PLOG[-1] " $M"
echo -e -- $upcl$upcl" $M"
set -- T (date $TIME_fmt)
# overwritten lines are overwritten in log
# just a note
else
if test -n "$P"
set P ''
set T ''
end
set -a -- PLOG (echo -e -- "$T$N")
set -- EPH (date -j -f %H:%M.%S\ (echo -e -- $T |sed $ansi) +%s)
set -- T (date $TIME_fmt)
end
end # string match commands
end # if len < 2
end
@godDLL
Copy link
Author

godDLL commented Nov 5, 2021

License MIT, free to do whatever. Yours to fuck up.
asciinema.org/a/447537

@godDLL
Copy link
Author

godDLL commented Nov 5, 2021

Version 0.1 screenshots:

Screen Shot 2021-11-05 at 09 53 29 copy
Screen Shot 2021-11-05 at 09 53 11 copy

@godDLL
Copy link
Author

godDLL commented Nov 5, 2021

v0.1 bug fixes watch cast

+ calculate math with :
* full weekday name in STATUS
* slow default STATUS line now faster

@godDLL
Copy link
Author

godDLL commented Nov 5, 2021

v0.2 bug fixes

+ calculate using last result with .
* zero out last result with just :

calc

@kseistrup
Copy link

Fish's set_color command will output relevant escape sequences for changing colours and other attributes (and resetting them). Use set_color -c to see the colours it recognizes.

@godDLL
Copy link
Author

godDLL commented Nov 6, 2021

@kseistrup Correct.
It is also dog-slow for what I'd be using it for.

And I don't need the help in manipulating my terminal as to the modes, colors, pages etc.
Which it can't do anyway.
So no, not doing that.
👎

EDIT: eh, I did not mean to come over so stern.
There is nothing wrong with set_color except for how slow it is, really.
I don't even use it in my PROMPTs.

@kseistrup
Copy link

That's fine, I never expected you to — just thought I'd mention it.

Personally, I would never call set_color every time I needed it. Rather, I would e.g. set GREEN (setcolor green) in the beginning of the script and then refer to $GREEN everywhere else. Has the potential of making the code more legible.

I use set_color in some of my own fish scripts, and I disagree with the “dog slowness”.

@godDLL
Copy link
Author

godDLL commented Nov 7, 2021

Oh, it is so good to actually meet someone you could comfortably disagree with. I exactly started doing what you describe, than ran that 10K times, and had to get coffee. Then it happened again, in a different script I wrote. So, how was that saying, three times makes an idiot of me, or whatever to that effect.
I am of the opinion that FISH itself is way slow. If only it wasn't so convenient I'd switch away to, eh, I dunno, I'd whip something up.
❤️

UPDATE: looking for iffy sections I found exactly 5 lines to comment where it's all ANSI escapes, should be very readable now. Thanks.
UPDATE: removed one. But he's not starring this gist no more, so whatever.

@godDLL
Copy link
Author

godDLL commented Nov 7, 2021

v0.3 refinements to the UI, bug fixes

new CALC demo
new EDITING demo
new USAGE demo

* calculator changed to use = instead of :
+ see the time difference with just /
* status adding changed from just + to ++
* a + adds an empty line
+ added facility to strip ANSI colors (keeps motions tho)
+ previous line can now be time-stamped with -+
+ previous line can now be edited with --

(Yes, I know that the maths on main screenshot don't make sense, I'll be doing something about taht.)

@godDLL
Copy link
Author

godDLL commented Nov 8, 2021

Added a WIKI file, now that the feature-set and scope of this script has stabilized enough for that.

I might just not be adding any more features, it all feels well-rounded right now. Quite.

@godDLL
Copy link
Author

godDLL commented Nov 14, 2021

v0.4 added menu for your autofill

new MENU demo will appear with imminent v0.5 as part of documentation effort

* general formatting improvements
+ added MENU to call custom script with ! or `
- faster, less subshell usage

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment