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.

ui improvements

+49 -23
+8 -3
jj_tui/bin/global_funcs.ml
··· 5 5 let colored_string = Jj_tui.AnsiReverse.colored_string 6 6 7 7 let on_change () = 8 - let res = jj_no_log [ "show" ] |> colored_string in 8 + let res = jj_no_log [ "show"; "-s"; "--color-words"] |> colored_string in 9 9 Vars.ui_state.jj_show $= res; 10 - let res = jj_no_log [] |> colored_string in 11 - Vars.ui_state.jj_tree $= res 10 + let res = jj_no_log ["log"] |> colored_string in 11 + Vars.ui_state.jj_tree $= res; 12 + (* TODO: stop using dop last twice *) 13 + let res = 14 + jj_no_log [ "branch";"list"; "-a"]|>colored_string 15 + in 16 + Vars.ui_state.jj_branches $= res 12 17 ;;
+2
jj_tui/bin/global_vars.ml
··· 19 19 command_log : string list Lwd.var; 20 20 jj_tree : I.t Lwd.var; 21 21 jj_show : I.t Lwd.var; 22 + jj_branches : I.t Lwd.var; 22 23 } 23 24 24 25 (** Global variables for the ui*) ··· 41 42 view = Lwd.var `Main; 42 43 jj_tree = Lwd.var I.empty; 43 44 jj_show = Lwd.var I.empty; 45 + jj_branches = Lwd.var I.empty; 44 46 input = Lwd.var `Normal; 45 47 show_popup = Lwd.var None; 46 48 show_prompt = Lwd.var None;
+20 -17
jj_tui/bin/jj_ui.ml
··· 32 32 Notty.I.void term_width term_height |> Nottui.Ui.atom 33 33 ;; 34 34 35 - 36 35 (* let vQuit = Lwd.var false *) 37 36 38 37 let _quitButton = ··· 46 45 let ( << ) f g x = f (g x) 47 46 48 47 (* let ( let<- ) v f = Lwd.map ~f (Lwd.get v) *) 49 - 50 48 51 49 let post_change new_view = 52 50 on_change (); ··· 63 61 handle 64 62 in 65 63 ui 66 - |> Ui.keyboard_area@@ fun event -> 64 + |> Ui.keyboard_area @@ fun event -> 67 65 match event with 68 - | (`ASCII 'q', _) -> 66 + | `ASCII 'q', _ -> 69 67 Vars.quit $= true; 70 68 `Handled 71 - | (`ASCII key, _) -> 69 + | `ASCII key, _ -> 72 70 (match handler key with 73 71 | `Handled -> 74 72 on_change (); 75 73 `Handled 76 74 | `Unhandled -> 77 75 `Unhandled) 78 - | (`Escape, _) -> 76 + | `Escape, _ -> 79 77 (*TODO: I could refactor this and the rest of the mode handling so that when the popup is up and in focus it handles all key inputs *) 80 78 (match input_state with 81 79 | `Mode _ -> ··· 111 109 ui 112 110 |> Ui.keyboard_area (fun event -> 113 111 match event with 114 - |(`ASCII ' ', _) -> 112 + | `ASCII ' ', _ -> 115 113 post_change `Main; 116 114 `Handled 117 115 | _ -> ··· 133 131 full_term_sized_background 134 132 | `RunCmd cmd -> 135 133 interactive_process env ("jj" :: cmd) 136 - | (`Main ) -> 134 + | `Main -> 137 135 let v_cmd_out = Lwd.var "" in 138 - let scrollState = Lwd.var W.default_scroll_state in 139 136 let$* pane = 140 137 W.h_pane 141 138 (W.vbox 142 139 [ 143 - ui_state.jj_tree $-> (I.pad ~l:1 ~r:1 >> Ui.atom); 144 - W.string "━━━━━━━━━━━━━━━━━━" |> Lwd.pure; 145 - ui_state.command_log 146 - |> Lwd.get 147 - |> Lwd.bind ~f:(List.map (W.string >> Lwd.pure) >> W.vlist); 140 + 141 + Widgets.scrollable(ui_state.jj_tree $-> (I.pad ~l:1 ~r:1 >> Ui.atom)) 142 + |>$ Ui.resize ~sh:3; 143 + Widgets.h_rule 144 + |> Lwd.pure; 145 + Widgets.scrollable (ui_state.jj_branches $-> Ui.atom) |>$ Ui.resize ~sh:1; 146 + Widgets.h_rule 147 + |> Lwd.pure; 148 + Widgets.scrollable 149 + (ui_state.command_log 150 + |> Lwd.get 151 + |> Lwd.bind ~f:(List.map (W.string >> Lwd.pure) >> W.vlist)) 152 + |>$ Ui.resize ~sh:1; 148 153 v_cmd_out $-> W.string; 149 154 ]) 150 - (W.vscroll_area 151 - ~change:(fun _action state -> scrollState $= state) 152 - ~state:(Lwd.get scrollState) 155 + (Widgets.scrollable 153 156 ((fun x -> x |> I.pad ~l:1 ~r:1 |> Ui.atom) <-$ ui_state.jj_show)) 154 157 |> Widgets.general_prompt ~char_count:true ~show_prompt_var:ui_state.show_prompt 155 158 |> Widgets.popup ~show_popup_var:ui_state.show_popup
+12
jj_tui/bin/widgets.ml
··· 271 271 let prompt = general_prompt ~show_prompt_var ui in 272 272 W.h_pane prompt (W.string "other side" |> Lwd.pure) 273 273 ;; 274 + 275 + (** horizontal rule, has no width by default but is very very wide so it should fill any space*) 276 + let h_rule= 277 + W.string 278 + "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"|>Ui.resize ~w:0 ~sw:100 279 + let scrollable ui = 280 + let scrollState = Lwd.var W.default_scroll_state in 281 + W.vscroll_area 282 + ~change:(fun _action state -> scrollState $= state) 283 + ~state:(Lwd.get scrollState) 284 + ui 285 + ;;
+7 -3
notty/src/notty.ml
··· 90 90 91 91 let is_empty t = width t = 0 92 92 93 - let graphemes str = 93 + let graphemes ?(should_throw=false) str = 94 94 let module Uuseg = Notty_grapheme_cluster in 95 95 let seg = Uuseg.create () in 96 96 let rec f (is, w as acc) i evt = ··· 100 100 | `Boundary -> 101 101 let is = match w with 0 -> is | 1 -> i::is | _ -> i::(-1)::is in 102 102 f (is, 0) i `Await in 103 - let acc = Uutf.String.fold_utf_8 (fun acc i -> function 104 - | `Malformed err -> err_malformed err str 103 + let acc = Uutf.String.fold_utf_8(fun acc i -> function 104 + | `Malformed err -> 105 + if should_throw then 106 + err_malformed err str 107 + else 108 + f acc i (`Uchar (Uchar.of_int 0xffd )) 105 109 | `Uchar _ as u -> f acc i u 106 110 ) ([0], 0) str in 107 111 f acc (String.length str) `End |> fst |> List.rev |> Array.of_list (*XXX*)