diff options
Diffstat (limited to '')
-rw-r--r-- | lib/headlines.ml | 84 |
1 files changed, 76 insertions, 8 deletions
diff --git a/lib/headlines.ml b/lib/headlines.ml index 4f905fd..654e389 100644 --- a/lib/headlines.ml +++ b/lib/headlines.ml @@ -12,6 +12,8 @@ type state = ; content_pretty : string array ; goto_todos_view : (unit -> unit) -> unit ; goto_done_view : (unit -> unit) -> unit + ; output : string option + ; tag : string } let init ~goto_done_view ~goto_todos_view ~regexp = @@ -27,7 +29,15 @@ let init ~goto_done_view ~goto_todos_view ~regexp = exit 0) else ( let content_pretty = content |> Grep.pretty_format in - { pos = 0, 2; scroll = 0; content; content_pretty; goto_done_view; goto_todos_view }) + { pos = 0, 2 + ; scroll = 0 + ; content + ; content_pretty + ; goto_done_view + ; goto_todos_view + ; output = None + ; tag = "" + }) let title = I.strf ~attr:A.(st bold) "%s" "Note View" |> I.pad ~l:0 ~t:0 @@ -35,12 +45,21 @@ let title = I.strf ~attr:A.(st bold) "%s" "Note View" |> I.pad ~l:0 ~t:0 (* TODO: Add page title *) let rec render t - ({ pos; scroll; content; content_pretty; goto_todos_view; goto_done_view } as state) + ({ pos; scroll; content; content_pretty; goto_todos_view; goto_done_view; tag; output } + as state) = let content_start = 2 in + let size_x, size_y = Common.Term.size t in let x, y = pos in let content_position = y - content_start in let img = + let output_info = + match output with + | Some line -> + I.strf "%s%s" (String.escaped line) (String.make size_x ' ') + |> I.pad ~t:(size_y - 1) + | None -> I.empty + in let dot = if Array.length content_pretty = 0 then I.empty @@ -54,18 +73,17 @@ let rec render (Array.to_seq content_pretty |> Seq.drop scroll |> Array.of_seq) in let open I in - Array.fold_left (fun sum el -> el </> sum) (title </> dot) elements + Array.fold_left (fun sum el -> sum </> el) (title </> dot </> output_info) elements in - let _, size_y = Common.Term.size t in Common.Term.image t img; let content_end = Array.length content_pretty + (content_start - 1) in let scroll_up () = let scroll = if y - content_start - scroll = 0 then max (scroll - 1) 0 else scroll in - render t { state with pos = x, max (y - 1) content_start; scroll } + render t { state with pos = x, max (y - 1) content_start; scroll; output = None } 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_end; scroll } + render t { state with pos = x, min (y + 1) content_end; scroll; output = None } in match Common.Term.event t with | `End | `Key (`Escape, []) | `Key (`ASCII 'q', []) | `Key (`ASCII 'C', [ `Ctrl ]) -> () @@ -75,7 +93,7 @@ let rec render | `Up -> scroll_up ()) | `Resize _ -> render t state | `Mouse ((`Press _ | `Drag), (_, y), _) -> - render t { state with pos = 0, min y content_end } + render t { state with pos = 0, min y content_end; output = None } | `Key (`ASCII '?', []) -> Help_screen.render t { go_back = (fun () -> render t state) } | `Key (`ASCII '2', []) -> goto_todos_view (fun () -> render t state) | `Key (`ASCII '3', []) -> goto_done_view (fun () -> render t state) @@ -112,7 +130,13 @@ let rec render Common.Term.cursor t None; render t - { state with content; content_pretty; pos = 0, content_start; scroll = 0 }) + { state with + content + ; content_pretty + ; pos = 0, content_start + ; scroll = 0 + ; tag + }) ; on_cancel = (fun _ -> Common.Term.cursor t None; @@ -127,6 +151,50 @@ let rec render | `Up -> scroll_up () | `Down -> scroll_down () | _ -> render t state) + | `Key (`ASCII '!', []) -> + let selected_file, _ = Array.get content content_position in + let selected_file = Grep.execution_directory ^ "/" ^ selected_file in + let content = + Array.map (fun (_, c) -> c) content |> Array.to_list |> String.concat "\n" + in + let (input_state : Input_prompt.state) = + { screen = img + ; user_input = "" + ; prompt = "COMMAND" + ; on_enter = + (fun command -> + if String.equal (String.trim command) String.empty + then ( + Common.Term.cursor t None; + render t state) + else + Arbitrary_command.run + t + ~command:(Scanf.unescaped command) + ~content + ~selected_file + ~on_return:(fun result -> + let content = + Grep.get_tagged_headlines tag () |> Grep.parse_headlines + in + let content_pretty = Grep.pretty_format content in + Common.Term.cursor t None; + render + t + { state with + content + ; content_pretty + ; pos = 0, content_start + ; scroll = 0 + ; output = Some result + })) + ; on_cancel = + (fun _ -> + Common.Term.cursor t None; + render t state) + } + in + Input_prompt.render t input_state | `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) = |