···55let colored_string = Jj_tui.AnsiReverse.colored_string
6677let on_change () =
88- let res = jj_no_log [ "show" ] |> colored_string in
88+ let res = jj_no_log [ "show"; "-s"; "--color-words"] |> colored_string in
99 Vars.ui_state.jj_show $= res;
1010- let res = jj_no_log [] |> colored_string in
1111- Vars.ui_state.jj_tree $= res
1010+ let res = jj_no_log ["log"] |> colored_string in
1111+ Vars.ui_state.jj_tree $= res;
1212+ (* TODO: stop using dop last twice *)
1313+ let res =
1414+ jj_no_log [ "branch";"list"; "-a"]|>colored_string
1515+ in
1616+ Vars.ui_state.jj_branches $= res
1217;;
···3232 Notty.I.void term_width term_height |> Nottui.Ui.atom
3333 ;;
34343535-3635 (* let vQuit = Lwd.var false *)
37363837 let _quitButton =
···4645 let ( << ) f g x = f (g x)
47464847 (* let ( let<- ) v f = Lwd.map ~f (Lwd.get v) *)
4949-50485149 let post_change new_view =
5250 on_change ();
···6361 handle
6462 in
6563 ui
6666- |> Ui.keyboard_area@@ fun event ->
6464+ |> Ui.keyboard_area @@ fun event ->
6765 match event with
6868- | (`ASCII 'q', _) ->
6666+ | `ASCII 'q', _ ->
6967 Vars.quit $= true;
7068 `Handled
7171- | (`ASCII key, _) ->
6969+ | `ASCII key, _ ->
7270 (match handler key with
7371 | `Handled ->
7472 on_change ();
7573 `Handled
7674 | `Unhandled ->
7775 `Unhandled)
7878- | (`Escape, _) ->
7676+ | `Escape, _ ->
7977 (*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 *)
8078 (match input_state with
8179 | `Mode _ ->
···111109 ui
112110 |> Ui.keyboard_area (fun event ->
113111 match event with
114114- |(`ASCII ' ', _) ->
112112+ | `ASCII ' ', _ ->
115113 post_change `Main;
116114 `Handled
117115 | _ ->
···133131 full_term_sized_background
134132 | `RunCmd cmd ->
135133 interactive_process env ("jj" :: cmd)
136136- | (`Main ) ->
134134+ | `Main ->
137135 let v_cmd_out = Lwd.var "" in
138138- let scrollState = Lwd.var W.default_scroll_state in
139136 let$* pane =
140137 W.h_pane
141138 (W.vbox
142139 [
143143- ui_state.jj_tree $-> (I.pad ~l:1 ~r:1 >> Ui.atom);
144144- W.string "━━━━━━━━━━━━━━━━━━" |> Lwd.pure;
145145- ui_state.command_log
146146- |> Lwd.get
147147- |> Lwd.bind ~f:(List.map (W.string >> Lwd.pure) >> W.vlist);
140140+141141+ Widgets.scrollable(ui_state.jj_tree $-> (I.pad ~l:1 ~r:1 >> Ui.atom))
142142+ |>$ Ui.resize ~sh:3;
143143+ Widgets.h_rule
144144+ |> Lwd.pure;
145145+ Widgets.scrollable (ui_state.jj_branches $-> Ui.atom) |>$ Ui.resize ~sh:1;
146146+ Widgets.h_rule
147147+ |> Lwd.pure;
148148+ Widgets.scrollable
149149+ (ui_state.command_log
150150+ |> Lwd.get
151151+ |> Lwd.bind ~f:(List.map (W.string >> Lwd.pure) >> W.vlist))
152152+ |>$ Ui.resize ~sh:1;
148153 v_cmd_out $-> W.string;
149154 ])
150150- (W.vscroll_area
151151- ~change:(fun _action state -> scrollState $= state)
152152- ~state:(Lwd.get scrollState)
155155+ (Widgets.scrollable
153156 ((fun x -> x |> I.pad ~l:1 ~r:1 |> Ui.atom) <-$ ui_state.jj_show))
154157 |> Widgets.general_prompt ~char_count:true ~show_prompt_var:ui_state.show_prompt
155158 |> Widgets.popup ~show_popup_var:ui_state.show_popup
+12
jj_tui/bin/widgets.ml
···271271 let prompt = general_prompt ~show_prompt_var ui in
272272 W.h_pane prompt (W.string "other side" |> Lwd.pure)
273273;;
274274+275275+(** horizontal rule, has no width by default but is very very wide so it should fill any space*)
276276+let h_rule=
277277+ W.string
278278+ "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"|>Ui.resize ~w:0 ~sw:100
279279+let scrollable ui =
280280+ let scrollState = Lwd.var W.default_scroll_state in
281281+ W.vscroll_area
282282+ ~change:(fun _action state -> scrollState $= state)
283283+ ~state:(Lwd.get scrollState)
284284+ ui
285285+;;
+7-3
notty/src/notty.ml
···90909191 let is_empty t = width t = 0
92929393- let graphemes str =
9393+ let graphemes ?(should_throw=false) str =
9494 let module Uuseg = Notty_grapheme_cluster in
9595 let seg = Uuseg.create () in
9696 let rec f (is, w as acc) i evt =
···100100 | `Boundary ->
101101 let is = match w with 0 -> is | 1 -> i::is | _ -> i::(-1)::is in
102102 f (is, 0) i `Await in
103103- let acc = Uutf.String.fold_utf_8 (fun acc i -> function
104104- | `Malformed err -> err_malformed err str
103103+ let acc = Uutf.String.fold_utf_8(fun acc i -> function
104104+ | `Malformed err ->
105105+ if should_throw then
106106+ err_malformed err str
107107+ else
108108+ f acc i (`Uchar (Uchar.of_int 0xffd ))
105109 | `Uchar _ as u -> f acc i u
106110 ) ([0], 0) str in
107111 f acc (String.length str) `End |> fst |> List.rev |> Array.of_list (*XXX*)