open Types let ansi_filter s = s |> function | Ansi a -> Types.Ansi (List.filter (function Types.Fg _ | Types.Bg _ -> false | _ -> true) a) | n -> n let permute order a = Array.mapi (fun i _ -> a.(order.(i))) a (* TODO: implement this so cli can use a dsl to specify colourising patterns *) type culr = { colours : colour array; sz : int; mutable current : int; mutable first : bool; } module Culriser = struct type filter = (colour -> bool) list type sort = int array let run_filters f el = List.fold_left (fun res filt -> if not (filt el) then false else res) true f let create ?(s = [| 0; 1; 2; 3; 4; 5; 6; 7; 8; 9; 10; 11; 12; 13; 14; 15 |]) ?(f = []) c = let colours = c |> List.fold_left (fun acc el -> if run_filters f el then acc @ [ el ] else acc) [] |> Array.of_list |> permute s in { colours; sz = Array.length colours; current = 0; first = true } let next t = let nv = t.current + 1 in if nv >= t.sz then t.current <- 0 else t.current <- nv; t.colours.(t.current) let reset t = t.current <- 0 let add_colour t chunk = if t.first then ( t.first <- false; Ansi [ Fg (next t) ] :: [ chunk ]) else match chunk with | Separator _ -> chunk :: [ Ansi [ Fg (next t) ] ] | Delimiter _ -> reset t; chunk :: [ Ansi [ Fg (next t) ] ] | Ansi _ -> [ chunk ] | Text _ -> [ chunk ] end