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.

correctly detect and handle divergent changes

+72 -59
+11 -13
jj_tui/bin/global_vars.ml
··· 25 25 (* rev_id maybe_unique W.Overlay.filterable_selection_list_prompt_data option Lwd.var *) 26 26 ; show_string_selection_prompt : 27 27 string W.Overlay.filterable_selection_list_prompt_data option Lwd.var 28 - ; graph_revs : rev_id maybe_unique W.Lists.multi_selectable_item array Lwd.var 28 + ; graph_revs : string maybe_unique W.Lists.multi_selectable_item array Lwd.var 29 29 ; command_log : string list Lwd.var 30 30 ; jj_show : I.t Lwd.var 31 31 ; jj_show_promise : unit Promise.t ref 32 32 ; jj_branches : I.t Lwd.var 33 33 ; jj_change_files : (string * string) list Lwd.var 34 - ; hovered_revision : rev_id maybe_unique Lwd.var 35 - ; selected_revisions : rev_id maybe_unique list Lwd.var 34 + ; hovered_revision : string maybe_unique Lwd.var 35 + ; selected_revisions : string maybe_unique list Lwd.var 36 36 ; revset : string option Lwd.var 37 37 ; trigger_update : unit Lwd.var 38 38 ; reset_selection : unit Signal.t ··· 42 42 43 43 let get_unique_id maybe_unique_rev = 44 44 match maybe_unique_rev with 45 - | Unique { change_id; _ } -> 46 - change_id 47 - | Duplicate { commit_id; _ } -> 48 - commit_id 45 + | Unique s -> 46 + s 47 + | Duplicate s -> 48 + s 49 49 ;; 50 50 51 51 (** Global variables for the ui. Here we keep anything that's just a pain to pipe around*) ··· 69 69 val get_active_revs_lwd : unit -> string list Lwd.t 70 70 val config : Config.t Lwd.var 71 71 val show_popup : (Nottui.ui Lwd.t * string) option -> unit 72 - 73 - 74 - 75 72 val set_loading : string option -> unit 76 73 end 77 74 ··· 85 82 ; jj_show_promise = ref @@ Promise.of_value () 86 83 ; jj_branches = Lwd.var I.empty 87 84 ; jj_change_files = Lwd.var [] 88 - ; hovered_revision = Lwd.var (Unique { change_id = "@"; commit_id = "@" }) 89 - ; selected_revisions = Lwd.var [ Unique { change_id = "@"; commit_id = "@" } ] 85 + ; hovered_revision = 86 + Lwd.var (Unique "@") 87 + ; selected_revisions = 88 + Lwd.var [ Unique "@"; ] 90 89 ; revset = Lwd.var None 91 90 ; graph_revs = Lwd.var [||] 92 91 ; input = Lwd.var `Normal ··· 146 145 then [ hovered |> get_unique_id ] 147 146 else selected |> List.map get_unique_id 148 147 ;; 149 - 150 148 151 149 let show_popup popup = 152 150 [%log debug "setting show popup"];
+2
jj_tui/lib/process.ml
··· 1 1 type rev_id = { 2 2 change_id : string 3 3 ; commit_id : string 4 + 5 + ; divergent : bool(** Indicates the changeid is conflicted and we must use the commitid *) 4 6 } 5 7 6 8 type 'a maybe_unique =
+59 -46
jj_tui/lib/process_wrappers.ml
··· 11 11 exception FoundStart 12 12 exception FoundFiller 13 13 14 - (** Function to tag duplicated items in a list *) 15 - let tag_duplicates lst = 16 - (* Create a frequency map to count occurrences of each element *) 17 - let freq_map = 18 - List.fold_left 19 - (fun acc { change_id; _ } -> 20 - let count = try List.assoc change_id acc with Not_found -> 0 in 21 - (change_id, count + 1) :: List.remove_assoc change_id acc) 22 - [] 23 - lst 24 - in 25 - (* Tag each item in the list based on the frequency map *) 26 - List.map 27 - (fun ({ change_id; _ } as x) -> 28 - if List.assoc change_id freq_map > 1 then Duplicate x else Unique x) 29 - lst 30 - ;; 31 - 32 14 (** Matches any basic ansi escape codes*) 33 15 let ansi_regex = 34 16 let open Re in ··· 48 30 in 49 31 Re.compile pattern 50 32 ;; 33 + 51 34 (** Removes any found ansi escape codes*) 52 35 let remove_ansi str = str |> Re.replace_string ~by:"" ansi_regex 36 + 53 37 let count_ansi str = str |> Re.all ansi_regex |> List.length 54 38 55 39 let find_selectable_from_graph str = 56 - 57 - (** Matches a single revision in the format specificied by the graph template *) 40 + (* Matches a single revision in the format specificied by the graph template *) 58 41 let matches = 59 42 str 60 43 |> Re.split_full 61 44 (Re.Pcre.regexp 62 45 ~flags:[ Re.Pcre.(`MULTILINE) ] 63 - {|(^.*?)\$\$--START--\$\$\|(.+?)\|(.+?)\|([\s\S]*?)\$\$--END--\$\$\n?|}) 46 + {|(^.*?)\$\$--START--\$\$\|(.+?)\|(.+?)\|(.+?)\|(.+?)\|([\s\S]*?)\$\$--END--\$\$\n?|}) 64 47 in 65 48 let graph, ids = 66 49 matches 67 50 |> List.fold_left 68 51 (fun (graph_acc, ids_acc) chunk -> 69 - match chunk with 70 - | `Delim selectable -> 71 - let graph_bit = Re.Group.get selectable 1 in 72 - (* In future we should be able to use the strifify function in ocaml*) 73 - let change_id = Re.Group.get selectable 2 |> remove_ansi in 74 - let commit_id = Re.Group.get selectable 3 |> remove_ansi in 75 - let content = Re.Group.get selectable 4 in 76 - ( `Selectable (graph_bit ^ content) :: graph_acc 77 - , { change_id; commit_id } :: ids_acc ) 78 - | `Text filler -> (*Anything between our match is non-selectable filler*) 79 - if filler = "" 80 - then 81 - graph_acc, ids_acc 82 - else `Filler filler :: graph_acc, ids_acc) 52 + match chunk with 53 + | `Delim selectable -> 54 + let graph_bit = Re.Group.get selectable 1 in 55 + (* In future we should be able to use the strifify function in ocaml*) 56 + let change_id = Re.Group.get selectable 2 |> remove_ansi in 57 + let commit_id = Re.Group.get selectable 3 |> remove_ansi in 58 + let divergent = 59 + match Re.Group.get selectable 4 |> remove_ansi with 60 + | "true" -> 61 + true 62 + | "false" -> 63 + false 64 + | content -> 65 + failwith @@ "Couldn't parse jj divergent value:" ^ content 66 + in 67 + let hidden = 68 + match Re.Group.get selectable 5 |> remove_ansi with 69 + | "true" -> 70 + true 71 + | "false" -> 72 + false 73 + | content -> 74 + failwith @@ "Couldn't parse jj divergent value:" ^ content 75 + in 76 + [%log 77 + debug 78 + "parsed rev: change_id: %s commit_id: %s divergent: %s" 79 + change_id 80 + commit_id 81 + (Re.Group.get selectable 6 |> remove_ansi)]; 82 + let rev = { commit_id; change_id; divergent } in 83 + let id = if divergent || hidden then Duplicate commit_id else Unique change_id in 84 + let content = Re.Group.get selectable 6 in 85 + `Selectable (graph_bit ^ content) :: graph_acc, id :: ids_acc 86 + | `Text filler -> 87 + (*Anything between our match is non-selectable filler*) 88 + if filler = "" 89 + then graph_acc, ids_acc 90 + else `Filler filler :: graph_acc, ids_acc) 83 91 ([], []) 84 92 |> fun (graph, ids) -> List.rev graph |> Array.of_list, List.rev ids 85 93 in 86 - let revs = ids |> tag_duplicates in 94 + let revs = ids in 87 95 graph, revs 88 96 ;; 89 97 ··· 97 105 end) = 98 106 struct 99 107 open Process 100 - (* Currently hard-coded. Soon it'l be settable in config *) 108 + 109 + (* Currently hard-coded. Soon it'l be settable in config *) 101 110 let base_graph_template = 102 111 {|if(root, 103 112 format_root_commit(self), ··· 115 124 ) 116 125 )|} 117 126 ;; 118 - 119 - let graph_info_template node_template= 120 - {|"$$--START--$$"++"|"++change_id++"|"++commit_id++"|"++|} 127 + 128 + let graph_info_template node_template = 129 + {|"$$--START--$$"++"|"++change_id++"|"++commit_id++"|"++divergent++"|"++hidden++"|"++|} 121 130 ^ node_template 122 131 ^ {|++"$$--END--$$"++""|} 123 132 ;; 124 133 125 134 let get_graph_info node_template revset_arg = 126 - let output = jj_no_log ([ "log"; "-T"; graph_info_template node_template] @ revset_arg) in 135 + let output = 136 + jj_no_log ([ "log"; "-T"; graph_info_template node_template ] @ revset_arg) 137 + in 127 138 output |> find_selectable_from_graph 128 139 ;; 129 140 ··· 142 153 end 143 154 144 155 (*========Tests======*) 145 - 146 156 147 157 let test_data_3 = 148 158 {|@ $$--START--$$|zqtxnkuuryqzzolyksrylpzotmplmvus|8ee443e4a374f7dfdd00494d8bf71af6162a1300|zqtxnkuu eli.jambu@gmail.com 2025-02-15 21:22:48 8ee443e4 ··· 203 213 let id = ids.(!ids_idx) in 204 214 (match id with 205 215 | Unique id -> 206 - id.change_id |> print_endline; 207 - id.commit_id |> print_endline 216 + (* id.change_id |> print_endline; *) 217 + (* id.commit_id |> print_endline *) 218 + id|>print_endline 208 219 | Duplicate id -> 209 - id.change_id |> print_endline; 210 - id.commit_id |> print_endline); 220 + (* id.change_id |> print_endline; *) 221 + (* id.commit_id |> print_endline); *) 222 + id|>print_endline 223 + ); 211 224 incr ids_idx; 212 225 x |> print_endline); 213 226 [%expect