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.

cleanup process wrappers code

+40 -230
+13 -230
jj_tui/lib/process_wrappers.ml
··· 11 11 exception FoundStart 12 12 exception FoundFiller 13 13 14 - let make_uchar str = 15 - let a = String.get_utf_8_uchar str 0 in 16 - if a |> Uchar.utf_decode_is_valid 17 - then a |> Uchar.utf_decode_uchar 18 - else failwith "not a unicode string" 19 - ;; 20 - 21 - let elieded_symbol = make_uchar "◌" 22 - let elieded_symbol_alt = make_uchar "○" 23 - let rev_symbol = make_uchar "◉" 24 - let merge_symbol = make_uchar "◆" 25 - 26 - let is_whitespace_char (code_point : int) : bool = 27 - match code_point with 28 - | 0x0009 (* Tab *) 29 - | 0x000A (* Line Feed *) 30 - | 0x000B (* Vertical Tab *) 31 - | 0x000C (* Form Feed *) 32 - | 0x000D (* Carriage Return *) 33 - | 0x0020 (* Space *) 34 - | 0x0085 (* Next Line *) 35 - | 0x00A0 (* No-Break Space *) 36 - | 0x1680 (* Ogham Space Mark *) 37 - | 0x2000 (* En Quad *) 38 - | 0x2001 (* Em Quad *) 39 - | 0x2002 (* En Space *) 40 - | 0x2003 (* Em Space *) 41 - | 0x2004 (* Three-Per-Em Space *) 42 - | 0x2005 (* Four-Per-Em Space *) 43 - | 0x2006 (* Six-Per-Em Space *) 44 - | 0x2007 (* Figure Space *) 45 - | 0x2008 (* Punctuation Space *) 46 - | 0x2009 (* Thin Space *) 47 - | 0x200A (* Hair Space *) 48 - | 0x2028 (* Line Separator *) 49 - | 0x2029 (* Paragraph Separator *) 50 - | 0x202F (* Narrow No-Brpeak Space *) 51 - | 0x205F (* Medium Mathematical Space *) 52 - | 0x3000 (* Ideographic Space *) -> 53 - true 54 - | _ -> 55 - false 56 - ;; 57 - 58 - let is_graph_start_char char = 59 - let i = Uchar.to_int char in 60 - (*chars like these: ├─╮*) 61 - let is_pipe = i > 0x2500 && i < 0x259f in 62 - let is_whitespace = is_whitespace_char i in 63 - is_pipe || is_whitespace 64 - ;; 65 - 66 - let rec list_to_pairs lst = 67 - match lst with 68 - | [] | [ _ ] -> 69 - [] (* If list is empty or has only one element, return empty list *) 70 - | x :: y :: rest -> 71 - (x, y) :: list_to_pairs rest 72 - ;; 73 - 74 - let rec pairwise f ~f_last lst = 75 - match lst with 76 - | [ single ] -> 77 - f_last single 78 - | x :: y :: rest -> 79 - ((x, y) |> f) :: pairwise f ~f_last rest 80 - | [] -> 81 - [] (* If list is empty or has only one element, return empty list *) 82 - ;; 83 - 84 - (* 85 - 1. Make the graph 86 - *) 87 14 (** Function to tag duplicated items in a list *) 88 15 let tag_duplicates lst = 89 16 (* Create a frequency map to count occurrences of each element *) ··· 102 29 lst 103 30 ;; 104 31 105 - (* 106 - let ansi_regex = 107 - let open Re in 108 - let csi_start = alt [ char '\x1B'; char '\x9B' ] in (* ESC or CSI *) 109 - let intermediates = rep (set "[]()#;?") in 110 - let params = rep (seq [ char ';'; rep1 (set "-a-zA-Z0-9/#&.:=?%@~_") ]) in 111 - let csi_terminator = alt [ 112 - char '\x07'; (* BEL *) 113 - seq [ char '\x1B'; char '\\' ]; (* ESC \ *) 114 - char '\x9C' (* ST *) 115 - ] in 116 - let csi_sequence = seq [ 117 - csi_start; 118 - intermediates; 119 - opt (alt [ 120 - seq [ params; csi_terminator ]; 121 - seq [ rep1 (rg 'a' 'z'); opt params; csi_terminator ] 122 - ]) 123 - ] in 124 - let param_sequence = seq [ 125 - rep (seq [ rg '0' '9'; rep (seq [ char ';'; rep (rg '0' '9') ]) ]); 126 - alt [ 127 - set "A-PR-TZ"; (* Cursor movements and scroll regions *) 128 - set "cf-nq-uy"; (* Tab stops and erasure *) 129 - set "=><~" (* Keypad and editing modes *) 130 - ] 131 - ] in 132 - Re.compile (alt [ 133 - csi_sequence; 134 - param_sequence 135 - ]) 136 - let ansi_regex = 137 - let open Re in 138 - let st = alt [ str "\x07"; str "\x1B\\"; str "\x9C" ] in 139 - let pattern = 140 - alt [ 141 - (* CSI escape sequence pattern *) 142 - seq [ 143 - set "\x1B\x9B"; 144 - rep (set "[]()#;?"); 145 - opt (alt [ 146 - rep (seq [ char ';'; rep1 (set "a-zA-Z0-9/#&.:=?%@~_-") ]); 147 - seq [ 148 - rep1 (set "a-zA-Z0-9"); 149 - rep (seq [ char ';'; rep (set "a-zA-Z0-9/#&.:=?%@~_-") ]) 150 - ] 151 - ]); 152 - st; 153 - ]; 154 - 155 - (* OSC escape sequence pattern *) 156 - seq [ 157 - opt (seq [ repn digit 1 (Some 4); rep (seq [ char ';'; repn digit 0 (Some 4) ]) ]); 158 - set "0-9A-PR-TZcf-nq-uy=><~"; 159 - ] 160 - ] 161 - in 162 - Re.compile pattern *) 32 + (** Matches any basic ansi escape codes*) 163 33 let ansi_regex = 164 34 let open Re in 165 35 let pattern = ··· 178 48 in 179 49 Re.compile pattern 180 50 ;; 181 - 51 + (** Removes any found ansi escape codes*) 182 52 let remove_ansi str = str |> Re.replace_string ~by:"" ansi_regex 183 53 let count_ansi str = str |> Re.all ansi_regex |> List.length 184 54 185 55 let find_selectable_from_graph str = 56 + 57 + (** Matches a single revision in the format specificied by the graph template *) 186 58 let matches = 187 59 str 188 60 |> Re.split_full ··· 190 62 ~flags:[ Re.Pcre.(`MULTILINE) ] 191 63 {|(^.*?)\$\$--START--\$\$\|(.+?)\|(.+?)\|([\s\S]*?)\$\$--END--\$\$\n?|}) 192 64 in 193 - (*if there are no matches it's all filler*) 194 - (* let count = matches |> List.length in *) 195 65 let graph, ids = 196 66 matches 197 67 |> List.fold_left ··· 199 69 match chunk with 200 70 | `Delim selectable -> 201 71 let graph_bit = Re.Group.get selectable 1 in 72 + (* In future we should be able to use the strifify function in ocaml*) 202 73 let change_id = Re.Group.get selectable 2 |> remove_ansi in 203 74 let commit_id = Re.Group.get selectable 3 |> remove_ansi in 204 75 let content = Re.Group.get selectable 4 in 205 76 ( `Selectable (graph_bit ^ content) :: graph_acc 206 77 , { change_id; commit_id } :: ids_acc ) 207 - | `Text filler -> 78 + | `Text filler -> (*Anything between our match is non-selectable filler*) 208 79 if filler = "" 209 80 then 210 81 graph_acc, ids_acc ··· 216 87 graph, revs 217 88 ;; 218 89 219 - (** retrieve revs from jj log of jj_tui*) 220 - let revs_from_log log = 221 - log 222 - |> String.split_on_char '\n' 223 - |> List.filter_map (fun x -> 224 - let items = x |> String.split_on_char '|' in 225 - match items with 226 - | [ _graph; change_id; commit_id ] -> 227 - Some { change_id; commit_id } 228 - | _ -> 229 - None) 230 - |> tag_duplicates 231 - |> Array.of_list 232 - ;; 233 - 234 90 module Make (Process : sig 235 91 val jj_no_log : 236 92 ?get_stderr:bool ··· 241 97 end) = 242 98 struct 243 99 open Process 244 - 100 + (* Currently hard-coded. Soon it'l be settable in config *) 245 101 let base_graph_template = 246 102 {|if(root, 247 103 format_root_commit(self), ··· 259 115 ) 260 116 )|} 261 117 ;; 262 - 263 - let graph_info_template = 118 + 119 + let graph_info_template node_template= 264 120 {|"$$--START--$$"++"|"++change_id++"|"++commit_id++"|"++|} 265 - ^ base_graph_template 121 + ^ node_template 266 122 ^ {|++"$$--END--$$"++""|} 267 123 ;; 268 124 269 - let get_graph_info revset_arg = 270 - let output = jj_no_log ([ "log"; "-T"; graph_info_template ] @ revset_arg) in 125 + let get_graph_info node_template revset_arg = 126 + let output = jj_no_log ([ "log"; "-T"; graph_info_template node_template] @ revset_arg) in 271 127 output |> find_selectable_from_graph 272 128 ;; 273 129 274 - (**Returns a list of revs with both the change_id and commit_id*) 275 - let get_revs ?revset () = 276 - let revset_arg = match revset with Some revset -> [ "-r"; revset ] | None -> [] in 277 - jj_no_log 278 - ~color:false 279 - ([ "log"; "-T"; {|"|"++change_id++"|"++commit_id++"\n"|} ] @ revset_arg) 280 - |> revs_from_log 281 - ;; 282 - 283 - (* let test= *) 284 - (* let count,graph=find_selectable_from_graph root_test *) 285 - (* in *) 286 - (* if count<=0 then failwith "no process root" *) 287 - (* ;; *) 288 - let graph_view_template = {|""|} 289 - 290 130 (** returns the graph and a list of revs within that graph*) 291 131 let graph_and_revs ?revset () = 292 132 (*We join_after here to ensure any errors in sub-fibers only propegate to here, otherwise fibers everywhere would get cancelled when an error here occurs*) ··· 294 134 let graph = 295 135 Flock.fork_as_promise @@ fun () -> 296 136 let revset_arg = match revset with Some revset -> [ "-r"; revset ] | None -> [] in 297 - get_graph_info revset_arg 137 + get_graph_info base_graph_template revset_arg 298 138 in 299 139 let graph, revs = Promise.await graph in 300 - (*The graph should never have selectable items that don't also have a rev*) 301 - (* if not (Array.length graph = List.length revs) then 302 - failwith @@ Printf.sprintf "graph and revs length mismatch %d %d" (Array.length graph) (List.length revs) 303 - else *) 304 140 graph, revs |> Array.of_list 305 141 ;; 306 142 end 307 143 308 144 (*========Tests======*) 309 145 310 - let test_data = 311 - {|◉ yzquvpvl eli.jambu@gmail.com 2024-05-23 15:04:24 3565237c 312 - ├─╮ merger 313 - ◉ │ wttqrrwo eli.jambu@gmail.com 2024-05-23 14:36:43 ui-update* 7e46fdef 314 - │ │ border_box working 315 - │ │ ◉ skwqmzmt eli.jambu@gmail.com 2024-05-25 01:07:57 7e358c79 316 - │ ├─╯ test old size scaling 317 - │ ◉ nuptyuws eli.jambu@gmail.com 2024-05-22 18:58:31 master 7b156964 318 - │ │ Update README.md 319 - │ ◌ (elided revisions) 320 - │ │ ◉ kmslutyl eli.jambu@gmail.com 2024-05-22 18:07:36 7b10ea4f conflict 321 - │ │ │ (no description set) 322 - │ │ ◉ nqyzyups eli.jambu@gmail.com 2024-05-22 18:07:36 519c664f conflict 323 - │ ├─╯ progress 324 - │ ◉ tutrxvzs eli.jambu@gmail.com 2024-05-22 18:07:36 af8620df 325 - │ │ flakes working 326 - │ ◌ (elided revisions) 327 - │ │ ◉ vlkxvssz eli.jambu@gmail.com 2024-05-15 19:40:28 79fb16f1 328 - │ ├─╯ (no description set) 329 - │ ◉ vtkpsqlr eli.jambu@gmail.com 2024-05-15 16:44:09 1974cc7d 330 - │ │ switch to pkgsStatic 331 - │ ◌ (elided revisions) 332 - │ │ ◉ zpvnoqkm eli.jambu@gmail.com 2024-05-15 09:47:41 c9f95816 333 - ├───╯ (no description set) 334 - ◉ │ unspmqrw eli.jambu@gmail.com 2024-05-15 09:47:41 83aafe3c 335 - ├─╯ update to nottui 336 - │ ◉ smvuxtrv eli.jambu@gmail.com 2024-05-15 09:47:41 d0ce4665 337 - ├─╯ (empty) bup 338 - ◉ yqytskyk eli.jambu@gmail.com 2024-05-15 09:47:41 0a89ce77 339 - │ test reorganise 340 - ◌ (elided revisions) 341 - │ ◉ qpqzkuss eli.jambu@gmail.com 2024-05-15 09:46:18 fdd16b26 conflict 342 - │ │ (no description set) 343 - │ ◉ xpqmtrmp eli.jambu@gmail.com 2024-05-15 09:46:18 555a5355 344 - ├─╯ remove old nix file 345 - ◉ zxpskuop eli.jambu@gmail.com 2024-05-15 09:46:18 dac0f8bb 346 - │ Update README.md|} 347 - ;; 348 - 349 - let root_test = {|◆ zzzzzzzz root() 00000000|} 350 - 351 - let test_data_2 = 352 - {|@ qpnrvwyl ethanboxx 13 seconds ago 48829167 353 - │ (no description set) 354 - ◆ pqvkrmkw ethanboxx 3 months ago main v0.1.10 HEAD@git 931019c4 355 - │ (empty) Merge pull request #63 from eopb/release-plz-2024-05-11T09-14-47Z 356 - ~ (elided revisions) 357 - │ ○ xnyvmlur ethanboxx 5 months ago push-znvwmrtqnnlq 0deaa0aa 358 - ├─┘ feat: impl `Deref` and `DerefMut` without exposing `Secret` 359 - ◆ kkzuqwxo ethanboxx 5 months ago 9aa340cc 360 - │ (empty) Merge pull request #56 from eopb/push-smksztlxprww 361 - ~|} 362 - ;; 363 146 364 147 let test_data_3 = 365 148 {|@ $$--START--$$|zqtxnkuuryqzzolyksrylpzotmplmvus|8ee443e4a374f7dfdd00494d8bf71af6162a1300|zqtxnkuu eli.jambu@gmail.com 2025-02-15 21:22:48 8ee443e4
+27
jj_tui/lib/util.ml
··· 46 46 strings |> List.filter (Base.String.is_empty >> not) |> String.concat sep 47 47 ;; 48 48 end 49 + (** convinience method to take a str and turn it into a unicode char*) 50 + let make_uchar str = 51 + let a = String.get_utf_8_uchar str 0 in 52 + if a |> Uchar.utf_decode_is_valid 53 + then a |> Uchar.utf_decode_uchar 54 + else failwith "not a unicode string" 55 + ;; 56 + 57 + (** Takes a list and pair all elements we can*) 58 + let rec list_to_pairs lst = 59 + match lst with 60 + | [] | [ _ ] -> 61 + [] (* If list is empty or has only one element, return empty list *) 62 + | x :: y :: rest -> 63 + (x, y) :: list_to_pairs rest 64 + ;; 65 + (** Iterate over a list in pairs. f_last handles if there is a last elemment that doesn't have a pair*) 66 + let rec pairwise f ~f_last lst = 67 + match lst with 68 + | [ single ] -> 69 + f_last single 70 + | x :: y :: rest -> 71 + ((x, y) |> f) :: pairwise f ~f_last rest 72 + | [] -> 73 + [] (* If list is empty or has only one element, return empty list *) 74 + ;; 75 +