diff --git a/spec/13-progress_spec.lua b/spec/13-progress_spec.lua index 2380803..e2a0bb7 100644 --- a/spec/13-progress_spec.lua +++ b/spec/13-progress_spec.lua @@ -83,4 +83,23 @@ describe("terminal.progress", function() end) + + + describe("progress_path()", function() + + it("renders progress correctly", function() + local result = progress.progress_path(50, 10, "S", ">") + assert.are.equal("S.....>", result) + end) + + + it("clamps percent between 0 and 100", function() + local r1 = progress.progress_path(-10, 10, "", ">") + local r2 = progress.progress_path(150, 10, "", ">") + assert.are.equal("..........>", r1) + assert.are.equal(">", r2) + end) + + end) + end) diff --git a/src/terminal/progress.lua b/src/terminal/progress.lua index 920b7fe..66f8c5f 100644 --- a/src/terminal/progress.lua +++ b/src/terminal/progress.lua @@ -134,6 +134,37 @@ end +--- Path progress animation where a runner moves left to right through dots. +-- The runner consumes the dots as progress increases. +-- +-- Example: +-- progress_path(40, 20, "📍", "🚙") +-- +-- Output example: +-- 📍........🚙 40% +-- +-- @tparam number percent progress 0-100 +-- @tparam[opt=20] number width number of dot characters in the path +-- (total visual width = width + start_icon length + runner_icon length) +-- @tparam string start_icon icon at the start position +-- @tparam string runner_icon icon representing the runner/progress +function M.progress_path(percent, width, start_icon, runner_icon) + width = width or 20 + start_icon = start_icon or "" + runner_icon = runner_icon or ">" + + percent = math.max(0, math.min(100, percent)) + + local filled = math.floor((percent / 100) * width) + local remaining = width - filled + + local dots = string.rep(".", remaining) + + return start_icon .. dots .. runner_icon +end + + + --- Create a text/led ticker like sprite-sequence for use with a progress spinner. -- @tparam string text the text to display -- @tparam[opt=40] number width the width of the ticker, in characters