74 lines
1.9 KiB
OCaml
74 lines
1.9 KiB
OCaml
open Types
|
|
open Array
|
|
|
|
(* 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 : filter) el =
|
|
List.fold_left (fun res filt -> if not (filt el) then false else res) true f
|
|
|
|
let create ?(filters = []) (c : colour array) =
|
|
let ( @ ) = append in
|
|
let colours =
|
|
if List.length filters > 0 then
|
|
fold_left
|
|
(fun acc el -> if run_filters filters el then acc @ [| el |] else acc)
|
|
[||] c
|
|
else c
|
|
in
|
|
{ colours; sz = length colours; current = 0; first = true }
|
|
|
|
let current t = t.colours.(t.current)
|
|
|
|
let next t =
|
|
t.current <- (t.current + 1) mod t.sz;
|
|
t.colours.(t.current)
|
|
|
|
let reset t =
|
|
t.current <- 0;
|
|
t.first <- true
|
|
|
|
let serialise_with_colour t serialiser chunk =
|
|
Emitter.serialise serialiser chunk;
|
|
(match chunk with
|
|
| Separator _ ->
|
|
if not t.first then Emitter.serialise serialiser (Ansi [ Fg (next t) ])
|
|
| Delimiter _ ->
|
|
reset t;
|
|
Emitter.serialise serialiser (Ansi [ Fg (current t) ]);
|
|
| Text _ -> if t.first then t.first <- false
|
|
| _ -> ())
|
|
end
|
|
|
|
let ansi_filter t s =
|
|
s |> function
|
|
| Ansi a -> (
|
|
let open List in
|
|
let ol = length a
|
|
and result =
|
|
a
|
|
|> filter (function Fg _ | Bg _ -> false | _ -> true)
|
|
|> fold_left
|
|
(fun acc el ->
|
|
if el = Reset then acc @ [ el; Fg (Culriser.current t) ]
|
|
else acc @ [ el ])
|
|
[]
|
|
in
|
|
let rl = length result in
|
|
match (rl, ol) with
|
|
(* empty ansi code is equivalent to a reset *)
|
|
| 0, 0 -> Ansi [ Reset; Fg (Culriser.current t) ]
|
|
(* if we filtered everything out of it produce no tokens *)
|
|
| 0, _ -> Empty
|
|
| _, _ -> Ansi result)
|
|
| n -> n
|