swap spinny to using bbstrings

This commit is contained in:
Daylin Morgan 2024-11-22 11:04:51 -06:00
parent 186dab6d84
commit 3cf572ea4a
Signed by: daylin
GPG key ID: 950D13E9719334AD

View file

@ -5,47 +5,50 @@ type
Spinny = ref object
t: Thread[Spinny]
lock: Lock
text: string
text: BbString
running: bool
frames: seq[string]
frame: string
bbFrames: seq[BbString]
frame: BbString
interval: int
customSymbol: bool
style: string
file: File
EventKind = enum
Stop
SymbolChange
TextChange
SpinnyEvent = object
kind: EventKind
payload: string
payload: BbString
var spinnyChannel: Channel[SpinnyEvent]
proc newSpinny*(text: string, s: Spinner): Spinny =
proc newSpinny*(text: string | Bbstring, s: Spinner): Spinny =
let style = "bold blue"
Spinny(
text: text,
text: bb(text),
running: true,
frames: mapIt(s.frames, $bb(bbEscape(it), style)),
frames: s.frames,
bbFrames: mapIt(s.frames, bb(bbEscape(it), style)),
customSymbol: false,
interval: s.interval,
style: "bold blue",
file: stderr,
)
proc newSpinny*(text: string, spinType: SpinnerKind): Spinny =
proc newSpinny*(text: string | Bbstring, spinType: SpinnerKind): Spinny =
newSpinny(text, Spinners[spinType])
proc setSymbolColor*(spinny: Spinny, style: string) =
spinny.frames = mapIt(spinny.frames, $bb(it, style))
spinny.bbFrames = mapIt(spinny.frames, bb(bbEscape(it), style))
proc setSymbol*(spinny: Spinny, symbol: string) =
spinnyChannel.send(SpinnyEvent(kind: SymbolChange, payload: symbol))
spinnyChannel.send(SpinnyEvent(kind: SymbolChange, payload: bb(symbol)))
proc setText*(spinny: Spinny, text: string) =
spinnyChannel.send(SpinnyEvent(kind: TextChange, payload: text))
proc setText*(spinny: Spinny, text: string | BbString) =
spinnyChannel.send(SpinnyEvent(kind: TextChange, payload: bb(text)))
proc handleEvent(spinny: Spinny, eventData: SpinnyEvent): bool =
result = true
@ -74,14 +77,15 @@ proc spinnyLoop(spinny: Spinny) {.thread.} =
spinny.running = false
break
stdout.flushFile()
flushFile spinny.file
if not spinny.customSymbol:
spinny.frame = spinny.frames[frameCounter]
spinny.frame = spinny.bbFrames[frameCounter]
# TODO: instead of truncating support multiline text, need custom wrapping and cleanup then
withLock spinny.lock:
eraseLine()
stdout.write(spinny.frame & " " & spinny.text)
stdout.flushFile()
eraseLine spinny.file
spinny.file.write $((spinny.frame & " " & spinny.text).truncate(terminalWidth())) # needs to be truncated
flushFile spinny.file
sleep spinny.interval
@ -96,37 +100,35 @@ proc start*(spinny: Spinny) =
createThread(spinny.t, spinnyLoop, spinny)
proc stop(spinny: Spinny, kind: EventKind, payload = "") =
spinnyChannel.send(SpinnyEvent(kind: kind, payload: payload))
spinnyChannel.send(SpinnyEvent(kind: kind, payload: bb(payload)))
spinnyChannel.send(SpinnyEvent(kind: Stop))
joinThread spinny.t
eraseLine stdout
flushFile stdout
eraseLine spinny.file
flushFile spinny.file
proc stop*(spinny: Spinny) =
spinny.stop(Stop)
template withSpinner*(msg: string = "", body: untyped): untyped =
var spinner {.inject.} = newSpinny(msg, Dots)
if isatty(stdout): # don't spin if it's not a tty
if isatty(spinner.file): # don't spin if it's not a tty
start spinner
body
if isatty(stdout):
body
stop spinner
else:
body
template withSpinner*(body: untyped): untyped =
withSpinner("", body)
template with*(kind: SpinnerKind, msg: string, body: untyped): untyped =
var spinner {.inject.} = newSpinny(msg, kind)
if isatty(stdout): # don't spin if it's not a tty
if isatty(spinner.file): # don't spin if it's not a tty
start spinner
body
if isatty(stdout):
body
stop spinner
else:
body
when isMainModule:
for kind, _ in Spinners: