stitch

Note taking for messy minimalists

git clone git://mccd.space/stitch
commit 5618ab3a4109a0f962b8554d497d6400406b7b4b
parent 9938ba49842b622800513c1a0e3c58d6439ee0f2
Author: Marc Coquand <marc@mccd.space>
Date:   Sun, 19 May 2024 15:13:55 -0500

Arbitrary command supports all shell scripts, also those that open editor

Diffstat:
Mlib/arbitrary_command.ml | 43+++++++++++++++++++++++++++++++++----------
1 file changed, 33 insertions(+), 10 deletions(-)
diff --git a/lib/arbitrary_command.ml b/lib/arbitrary_command.ml
@@ -1,30 +1,53 @@
 module Grep = Grep
 
+let extract_env env =
+  env
+  |> Array.to_list
+  |> List.map (fun env_var ->
+    let result = Str.bounded_split (Str.regexp "=") env_var 2 in
+    match result with
+    | [ a; b ] -> a, b
+    | [ a ] -> a, ""
+    | _ -> failwith ("Could not split the environment variables: " ^ env_var))
+
+
 let run ~(on_return : string -> unit) t ~selected_file ~content ~command =
-  let command = String.split_on_char ' ' command in
   (* Substitute after splitting to more easily deal with file names that have spaces *)
   let command =
-    command
-    |> List.map (fun s ->
-      let s = Str.global_replace (Str.regexp "%(file)") selected_file s in
-      Str.global_replace (Str.regexp "%(line)") content s)
+    let s = Str.global_replace (Str.regexp "%(file)") selected_file command in
+    Str.global_replace (Str.regexp "%(line)") content s
   in
+  let shell = Sys.getenv "SHELL" in
+  let command = List.concat [ [ shell; "-c"; command ] ] in
   Common.Term.cursor t (Some (0, 0));
   try
-    let result =
+    let exit_code =
       let open Shexp_process in
-      let open Shexp_process.Infix in
-      eval (chdir Grep.execution_directory (call command |- read_all))
+      let context =
+        Context.create
+          ~stdin:Unix.stdin
+          ~stdout:Unix.stdout
+          ~stderr:Unix.stderr
+          ~unix_env:(Unix.environment () |> extract_env)
+          ()
+      in
+      let result =
+        eval ~context (chdir Grep.execution_directory (call_exit_code command))
+      in
+      Context.dispose context;
+      result
     in
     Common.Term.cursor t None;
-    on_return result
+    on_return ("Command exited with code " ^ Int.to_string exit_code)
   with
   | exn ->
     let oc = open_out "/tmp/stitch-error" in
+    let environment = String.concat "," (Unix.environment () |> Array.to_list) in
     let commands_result = String.concat " " command in
     Printf.fprintf
       oc
-      "%s\n%s\n%s\n%s\n"
+      "%s\n%s\n%s\n%s\n%s\n"
+      environment
       selected_file
       commands_result
       (Printexc.to_string exn)