From 91f1be4d763305693e159a151630f227a29cb41d Mon Sep 17 00:00:00 2001 From: Jonathan Bernard Date: Sun, 29 Jun 2025 21:24:10 -0500 Subject: [PATCH] nim: Make printing customizable and default to colored output. --- console_progress.nimble | 2 +- src/main/nim/console_progress.nim | 60 +++++++++++++++++++++++++------ src/test/nim/test.nim | 8 +++++ 3 files changed, 58 insertions(+), 12 deletions(-) create mode 100644 src/test/nim/test.nim diff --git a/console_progress.nimble b/console_progress.nimble index 3352c25..0fa282e 100644 --- a/console_progress.nimble +++ b/console_progress.nimble @@ -1,6 +1,6 @@ # Package -version = "1.2.2" +version = "1.2.3" author = "Jonathan Bernard" description = "Utility for writing dynamic progress bars to the console." license = "BSD" diff --git a/src/main/nim/console_progress.nim b/src/main/nim/console_progress.nim index 4a451f9..7d109c9 100644 --- a/src/main/nim/console_progress.nim +++ b/src/main/nim/console_progress.nim @@ -1,11 +1,37 @@ import strutils, times, math -type Progress* = ref object of RootObj - sout: File - lastStep, width, maxSteps: int - startTime: float - lastInfo: string - maxValue: BiggestInt +type + PBDisplayConfig* = object + ## Progress Bar Display Configuration - controls how the progress bar is + ## displayed to the terminal + before*: string ## Written at the start, before the bar. This is + ## intended for ANSI control characters and must take + ## up zero characters when printed. + after*: string ## Written at the end, after the bar This is intended + ## for ANSI control characters and must take up zero + ## characters when printed. + completed*: string ## Written for each completed step of the bar. This + ## should take up one character of space when printed. + todo*: string ## Written for each step remaining in the bar. This + ## should take up one character of space when printed. + separator*: string ## Written for the current step, separating completed + ## and done. This should take up one character of space + ## when printed. + + Progress* = ref object of RootObj + sout: File + lastStep, width, maxSteps: int + startTime: float + lastInfo: string + maxValue: BiggestInt + displayCfg: PBDisplayConfig + +const DEFAULT_DISPLAY_CFG* = PBDisplayConfig( + before: "\x1b[38;5;2m", + after: "\x1b[0m", + completed: "━", + todo: "─", + separator: "𜱶\x1b[38;5;8m") proc getMax*(pd: Progress): BiggestInt = return pd.maxValue @@ -13,13 +39,20 @@ proc getMax*(pd: Progress): BiggestInt = proc setMax*(pd: Progress, maxValue: BiggestInt) = pd.maxValue = max(maxValue, 1) -proc newProgress*(maxValue: BiggestInt, sout: File = stdout): Progress = +proc newProgress*( + maxValue: BiggestInt, + sout: File = stdout, + width: int = 79, + maxSteps: int = 35, + displayCfg: PBDisplayConfig = DEFAULT_DISPLAY_CFG): Progress = + return Progress(sout: sout, startTime: cpuTime(), lastStep: 0, maxValue: maxValue, width: 79, - maxSteps: 35) + maxSteps: 35, + displayCfg: displayCfg) proc updateProgress*(pd: Progress, newValue: BiggestInt, info: string): void = @@ -32,7 +65,9 @@ proc updateProgress*(pd: Progress, newValue: BiggestInt, info: string): void = let curDuration = cpuTime() - pd.startTime let remTime = ((curDuration / curPercent) - curDuration) - let displayedSteps = max(curStep - 1, 0) + let displayedSteps = + if curStep == pd.maxSteps: curStep + else: max(curStep - 1, 0) pd.lastInfo = info var displayedInfo = info @@ -43,8 +78,11 @@ proc updateProgress*(pd: Progress, newValue: BiggestInt, info: string): void = pd.sout.write('\b'.repeat(pd.width)) var line = - '='.repeat(displayedSteps) & (if curStep > 0: "0" else: "") & - '-'.repeat(pd.maxSteps - curStep) & " " & + pd.displayCfg.before & + pd.displayCfg.completed.repeat(displayedSteps) & + (if curStep > 0 and curStep < pd.maxSteps: pd.displayCfg.separator else: "") & + pd.displayCfg.todo.repeat(pd.maxSteps - curStep) & + pd.displayCfg.after & " " & displayedInfo & " -- (" & (curPercent * 100).formatFloat(ffDecimal, 2) & "%" diff --git a/src/test/nim/test.nim b/src/test/nim/test.nim new file mode 100644 index 0000000..a6bb894 --- /dev/null +++ b/src/test/nim/test.nim @@ -0,0 +1,8 @@ +import std/os +import ../../main/nim/console_progress + +when isMainModule: + let pd = newProgress(100) + for i in 0 .. 100: + pd.updateProgress(i, "step " & $i) + sleep 25