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.

Errors for bad startup states

+85 -36
+3 -1
README.md
··· 2 2 [![nix](https://github.com/faldor20/jj_tui/actions/workflows/build-nix.yml/badge.svg)](https://github.com/faldor20/jj_tui/actions/workflows/build-nix.yml) 3 3 A TUI for the new version control system Jujutsu 4 4 5 - ![screenshot](./screenshot.jpg) 5 + 6 + ![jj_tui-ezgif com-optimize](https://github.com/faldor20/jj_tui/assets/26968035/fb053320-484a-4d6f-9b66-e5b9d0d49e5d) 7 + 6 8 7 9 Press `h` to show the help. 8 10 Press `Alt+Up`and`Alt+Down` to navigate windows
+13 -2
jj_tui/bin/global_funcs.ml
··· 20 20 the start ") 21 21 else None) 22 22 ;; 23 - let is_jj_repo() = 24 - jj_no_log ~color:false [ "log";"''" ] |> Base.String.is_substring ~substring:"There is no jj repo"|>not 23 + 24 + let check_startup () = 25 + match jj_no_log_errorable ~color:false [ "log"; "''" ] with 26 + | Ok _ -> 27 + `Good 28 + | Error (`BadExit (i, str)) -> 29 + if str |> Base.String.is_substring ~substring:"There is no jj repo" 30 + then `NotInRepo 31 + else `OtherError str 32 + | Error (`EioErr a) -> 33 + `CantStartProcess 34 + ;; 35 + 25 36 (**Updates the status windows; Without snapshotting the working copy by default 26 37 This should be called after any command that performs a change *) 27 38 let update_status ?(cause_snapshot = false) () =
+32 -9
jj_tui/bin/jj_process.ml
··· 30 30 ~f:(fun x -> 31 31 (match x.exit_status with 32 32 | `Exited i -> 33 - if i == 0 then x.stdout else x.stdout ^ x.stderr 34 - | `Signaled _ -> 35 - x.stderr) 33 + if i == 0 then `Ok x.stdout else `BadExit (i, x.stderr) 34 + | `Signaled i -> 35 + `BadExit (i, x.stderr)) 36 36 |> Base.Or_error.return) 37 37 () 38 38 in 39 - out |> Result.to_option |> Option.value ~default:"there was an error" 39 + match out with 40 + | Error a -> 41 + Error (`EioErr a) 42 + | Ok (`Ok a) -> 43 + Ok a 44 + | Ok (`BadExit _ as a) -> 45 + Error a 40 46 ;; 41 47 42 48 (** Prevents concurrent acess to jj when running commands that cause snapshotting. ··· 47 53 @param ?snapshot=true 48 54 When true snapshots the state when running the command and also aquires a lock before running it. Set to false for commands you wish to run concurrently. like those for generating content in the UI 49 55 @param ?color=true When true output will have terminal escape codes for color *) 50 - let jj_no_log ?(snapshot = true) ?(color = true) args = 56 + let jj_no_log_errorable ?(snapshot = true) ?(color = true) args = 51 57 let locked = 52 58 if snapshot 53 59 then ( ··· 69 75 res 70 76 ;; 71 77 78 + (** Run a jj command without outputting to the command_log. 79 + @param ?snapshot=true 80 + When true snapshots the state when running the command and also aquires a lock before running it. Set to false for commands you wish to run concurrently. like those for generating content in the UI 81 + @param ?color=true When true output will have terminal escape codes for color *) 82 + let jj_no_log ?(snapshot = true) ?(color = true) args = 83 + match jj_no_log_errorable ~snapshot ~color args with 84 + | Ok a -> 85 + a 86 + | Error (`BadExit (code, str)) -> 87 + failwith (Printf.sprintf "Exited with code %i; Message:\n%s" code str) 88 + | Error (`EioErr a) -> 89 + failwith 90 + (Printf.sprintf 91 + "Error running jj process:\n%a" 92 + (fun _ -> Base.Error.to_string_hum) 93 + a) 94 + ;; 95 + 72 96 let jj args = 73 97 (*update the command log*) 74 98 let current_log = Lwd.peek Vars.ui_state.command_log in ··· 80 104 81 105 (**gets the description of the current and previous change. Useful when squashing*) 82 106 let get_messages () = 107 + let open Base.Result in 83 108 let output = 84 109 jj 85 110 [ ··· 88 113 ; "-T" 89 114 ; {|"::"++current_working_copy++"::\n"++description++"\n::end::\n"|} 90 115 ] 91 - |> String.trim 116 + |>String.trim 92 117 in 93 - let current, prev = 94 - output |> Jj_tui.OutputParsing.parse_descriptions |> Result.get_ok 95 - in 118 + let current, prev = output |>Jj_tui.OutputParsing.parse_descriptions|>Result.get_ok in 96 119 current |> String.concat "", prev |> String.concat "" 97 120 ;; 98 121 end
+37 -24
jj_tui/bin/jj_ui.ml
··· 56 56 `Unhandled 57 57 ;; 58 58 59 + (* shows a pretty box in the middle of the screen with our error in it*) 60 + let render_startup_error error = 61 + let message = 62 + match error with 63 + | `NotInRepo -> 64 + "Not in a jj repo." 65 + | `OtherError str -> 66 + str 67 + | `CantStartProcess -> 68 + "Can't start jj process, maybe it's not installed?" 69 + in 70 + W.string message 71 + |> Lwd.pure 72 + |> Wd.border_box 73 + |>$ Ui.resize 74 + ~sw:1 75 + ~sh:1 76 + ~mw:10000 77 + ~mh:10000 78 + ~crop:Wd.neutral_grav 79 + ~pad:Wd.neutral_grav 80 + |> inputs 81 + ;; 82 + 59 83 (** The primary view for the UI with the file_view graph_view and summary*) 60 84 let main_view ~sw = 61 85 let file_focus = Focus.make () in ··· 107 131 108 132 let mainUi ~sw env = 109 133 (*we want to initialize our states and keep them up to date*) 110 - let is_jj_repo = is_jj_repo () in 111 - if not is_jj_repo 112 - then 113 - W.string "Not in a jj repo." 114 - |> Lwd.pure 115 - |> Wd.border_box 116 - |>$ Ui.resize 117 - ~sw:1 118 - ~sh:1 119 - ~mw:10000 120 - ~mh:10000 121 - ~crop:Wd.neutral_grav 122 - ~pad:Wd.neutral_grav 123 - |> inputs 124 - else ( 134 + match check_startup () with 135 + | `Good -> 125 136 update_status ~cause_snapshot:true (); 126 137 Eio.Fiber.fork_daemon ~sw (fun _ -> 127 138 let clock = Eio.Stdenv.clock env in ··· 134 145 done; 135 146 `Stop_daemon); 136 147 let$* running = Lwd.get ui_state.view in 137 - match running with 138 - | `Cmd_I cmd -> 139 - (*We have this extra step to paint the terminal empty for one step*) 140 - Lwd.set ui_state.view @@ `RunCmd cmd; 141 - full_term_sized_background 142 - | `RunCmd cmd -> 143 - Jj_widgets.interactive_process env ("jj" :: cmd) 144 - | `Main -> 145 - main_view ~sw) 148 + (match running with 149 + | `Cmd_I cmd -> 150 + (*We have this extra step to paint the terminal empty for one step*) 151 + Lwd.set ui_state.view @@ `RunCmd cmd; 152 + full_term_sized_background 153 + | `RunCmd cmd -> 154 + Jj_widgets.interactive_process env ("jj" :: cmd) 155 + | `Main -> 156 + main_view ~sw) 157 + | (`CantStartProcess | `NotInRepo | `OtherError _) as other -> 158 + render_startup_error other 146 159 ;; 147 160 end