Terminal styling and layout widgets for OCaml (tables, trees, panels, colors)
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

tty: extract tty-eio package with Progress.animate helper

Adds a separate `tty-eio` package containing `Tty_eio.Progress.animate`,
an Eio-fiber-based redraw loop. Splitting it out keeps the core `tty`
library scheduler-agnostic.

+77 -16
+12
dune-project
··· 23 23 (uutf (>= 1.0)) 24 24 (alcotest :with-test) 25 25 (crowbar :with-test))) 26 + 27 + (package 28 + (name tty-eio) 29 + (synopsis "Eio bindings for tty progress bars") 30 + (tags (org:blacksun cli format eio)) 31 + (description 32 + "Helpers that animate Tty.Progress bars from an Eio fiber. Split out 33 + so the core tty library stays scheduler-agnostic.") 34 + (depends 35 + (ocaml (>= 5.1)) 36 + (tty (= :version)) 37 + (eio (>= 1.0))))
+4
lib/eio/dune
··· 1 + (library 2 + (name tty_eio) 3 + (public_name tty-eio) 4 + (libraries tty eio))
+7
lib/eio/progress.ml
··· 1 + let animate ~sw ~clock bar = 2 + Eio.Fiber.fork_daemon ~sw (fun () -> 3 + while not (Tty.Progress.is_finished bar) do 4 + Eio.Time.sleep clock 0.1; 5 + if not (Tty.Progress.is_finished bar) then Tty.Progress.redraw bar 6 + done; 7 + `Stop_daemon)
+6
lib/eio/progress.mli
··· 1 + (** Eio-based animation loop for {!Tty.Progress} bars. *) 2 + 3 + val animate : 4 + sw:Eio.Switch.t -> clock:_ Eio.Time.clock -> Tty.Progress.t -> unit 5 + (** [animate ~sw ~clock bar] forks a daemon fiber on [sw] that redraws [bar] 6 + every 100 ms until {!Tty.Progress.is_finished} returns [true]. *)
-1
lib/progress.ml
··· 270 270 271 271 let redraw = display 272 272 let is_finished t = t.finished 273 - 274 273 let position t = t.s.current 275 274 276 275 let pp ppf t =
+5 -5
lib/progress.mli
··· 122 122 position, spawn a loop that calls {!redraw} on your own scheduler: 123 123 {[ 124 124 Eio.Fiber.fork_daemon ~sw (fun () -> 125 - while not (Progress.is_finished bar) do 126 - Eio.Time.sleep clock 0.1; 127 - Progress.redraw bar 128 - done; 129 - `Stop_daemon) 125 + while not (Progress.is_finished bar) do 126 + Eio.Time.sleep clock 0.1; 127 + Progress.redraw bar 128 + done; 129 + `Stop_daemon) 130 130 ]} *) 131 131 132 132 val redraw : t -> unit
+12 -10
test/test_progress.ml
··· 102 102 ignore (read_bar ()); 103 103 Progress.message b "middle"; 104 104 Progress.tick b; 105 - Alcotest.(check bool) "shows updated message" true 105 + Alcotest.(check bool) 106 + "shows updated message" true 106 107 (contains "middle" (read_bar ())) 107 108 108 109 let test_phase () = ··· 194 195 ignore (read_bar ()); 195 196 Progress.log b "fetching foo"; 196 197 let output = Format.flush_str_formatter () |> strip_ansi in 197 - Alcotest.(check bool) "status text appears" true 198 + Alcotest.(check bool) 199 + "status text appears" true 198 200 (contains "fetching foo" output); 199 201 Alcotest.(check bool) "bar still renders" true (contains "With status" output) 200 202 201 203 let test_log_ring_drops () = 202 204 let b = bar ~status_lines:2 ~total:10 "Ring" in 203 - ignore (read_bar ()); 204 205 Progress.log b "first"; 206 + ignore (Format.flush_str_formatter ()); 205 207 Progress.log b "second"; 208 + ignore (Format.flush_str_formatter ()); 206 209 Progress.log b "third"; 207 210 let output = Format.flush_str_formatter () |> strip_ansi in 208 211 Alcotest.(check bool) "oldest dropped" false (contains "first" output); ··· 223 226 assert the final block has the right shape by checking newlines. *) 224 227 ignore final_block; 225 228 let total_newlines = count_lines output in 226 - Alcotest.(check bool) "block writes multi-line output" true 227 - (total_newlines >= 2) 229 + Alcotest.(check bool) 230 + "block writes multi-line output" true (total_newlines >= 2) 228 231 229 232 let test_log_noop_disabled () = 230 233 let b = ··· 253 256 Alcotest.test_case "stays on one line" `Quick test_stays_on_one_line; 254 257 (* Redraw and animation *) 255 258 Alcotest.test_case "redraw emits \\r" `Quick test_redraw_emits_cr; 256 - Alcotest.test_case "redraw keeps position" `Quick test_redraw_keeps_position; 259 + Alcotest.test_case "redraw keeps position" `Quick 260 + test_redraw_keeps_position; 257 261 Alcotest.test_case "is_finished" `Quick test_is_finished; 258 262 Alcotest.test_case "redraw after finish" `Quick test_redraw_after_finish; 259 263 Alcotest.test_case "redraw while disabled" `Quick 260 264 test_redraw_while_disabled; 261 265 Alcotest.test_case "animation loop" `Quick test_animation_loop; 262 266 (* Status zone *) 263 - Alcotest.test_case "status off by default" `Quick 264 - test_status_lines_off; 267 + Alcotest.test_case "status off by default" `Quick test_status_lines_off; 265 268 Alcotest.test_case "log emits status row" `Quick test_log_emits_status_row; 266 - Alcotest.test_case "log ring drops oldest" `Quick 267 - test_log_ring_drops; 269 + Alcotest.test_case "log ring drops oldest" `Quick test_log_ring_drops; 268 270 Alcotest.test_case "log block clears cleanly" `Quick 269 271 test_log_block_clears_cleanly; 270 272 Alcotest.test_case "log silent when disabled" `Quick
+31
tty-eio.opam
··· 1 + # This file is generated by dune, edit dune-project instead 2 + opam-version: "2.0" 3 + synopsis: "Eio bindings for tty progress bars" 4 + description: """ 5 + Helpers that animate Tty.Progress bars from an Eio fiber. Split out 6 + so the core tty library stays scheduler-agnostic.""" 7 + maintainer: ["Thomas Gazagnaire <thomas@gazagnaire.org>"] 8 + authors: ["Thomas Gazagnaire <thomas@gazagnaire.org>"] 9 + license: "MIT" 10 + tags: ["org:blacksun" "cli" "format" "eio"] 11 + depends: [ 12 + "dune" {>= "3.0"} 13 + "ocaml" {>= "5.1"} 14 + "tty" {= version} 15 + "eio" {>= "1.0"} 16 + "odoc" {with-doc} 17 + ] 18 + build: [ 19 + ["dune" "subst"] {dev} 20 + [ 21 + "dune" 22 + "build" 23 + "-p" 24 + name 25 + "-j" 26 + jobs 27 + "@install" 28 + "@runtest" {with-test} 29 + "@doc" {with-doc} 30 + ] 31 + ]