stitch

Note taking for messy minimalists

git clone git://mccd.space/stitch
commit fa2582d562118dc1ceccd01ede8d0d7e80d71a29
parent 613b17e9f30b4def18e014993576a4324d9b11a4
Author: Marc Coquand <marc@mccd.space>
Date:   Wed, 15 May 2024 15:06:49 -0500

Add basic file search

Diffstat:
Mlib/grep.ml | 14++++++++++++++
Mlib/headlines.ml | 1+
Mlib/stitched_article.ml | 55+++++++++++++++++++++++++++++++++++++++++++++++++++++--
3 files changed, 68 insertions(+), 2 deletions(-)
diff --git a/lib/grep.ml b/lib/grep.ml
@@ -256,6 +256,20 @@ let parse_full_content files =
        files
 
 
+let get_file_names tag =
+  let cmd =
+    let open Shexp_process in
+    let open Shexp_process.Infix in
+    find_sort_name ()
+    |- call [ "xargs"; grep_cmd; "-H"; "-r"; "-l"; "--no-messages"; "-E"; tag ]
+    |- call [ "sort"; "-n"; "-r" ]
+    |- read_all
+  in
+  Shexp_process.eval (Shexp_process.chdir execution_directory cmd)
+  |> String.split_on_char '\n'
+  |> List.filter (fun s -> not (String.equal "" s))
+
+
 type display_type =
   | Bold of string
   | Normal of string
diff --git a/lib/headlines.ml b/lib/headlines.ml
@@ -95,6 +95,7 @@ let rec render
       ; scroll = 0
       ; go_back = (fun () -> render t state)
       ; goto_todos_view
+      ; goto_done_view
       }
   | `Key (`ASCII 'r', []) ->
     let (input_state : Input_screen.state) =
diff --git a/lib/stitched_article.ml b/lib/stitched_article.ml
@@ -11,6 +11,7 @@ type state =
   ; go_back : unit -> unit
   ; content_pretty : Grep.display_type array
   ; goto_todos_view : (unit -> unit) -> unit
+  ; goto_done_view : (unit -> unit) -> unit
   }
 
 let title = I.strf ~attr:A.(st bold) "%s" "Note View" |> I.pad ~l:0 ~t:0
@@ -19,7 +20,8 @@ let content_start = 1
 (* TODO: Use grep -l to filter notes by regexp and rerender those files*)
 let rec render
   t
-  ({ pos; scroll; content_pretty; go_back; content; goto_todos_view } as state)
+  ({ pos; scroll; content_pretty; go_back; content; goto_todos_view; goto_done_view } as
+   state)
   =
   let size_x, size_y = Common.Term.size t in
   let x, y = pos in
@@ -55,8 +57,53 @@ let rec render
     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 (`ASCII 'r', []) ->
+    let (input_state : Input_screen.state) =
+      { screen = img
+      ; user_input = ""
+      ; prompt = "REGEXP: "
+      ; on_enter =
+          (fun tag ->
+            try
+              let content = Grep.get_file_names tag |> Array.of_list in
+              let oc = open_out "/tmp/stitch-output" in
+              Printf.fprintf oc "%s\n" (String.concat "\n" (content |> Array.to_list));
+              close_out oc;
+              let content =
+                Array.map
+                  (fun file_name -> Grep.get_full_file_content_content file_name)
+                  content
+                |> Array.to_list
+              in
+              let content = Grep.parse_full_content content in
+              let content_pretty =
+                Grep.pretty_print_parsed_content content |> Array.of_list
+              in
+              Common.Term.cursor t None;
+              render
+                t
+                { state with
+                  content = content |> Array.of_list
+                ; content_pretty
+                ; pos = 0, content_start
+                ; scroll = 0
+                }
+            with
+            | _ ->
+              let oc = open_out "/tmp/stitch-error" in
+              Printf.fprintf oc "%s\n" (Printexc.get_backtrace ());
+              close_out oc;
+              raise (Invalid_argument "FAILURE"))
+      ; on_cancel =
+          (fun _ ->
+            Common.Term.cursor t None;
+            render t state)
+      }
+    in
+    Input_screen.render t input_state
   | `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)
   | `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) =
@@ -89,7 +136,11 @@ let rec render
         render t state
       (* Capture resizing events *)
       | exception Unix.Unix_error (Unix.EINTR, _, _) -> run_editor ()
-      | exception Unix.Unix_error (_, _, _) -> failwith "ERROR"
+      | exception Unix.Unix_error (_, str_err, str_err_2) ->
+        let oc = open_out "/tmp/stitch-error" in
+        Printf.fprintf oc "%s: %s" str_err str_err_2;
+        close_out oc;
+        failwith "ERROR"
     in
     run_editor ()
   | `Key (`Arrow d, _) ->