From f805a04bd0600653f71e5e4e006104892cf7b6b9 Mon Sep 17 00:00:00 2001 From: Marc Coquand Date: Sat, 18 May 2024 13:19:26 -0500 Subject: Add run command to done; fix content bug --- lib/done.ml | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++------ lib/headlines.ml | 5 +---- lib/todos.ml | 5 +---- 3 files changed, 58 insertions(+), 14 deletions(-) diff --git a/lib/done.ml b/lib/done.ml index acec094..aaf819d 100644 --- a/lib/done.ml +++ b/lib/done.ml @@ -10,6 +10,8 @@ type state = ; content_pretty : string array ; goto_headlines : (unit -> unit) -> unit ; goto_todo : (unit -> unit) -> unit + ; tag : string + ; output : string option } let title = I.strf ~attr:A.(st bold) "%s" "Done View" |> I.pad ~l:0 ~t:0 @@ -24,6 +26,8 @@ let init ~goto_todo ~goto_headlines = ; content_pretty = content_pretty |> Array.of_list ; goto_headlines ; goto_todo + ; tag = "" + ; output = None } @@ -35,12 +39,19 @@ let load_done () = let rec render t - ({ pos; scroll; content; content_pretty; goto_headlines; goto_todo } as state) + ({ pos; scroll; content; content_pretty; goto_headlines; goto_todo; output; _ } as state) = let x, y = pos in + let size_x, size_y = Common.Term.size t in let content_position = y - content_start in let img = - let dot = + 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 + and dot = if Array.length content_pretty = 0 then I.empty else I.string A.(st bold) ">" |> I.pad ~l:0 ~t:(y - scroll) @@ -53,18 +64,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 -> el sum) (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 ]) -> () @@ -91,6 +101,7 @@ let rec render { state with content = content |> Array.of_list ; content_pretty = content_pretty |> Array.of_list + ; tag }) ; on_cancel = (fun _ -> @@ -111,6 +122,45 @@ let rec render ; content = content |> Array.of_list ; content_pretty = Array.of_list content_pretty } + | `Key (`ASCII '!', []) -> + let selected_file, content = Array.get content content_position in + let selected_file = Grep.execution_directory ^ "/" ^ selected_file 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, content_pretty = load_done () in + let y = min (List.length content_pretty + content_start) y in + Common.Term.cursor t None; + render + t + { state with + content = Array.of_list content + ; content_pretty = Array.of_list content_pretty + ; pos = 0, y + ; 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 'j', []) | `Key (`ASCII 'N', [ `Ctrl ]) -> scroll_down () | `Key (`ASCII 'k', []) | `Key (`ASCII 'P', [ `Ctrl ]) -> scroll_up () | `Key (`ASCII 'T', [ `Ctrl ]) -> diff --git a/lib/headlines.ml b/lib/headlines.ml index 654e389..915ba22 100644 --- a/lib/headlines.ml +++ b/lib/headlines.ml @@ -152,11 +152,8 @@ let rec render | `Down -> scroll_down () | _ -> render t state) | `Key (`ASCII '!', []) -> - let selected_file, _ = Array.get content content_position in + let selected_file, content = 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 = "" diff --git a/lib/todos.ml b/lib/todos.ml index bdbf877..6f8bef3 100644 --- a/lib/todos.ml +++ b/lib/todos.ml @@ -126,11 +126,8 @@ let rec render | `Key (`ASCII 'j', []) | `Key (`ASCII 'N', [ `Ctrl ]) -> scroll_down () | `Key (`ASCII 'k', []) | `Key (`ASCII 'P', [ `Ctrl ]) -> scroll_up () | `Key (`ASCII '!', []) -> - let selected_file, _ = Array.get content content_position in + let selected_file, content = 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 = "" -- cgit v1.2.3