From c5c240ca2e0eedd613a476fad42effa764e3172d Mon Sep 17 00:00:00 2001 From: atagen Date: Thu, 5 Dec 2024 23:40:30 +1100 Subject: [PATCH] make sep/delim customisable --- bin/main.ml | 2 +- lib/env.ml | 23 +++++++++++++++-------- lib/env.mli | 1 + lib/parse.ml | 29 +++++++++++++++-------------- lib/parse.mli | 2 +- lib/parsers.ml | 11 +++++++++++ lib/pipes.ml | 4 ++-- nix/culr-module.nix | 14 ++++++++++++++ 8 files changed, 60 insertions(+), 26 deletions(-) diff --git a/bin/main.ml b/bin/main.ml index f58c299..dae0e11 100644 --- a/bin/main.ml +++ b/bin/main.ml @@ -1,3 +1,3 @@ open Culr -let () = Pipes.read_all Env.get_colours \ No newline at end of file +let () = Pipes.read_all Env.get_colours Env.get_parser \ No newline at end of file diff --git a/lib/env.ml b/lib/env.ml index da3b061..3d13da6 100644 --- a/lib/env.ml +++ b/lib/env.ml @@ -16,13 +16,20 @@ let match_env_order = let ( >>= ) = Option.bind -let get_env_colours = - Sys.getenv_opt "CULRS" >>= fun s -> - if String.length s > 0 then Some s else None +let getenv_opt s = + Sys.getenv_opt s >>= fun s -> if String.length s > 0 then Some s else None -let get_env_order = - Sys.getenv_opt "CULR_ORDER" >>= fun s -> - if String.length s > 0 then Some s else None +let explode s = s |> String.to_seq |> Array.of_seq + +let get_parser = + let open Parsers in + let sep = getenv_opt "CULR_SEP" and del = getenv_opt "CULR_DELIM" in + match (sep, del) with + | Some s, Some d -> + create_parser ~separator:(explode s) ~delimiter:(explode d) () + | None, Some d -> create_parser ~delimiter:(explode d) () + | Some s, None -> create_parser ~separator:(explode s) () + | None, None -> create_parser () let to_sixteen f = ints 0 |> take 16 |> f |> Array.of_seq @@ -58,8 +65,8 @@ let permute (order : order) (colours : colour array) = colours let get_colours = - let colours = get_env_colours - and order = get_env_order + let colours = getenv_opt "CULRS" + and order = getenv_opt "CULR_ORDER" and init_default_colours = to_sixteen (map (fun x -> Types.Intrinsic x)) and init_order_for_colours c = let open Seq in diff --git a/lib/env.mli b/lib/env.mli index 7634a75..7605b71 100644 --- a/lib/env.mli +++ b/lib/env.mli @@ -1 +1,2 @@ val get_colours : Types.colour array +val get_parser : Parsers.parser \ No newline at end of file diff --git a/lib/parse.ml b/lib/parse.ml index 1e25f93..04b9844 100644 --- a/lib/parse.ml +++ b/lib/parse.ml @@ -2,20 +2,20 @@ open Types open Angstrom open Parsers -let is_sep = function '\x20' | '\x09' -> true | _ -> false -let is_delim = function '\x0a' | '\x0d' -> true | _ -> false -let is_text c = not (is_sep c || is_delim c || c = '\x1b') -let sep = take_while is_sep >>| fun s -> Separator s -let delim = take_while is_delim >>| fun s -> Delimiter s -let text = take_while is_text >>| fun s -> Text s +let is_sep p c = Array.mem c p.separator +let is_delim p c = Array.mem c p.delimiter +let is_text p c = not (is_sep p c || is_delim p c || c = '\x1b') +let sep p = take_while (is_sep p) >>| fun s -> Separator s +let delim p = take_while (is_delim p) >>| fun s -> Delimiter s +let text p = take_while (is_text p) >>| fun s -> Text s let ansi = Ansi.ansi_parse -let culr_parse = +let culr_parse p = peek_char_fail >>= function - | n when is_sep n -> sep - | n when is_delim n -> delim + | n when is_sep p n -> sep p + | n when is_delim p n -> delim p | n when n = '\x1b' -> ansi - | _n -> text + | _n -> text p let conv_rgb = function [ r; g; b ] -> Types.RGB (r, g, b) | _ -> assert false let hex_digit = take 2 >>| fun s -> int_of_string ("0x" ^ s) @@ -37,22 +37,23 @@ let parse_env_order s = |> unpack |> Array.of_list let%test "sep_parse" = - parse_string ~consume:Consume.All sep " " |> function + + parse_string ~consume:Consume.All (sep (create_parser ())) " " |> function | Ok (Separator " ") -> true | _ -> false let%test "delim_parse" = - parse_string ~consume:Consume.All delim "\n\n\n" |> function + parse_string ~consume:Consume.All (delim (create_parser ())) "\n\n\n" |> function | Ok (Delimiter "\n\n\n") -> true | _ -> false let%test "text_parse" = - parse_string ~consume:Consume.All text "okokyeahok" |> function + parse_string ~consume:Consume.All (text (create_parser ())) "okokyeahok" |> function | Ok (Text "okokyeahok") -> true | _ -> false let%test "culr_parse" = - parse_string ~consume:Consume.All (many1 culr_parse) + parse_string ~consume:Consume.All (many1 (culr_parse (create_parser ()))) "sometext \n\n\n \x1b[38;2;2m" |> function | Ok diff --git a/lib/parse.mli b/lib/parse.mli index 8949d89..7af01f4 100644 --- a/lib/parse.mli +++ b/lib/parse.mli @@ -1,3 +1,3 @@ -val culr_parse : Types.chunk Angstrom.t +val culr_parse : Parsers.parser -> Types.chunk Angstrom.t val parse_env_colours : string -> Types.colour array val parse_env_order : string -> int array diff --git a/lib/parsers.ml b/lib/parsers.ml index f45cdda..7f4dfe3 100644 --- a/lib/parsers.ml +++ b/lib/parsers.ml @@ -7,3 +7,14 @@ let digit = take_while is_digit >>| int_of_string let skip_semi = skip is_semi let semi_digits = sep_by1 skip_semi digit + + +type parser = { + separator : char array; + delimiter : char array; +} + +let create_parser ?(separator = [|'\x20'; '\x09'|]) ?(delimiter = [|'\x0a'; '\x0d'|]) () = { separator ; delimiter } + +let is_sep = function '\x20' | '\x09' -> true | _ -> false +let is_delim = function '\x0a' | '\x0d' -> true | _ -> false diff --git a/lib/pipes.ml b/lib/pipes.ml index 3865070..1449048 100644 --- a/lib/pipes.ml +++ b/lib/pipes.ml @@ -1,11 +1,11 @@ open Processing -let read_all colours = +let read_all colours parser = In_channel.set_binary_mode stdin true; let open Types in let t = Emitter.create and culr = Culriser.create colours in Emitter.serialise t (Ansi [ Fg (Culriser.current culr) ]); - Angstrom_unix.parse_many ~buf_size:4096 Parse.culr_parse + Angstrom_unix.parse_many ~buf_size:4096 (Parse.culr_parse parser) (fun c -> c |> ansi_filter culr |> Culriser.serialise_with_colour culr t) stdin |> function diff --git a/nix/culr-module.nix b/nix/culr-module.nix index c8589ad..fc309c4 100644 --- a/nix/culr-module.nix +++ b/nix/culr-module.nix @@ -19,6 +19,16 @@ in { default = []; description = "palette to use in comma separated RGB hex eg. #0f0f0f"; }; + separators = mkOption { + type = with types; str; + default = ""; + description = "char list of separators to use"; + }; + delimiters = mkOption { + type = with types; str; + default = ""; + description = "char list of delimiters to use"; + }; }; config = mkIf cfg.enable { @@ -34,6 +44,10 @@ in { (serialise.${typeOf cfg.pattern} cfg.pattern); CULR_PALETTE = mkIf (cfg.palette != []) (concatStringsSep ";" cfg.palette); + CULR_SEP = mkIf (cfg.separators != "") (cfg.separators); + CULR_DELIM = mkIf (cfg.delimiters != "") (cfg.delimiters); + }; + }; }; }; }