From 0bc0958e789847d3065f4d084a96117d62d18691 Mon Sep 17 00:00:00 2001 From: Marc Coquand Date: Tue, 14 May 2024 16:20:57 -0500 Subject: Add nice headings --- lib/stitched_article.ml | 68 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 lib/stitched_article.ml (limited to 'lib/stitched_article.ml') diff --git a/lib/stitched_article.ml b/lib/stitched_article.ml new file mode 100644 index 0000000..41efa75 --- /dev/null +++ b/lib/stitched_article.ml @@ -0,0 +1,68 @@ +module Grep = Grep +module Common = Common +open Notty +module Input_screen = Input_screen + +type state = + { pos : int * int + ; scroll : int + ; content : (string * int * string) array + ; content_pretty : Grep.display_type array + } + +let render_line size_x y scroll (el : Grep.display_type) i = + match el with + | Bold el -> + if i == y - scroll + then ( + let fill = String.make (max (size_x - String.length el) 0) ' ' in + I.strf "%s%s" ~attr:A.(st bold ++ st reverse) el fill |> I.pad ~l:0 ~t:i) + else I.strf "%s" ~attr:A.(st bold) el |> I.pad ~l:0 ~t:i + | Normal el -> + if i == y - scroll + then ( + let fill = String.make (max (size_x - String.length el) 0) ' ' in + I.strf "%s%s" ~attr:A.(st reverse) el fill |> I.pad ~l:0 ~t:i) + else I.strf "%s" el |> I.pad ~l:0 ~t:i + + +let rec render t ({ pos; scroll; content_pretty; _ } as state) = + let size_x, size_y = Common.Term.size t in + let x, y = pos in + let img = + let elements = + Array.mapi + (fun i el -> render_line size_x y scroll el i) + (* TODO: Fix this ugly slow conversion *) + (Array.to_seq content_pretty |> Seq.drop scroll |> Array.of_seq) + in + let open I in + Array.fold_left (fun sum el -> el sum) I.empty elements + in + Common.Term.image t img; + let content_length = Array.length content_pretty in + let scroll_up () = + let scroll = if y - scroll = 0 then max (scroll - 1) 0 else scroll in + render t @@ { state with pos = x, max (y - 1) 0; scroll } + in + let scroll_down () = + let scroll = if y - scroll >= size_y - 1 then scroll + 1 else scroll in + render t @@ { state with pos = x, min (y + 1) (content_length - 1); scroll } + in + match Common.Term.event t with + | `End | `Key (`Escape, []) | `Key (`ASCII 'q', []) | `Key (`ASCII 'C', [ `Ctrl ]) -> () + | `Mouse (`Press (`Scroll s), _, _) -> + (match s with + | `Down -> scroll_down () + | `Up -> scroll_up ()) + | `Resize _ -> render t state + | `Mouse ((`Press _ | `Drag), (_, y), _) -> + render t { state with pos = 0, min y content_length } + | `Key (`ASCII 'j', []) | `Key (`ASCII 'N', [ `Ctrl ]) -> scroll_down () + | `Key (`ASCII 'k', []) | `Key (`ASCII 'P', [ `Ctrl ]) -> scroll_up () + | `Key (`Arrow d, _) -> + (match d with + | `Up -> scroll_up () + | `Down -> scroll_down () + | _ -> render t state) + | _ -> render t state -- cgit v1.2.3