open Notty open Common let content = Stitch.get_headlines () |> Stitch.parse_headlines let content_pretty = content |> Stitch.pretty_format let rec main t (((x, y) as pos), scroll) = let img = let dot = I.string A.(fg black) ">" |> I.pad ~l:0 ~t:(y - scroll) and elements = Array.mapi (fun i el -> I.strf ~attr:A.(fg black) "%s" el |> I.pad ~l:2 ~t:i) (Array.to_seq content_pretty |> Seq.drop scroll |> Array.of_seq) in let open I in Array.fold_left (fun sum el -> el sum) dot elements in let _, size_y = Term.size t in 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 main t @@ ((x, max (y - 1) 0), scroll) in let scroll_down () = let scroll = if y - scroll >= size_y - 1 then scroll + 1 else scroll in main t @@ ((x, min (y + 1) content_length), scroll) in match 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 _ -> main t (pos, scroll) | `Mouse ((`Press _ | `Drag), (_, y), _) -> main t ((0, min y content_length), scroll) | `Key (`ASCII 'j', []) | `Key (`ASCII 'N', [ `Ctrl ]) -> scroll_down () | `Key (`ASCII 'k', []) | `Key (`ASCII 'P', [ `Ctrl ]) -> let scroll = if y - scroll = 0 then max (scroll - 1) 0 else scroll in main t @@ ((x, max (y - 1) 0), scroll) | `Key (`Arrow d, _) -> (match d with | `Up -> scroll_up () | `Down -> scroll_down () | _ -> main t ((x, y), scroll)) | `Key (`ASCII 'e', []) | `Key (`Enter, []) -> (* Editor might be set with extra args, in that case we need to separate these *) let[@warning "-8"] (editor :: args) = String.split_on_char ' ' (Sys.getenv "EDITOR") in let selected_file, _ = Array.get content y in let full_path_file = Stitch.execution_directory ^ "/" ^ selected_file in let full_args = Array.append (Array.of_list args) [| full_path_file |] in Term.cursor t (Some (0, 0)); let _ = Unix.create_process_env editor full_args (Unix.environment ()) Unix.stdin Unix.stdout Unix.stderr in let rec run_editor () = match Unix.wait () with | _, _ -> Term.cursor t None; main t ((x, y), scroll) (* Capture resizing events *) | exception Unix.Unix_error (Unix.EINTR, _, _) -> run_editor () | exception Unix.Unix_error (_, _, _) -> failwith "ERROR" in run_editor () | _ -> main t (pos, scroll) let () = main (Term.create ()) ((0, 0), 0)