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.

Added tab view and used selection better

+72 -18
+19 -14
jj_tui/bin/graph_view.ml
··· 75 75 , fun str -> 76 76 let curr_msg, prev_msg = get_messages () in 77 77 let new_msg = prev_msg ^ curr_msg in 78 - Dynamic_r(fun rev->Cmd [ "squash"; "--quiet"; "-m"; new_msg;"--from";rev; "--into"; str ] )) 78 + Dynamic_r 79 + (fun rev -> 80 + Cmd 81 + [ 82 + "squash" 83 + ; "--quiet" 84 + ; "-m" 85 + ; new_msg 86 + ; "--from" 87 + ; rev 88 + ; "--into" 89 + ; str 90 + ]) ) 79 91 } 80 92 ; { 81 93 key = 'u' ··· 246 258 |> Array.map (fun x -> 247 259 match x with 248 260 | `Selectable x -> 249 - let ui is_focused = 250 - (*hightlight blue when selection is true*) 251 - let prefix = 252 - if is_focused then I.char A.(bg A.blue) '>' 1 2 else I.char A.empty ' ' 1 2 253 - in 254 - I.hcat 255 - [ 256 - prefix 257 - ; x ^ "\n" 258 - (* TODO This won't work if we are on a branch, because that puts the @ further out*) 259 - |> Jj_tui.AnsiReverse.colored_string 260 - ] 261 - |> Ui.atom 261 + let ui = 262 + Wd.selectable_item 263 + (x ^ "\n" 264 + (* TODO This won't work if we are on a branch, because that puts the @ further out*) 265 + |> Jj_tui.AnsiReverse.colored_string 266 + |> Ui.atom) 262 267 in 263 268 let data = Wd.{ ui; data = rev_ids.(!selectable_idx) } in 264 269 selectable_idx := !selectable_idx + 1;
+5 -1
jj_tui/bin/jj_ui.ml
··· 158 158 | `RunCmd cmd -> 159 159 Jj_widgets.interactive_process env ("jj" :: cmd) 160 160 | `Main -> 161 - main_view ~sw) 161 + Wd.mouse_tabs 162 + [ 163 + ("main", fun _ -> main_view ~sw) 164 + ; ("other", fun _ -> W.string "they" |> Lwd.pure) 165 + ]) 162 166 | (`CantStartProcess | `NotInRepo | `OtherError _) as other -> 163 167 render_startup_error other 164 168 ;;
+6 -3
jj_tui/lib/widgets/selection_list.ml
··· 20 20 let selectable_item ui is_focused = 21 21 let height = Ui.layout_height ui in 22 22 let prefix = 23 - if is_focused then I.char A.(bg A.blue) '>' 1 height else I.char A.empty ' ' 1 height 23 + if is_focused 24 + then I.char A.(st bold++ bg (blue)) '>' 1 height 25 + else I.char A.empty ' ' 1 height 24 26 in 25 27 Ui.hcat [ prefix |> Ui.atom; ui ] 26 28 ;; 29 + 27 30 28 31 (** Selection list that allows for custom handling of keyboard events. 29 32 Scrolls when the selection reaches the lower third ··· 124 127 (* 125 128 The rough overview is: 126 129 1. Make a lookup list that has the indexes of all the selectable items within the overall list, we will be selecting from those 127 - 2. Render the items, making sure to tell the selected one to render as selected. 128 - 3. Calculate how much we should scroll by. 130 + 2. Render the items, making sure to tell the selected one to render as selected. 131 + 3. Calculate how much we should scroll by. 129 132 4. offset by the scroll amount, apply size sensors and output final ui 130 133 *) 131 134 let selected_var = Lwd.var 0 in
+42
jj_tui/lib/widgets/widgets.ml
··· 325 325 let is_focused ~focus f ui = 326 326 Lwd.map2 ui (focus |> Focus.status) ~f:(fun ui focus -> f ui (focus |> Focus.has_focus)) 327 327 ;; 328 + 329 + (** Gets an int that a char represents*) 330 + let char_to_int c = 331 + if c >= '0' && c <= '9' then Some (int_of_char c - int_of_char '0') else None 332 + ;; 333 + 334 + (** Tab view, where exactly one element of [l] is shown at a time. *) 335 + let mouse_tabs (tabs : (string * (unit -> Ui.t Lwd.t)) list) : Ui.t Lwd.t = 336 + match tabs with 337 + | [] -> 338 + Lwd.return Ui.empty 339 + | _ -> 340 + let cur = Lwd.var 0 in 341 + let$* idx_sel = Lwd.get cur in 342 + let _, f = List.nth tabs idx_sel in 343 + let tab_bar = 344 + tabs 345 + |> List.mapi (fun i (s, _) -> 346 + let attr = if i = idx_sel then A.(st underline) else A.empty in 347 + let tab_annot = W.printf ~attr "%s [%d]" s (i + 1) in 348 + tab_annot) 349 + |> Base.List.intersperse ~sep:(W.string " | ") 350 + |> Ui.hcat 351 + |> Ui.resize ~sw:1 ~mw:10000 352 + |> Lwd.pure 353 + |> border_box ~pad_w:1 ~pad_h:0 354 + in 355 + W.vbox [ tab_bar; f () ] 356 + |>$ Ui.keyboard_area (function 357 + | `ASCII key, _ -> 358 + key 359 + |> char_to_int 360 + |> Option.map (fun i -> 361 + if i >= 1 && i <= List.length tabs 362 + then ( 363 + cur $= i-1; 364 + `Handled) 365 + else `Unhandled) 366 + |> Option.value ~default:`Unhandled 367 + | _ -> 368 + `Unhandled) 369 + ;;