terminal user interface to jujutsu. Focused on speed and clarity
9
fork

Configure Feed

Select the types of activity you want to include in your feed.

log stderr for interactive processes

+55 -24
+28 -4
jj_tui/bin/jj_process.ml
··· 13 13 (* this mutex should be global*) 14 14 let access_lock = Mutex.create () 15 15 16 + let read_fd_contents fd = 17 + let buffer_size = 4096 in 18 + let buffer = Bytes.create buffer_size in 19 + let output = Buffer.create buffer_size in 20 + let rec read_loop () = 21 + match Unix.read fd buffer 0 buffer_size with 22 + | 0 -> Buffer.contents output (* EOF reached *) 23 + | n -> 24 + Buffer.add_subbytes output buffer 0 n; 25 + read_loop () 26 + | exception Unix.Unix_error (Unix.EBADF, _, _) -> 27 + Buffer.contents output (* Handle EBADF error *) 28 + | exception Unix.Unix_error (Unix.EAGAIN, _, _) -> 29 + Unix.sleepf 0.01; (* Short sleep to avoid busy waiting *) 30 + read_loop () 31 + in 32 + read_loop () 33 + 16 34 module Make (Vars : Global_vars.Vars) = struct 17 35 (** Makes a new process that has acess to all input and output 18 36 This should be used for running other tui sub-programs *) 19 37 let switch_to_process command = 20 38 let stdout = Unix.stdout in 21 39 let stdin = Unix.stdin in 22 - let stderr = Unix.stderr in 23 - let pid = Unix.create_process command.(0) command stdin stdout stderr in 24 - let _, status = Unix.waitpid [] pid in 25 - status 40 + (* Create a pipe for stderr to capture it *) 41 + let stderr_r, stderr_w = Unix.pipe () in 42 + let pid = Unix.create_process command.(0) command stdin stdout stderr_w in 43 + (* Close write end in parent *) 44 + Unix.close stderr_w; 45 + let _, status = Unix.waitpid [] pid in 46 + (* Read stderr contents *) 47 + let stderr_content = read_fd_contents stderr_r in 48 + Unix.close stderr_r; 49 + status, stderr_content 26 50 ;; 27 51 28 52 (*
+27 -20
jj_tui/bin/jj_widgets.ml
··· 145 145 Global_funcs.update_status (); 146 146 Lwd.set ui_state.view new_view 147 147 in 148 - let exit_status_to_str (y : Unix.process_status) = 148 + let exit_status_to_str (y : Unix.process_status) stderr_string = 149 149 let open Unix in 150 150 match match y with WSTOPPED x -> x | WEXITED x -> x | WSIGNALED x -> x with 151 151 | 0 -> 152 - "success" 152 + None 153 153 | 1 -> 154 - "failure%s" 154 + Some (Printf.sprintf "1, Failure\nStderr:\n%s" stderr_string) 155 155 | a -> 156 - Printf.sprintf "unknown code %d" a 156 + Some (Printf.sprintf "unknown code %d\nStderr:\n%s" a stderr_string) 157 157 in 158 - let res = switch_to_process (cmd |> Array.of_list) in 159 - let$ ui = 160 - W.vbox 161 - [ 162 - W.string (Printf.sprintf "exit code:%s" (res |> exit_status_to_str)) |> Lwd.pure 163 - ; W.button "back to main UI" (fun _ -> post_change `Main) |> Lwd.pure 164 - ] 165 - in 166 - ui 167 - |> Ui.keyboard_area (fun event -> 168 - match event with 169 - | `ASCII ' ', _ -> 170 - post_change `Main; 171 - `Handled 172 - | _ -> 173 - `Unhandled) 158 + let exit_code, stderr_string = switch_to_process (cmd |> Array.of_list) in 159 + let error_msg = exit_status_to_str exit_code stderr_string in 160 + match error_msg with 161 + | None -> 162 + post_change `Main; 163 + Ui.empty |> Lwd.pure 164 + | Some exit_msg -> 165 + let$ ui = 166 + W.vbox 167 + [ 168 + W.string (Printf.sprintf "exit code: %s" exit_msg) |> Lwd.pure 169 + ; W.button "Press space to return to main UI" (fun _ -> post_change `Main) 170 + |> Lwd.pure 171 + ] 172 + in 173 + ui 174 + |> Ui.keyboard_area (fun event -> 175 + match event with 176 + | `Escape, _ | `Enter, _ | `ASCII ' ', _ -> 177 + post_change `Main; 178 + `Handled 179 + | _ -> 180 + `Unhandled) 174 181 ;; 175 182 end