Last active
October 3, 2022 20:10
-
-
Save ezr/6c7a9d4d880b5ea489d726b693cf28bd to your computer and use it in GitHub Desktop.
A CLI stopwatch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"os" | |
"time" | |
"github.com/gdamore/tcell/v2" | |
"github.com/ltcsuite/lnd/ticker" | |
"github.com/mattn/go-runewidth" | |
) | |
func emitStr(s tcell.Screen, x, y int, style tcell.Style, str string) { | |
for _, c := range str { | |
var comb []rune | |
w := runewidth.RuneWidth(c) | |
if w == 0 { | |
comb = []rune{c} | |
c = ' ' | |
w = 1 | |
} | |
s.SetContent(x, y, c, comb, style) | |
x += w | |
} | |
} | |
func displayTime(time string, s tcell.Screen) { | |
w, h := s.Size() | |
s.Clear() | |
style := tcell.StyleDefault | |
emitStr(s, w/2-7, h/2, style, time) | |
emitStr(s, w/2-9, h/2+2, style, "Press ENTER to toggle pause.") | |
emitStr(s, w/2-9, h/2+3, style, "Press ESC to exit.") | |
s.Show() | |
} | |
func formatSecs(i int) string { | |
// takes a number of seconds and returns it formatted as hh:mm:ss | |
// after 100 hours it will start to be like: hhh:mm:ss | |
hours := i / 3600 | |
hoursRemainder := i % 3600 | |
minutes := hoursRemainder / 60 | |
seconds := hoursRemainder % 60 | |
return fmt.Sprintf("%02d:%02d:%02d", hours, minutes, seconds) | |
} | |
func main() { | |
tcell.SetEncodingFallback(tcell.EncodingFallbackASCII) | |
s, e := tcell.NewScreen() | |
if e != nil { | |
fmt.Fprintf(os.Stderr, "%v\n", e) | |
os.Exit(1) | |
} | |
if e = s.Init(); e != nil { | |
fmt.Fprintf(os.Stderr, "%v\n", e) | |
os.Exit(1) | |
} | |
s.Clear() | |
quit := make(chan struct{}) | |
pause := make(chan bool) | |
ispaused := false | |
go func() { | |
for { | |
ev := s.PollEvent() | |
switch ev := ev.(type) { | |
case *tcell.EventKey: | |
if (ev.Key() == tcell.KeyEscape) || (ev.Rune() == 'q') { | |
if ispaused { | |
// we need to unpause first, otherwise the program will lock up | |
pause <- false | |
} | |
close(quit) | |
return | |
} else if ev.Key() == tcell.KeyCtrlL { | |
s.Sync() | |
} else if (ev.Key() == tcell.KeyEnter) || (ev.Rune() == ' ') { | |
ispaused = !ispaused | |
pause <- ispaused | |
} | |
case *tcell.EventResize: | |
s.Sync() | |
} | |
} | |
}() | |
var i = 0 | |
var ts = formatSecs(0) | |
displayTime(ts, s) | |
var timeTicker = ticker.New(time.Second) | |
timeTicker.Resume() // newly created variable is paused | |
loop: | |
for { | |
select { | |
case <-quit: | |
break loop | |
case <-pause: | |
timeTicker.Pause() | |
// block until we get another message in the pause channel | |
<-pause | |
timeTicker.Resume() | |
case <-timeTicker.Ticks(): | |
i++ | |
ts = formatSecs(i) | |
displayTime(ts, s) | |
} | |
} | |
s.Fini() | |
fmt.Println(ts) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment