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.

ensure sorting order is correct

+182 -91
+107 -78
jj_tui/bin/file_commands.ml
··· 13 13 open Jj_tui 14 14 15 15 (* Define all file commands *) 16 - let get_command_registry active_files get_commands = [ 17 - { 18 - id = "show_help"; 19 - description = "Show help"; 20 - make_cmd = (fun () -> Fun (fun _ -> 21 - ui_state.show_popup 22 - $= Some (commands_list_ui ~include_arrows:true (get_commands()), "Help"); 23 - ui_state.input $= `Mode (fun _ -> `Unhandled))) 24 - }; 25 - { 26 - id = "move_to_rev"; 27 - description = "Move file to other commit"; 28 - make_cmd = (fun () -> 29 - PromptThen ( 30 - "Revision to move file to", 31 - fun rev -> 32 - Cmd ( 33 - ["squash"; "-u"; "--keep-emptied"; "--from"; get_hovered_rev (); "--into"; rev] 34 - @ Lwd.peek active_files 35 - ) 36 - ) 37 - ) 38 - }; 39 - { 40 - id = "move_to_child"; 41 - description = "Move file to child commit"; 42 - make_cmd = (fun () -> 43 - Dynamic_r (fun rev -> 44 - Cmd ( 45 - ["squash"; "-u"; "--keep-emptied"; "--from"; rev; "--into"; rev ^ "+"] 46 - @ Lwd.peek active_files 47 - ) 48 - ) 49 - ) 50 - }; 51 - { 52 - id = "move_to_parent"; 53 - description = "Move file to parent commit"; 54 - make_cmd = (fun () -> 55 - Dynamic_r (fun rev -> 56 - Cmd ( 57 - ["squash"; "-u"; "--keep-emptied"; "--from"; rev; "--into"; rev ^ "-"] 58 - @ Lwd.peek active_files 59 - ) 60 - ) 61 - ) 62 - }; 63 - { 64 - id = "discard"; 65 - description = "Restore to previous revision (git discard)"; 66 - make_cmd = (fun () -> 67 - Dynamic_r (fun rev -> 68 - let selected = Lwd.peek active_files in 69 - confirm_prompt 70 - ("discard all changes to:\n" 71 - ^ (selected |> String.concat "\n") 72 - ^ "\nin rev " 73 - ^ rev) 74 - (Cmd (["restore"; "--to"; rev; "--from"; rev ^ "-"] @ selected)) 75 - ) 76 - ) 77 - }; 78 - { 79 - id = "absorb"; 80 - description = "Absorb changes from index to working copy"; 81 - make_cmd = (fun () -> 82 - Dynamic_r (fun rev -> 83 - let selected = Lwd.peek active_files in 84 - confirm_prompt 85 - ("absorb all changes to:\n" 86 - ^ (selected |> String.concat "\n") 87 - ^ "\nin rev " 88 - ^ rev) 89 - (Cmd (["absorb"; "--from";rev] @ selected)) 90 - ) 91 - ) 92 - }; 93 - ]|>List.to_seq|>Seq.map (fun x -> x.id,x)|>Hashtbl.of_seq 16 + let get_command_registry active_files get_commands = 17 + [ { 18 + id = "show_help" 19 + ; description = "Show help" 20 + ; sorting_key = 0.0 21 + ; make_cmd = 22 + (fun () -> 23 + Fun 24 + (fun _ -> 25 + ui_state.show_popup 26 + $= Some (commands_list_ui ~include_arrows:true (get_commands ()), "Help"); 27 + ui_state.input $= `Mode (fun _ -> `Unhandled))) 28 + } 29 + ; { 30 + id = "move_to_rev" 31 + ; description = "Move file to other commit" 32 + ; sorting_key = 1.0 33 + ; make_cmd = 34 + (fun () -> 35 + PromptThen 36 + ( "Revision to move file to" 37 + , fun rev -> 38 + Cmd 39 + ( [ "squash" 40 + ; "-u" 41 + ; "--keep-emptied" 42 + ; "--from" 43 + ; get_hovered_rev () 44 + ; "--into" 45 + ; rev 46 + ] 47 + @ Lwd.peek active_files ) )) 48 + } 49 + ; { 50 + id = "move_to_child" 51 + ; description = "Move file to child commit" 52 + ; sorting_key = 2.0 53 + ; make_cmd = 54 + (fun () -> 55 + Dynamic_r 56 + (fun rev -> 57 + Cmd 58 + ( [ "squash" 59 + ; "-u" 60 + ; "--keep-emptied" 61 + ; "--from" 62 + ; rev 63 + ; "--into" 64 + ; rev ^ "+" 65 + ] 66 + @ Lwd.peek active_files ))) 67 + } 68 + ; { 69 + id = "move_to_parent" 70 + ; description = "Move file to parent commit" 71 + ; sorting_key = 3.0 72 + ; make_cmd = 73 + (fun () -> 74 + Dynamic_r 75 + (fun rev -> 76 + Cmd 77 + ( [ "squash" 78 + ; "-u" 79 + ; "--keep-emptied" 80 + ; "--from" 81 + ; rev 82 + ; "--into" 83 + ; rev ^ "-" 84 + ] 85 + @ Lwd.peek active_files ))) 86 + } 87 + ; { 88 + id = "abandon" 89 + ; description = "Restore to previous revision (git discard)" 90 + ; sorting_key = 4.0 91 + ; make_cmd = 92 + (fun () -> 93 + Dynamic_r 94 + (fun rev -> 95 + let selected = Lwd.peek active_files in 96 + confirm_prompt 97 + ("abandon all changes to:\n" 98 + ^ (selected |> String.concat "\n") 99 + ^ "\nin rev " 100 + ^ rev) 101 + (Cmd (["restore"; "--to"; rev; "--from"; rev ^ "-"] @ selected)))) 102 + } 103 + ; { 104 + id = "absorb" 105 + ; description = "Absorb changes from index to working copy" 106 + ; sorting_key = 5.0 107 + ; make_cmd = 108 + (fun () -> 109 + Dynamic_r 110 + (fun rev -> 111 + let selected = Lwd.peek active_files in 112 + confirm_prompt 113 + ("absorb all changes to:\n" 114 + ^ (selected |> String.concat "\n") 115 + ^ "\nin rev " 116 + ^ rev) 117 + (Cmd (["absorb"; "--from"; rev] @ selected)))) 118 + } 119 + ] 120 + |> List.to_seq 121 + |> Seq.map (fun x -> x.id, x) 122 + |> Hashtbl.of_seq 94 123 end
+40 -1
jj_tui/bin/graph_commands.ml
··· 36 36 { 37 37 id = "show_help" 38 38 ; description = "Show help" 39 + ; sorting_key = 0.0 39 40 ; make_cmd = 40 41 (fun () -> 41 42 Fun ··· 46 47 } 47 48 ; { 48 49 id = "prev" 50 + ; sorting_key = 1.0 49 51 ; description = "Move the working copy to the previous child" 50 52 ; make_cmd = (fun () -> Cmd [ "prev" ]) 51 53 } 52 54 ; { 53 55 id = "new_base" 56 + ; sorting_key = 2.0 54 57 ; description = "Make new child commit" 55 58 ; make_cmd = (fun () -> Cmd_with_revs (Active [ "new" ])) 56 59 } 57 60 ; { 58 61 id = "new_no_edit" 62 + ; sorting_key = 3.0 59 63 ; description = "Same as 'new', but without editing the new commit" 60 64 ; make_cmd = (fun () -> Cmd_with_revs (Active [ "new"; "--no-edit" ])) 61 65 } 62 66 ; { 63 67 id = "new_inline" 68 + ; sorting_key = 4.0 64 69 ; description = "Make a new change and insert it after the selected rev" 65 70 ; make_cmd = 66 71 (fun () -> ··· 69 74 } 70 75 ; { 71 76 id = "new_inline_no_edit" 77 + ; sorting_key = 5.0 72 78 ; description = "Same as 'new insert', but without editing the new commit" 73 79 ; make_cmd = 74 80 (fun () -> ··· 78 84 } 79 85 ; { 80 86 id = "duplicate" 87 + ; sorting_key = 6.0 81 88 ; description = "Duplicate the current selected commits " 82 89 ; make_cmd = 83 90 (fun () -> Dynamic (fun () -> Cmd ([ "duplicate" ] @ Vars.get_active_revs ()))) 84 91 } 85 92 ; { 86 93 id = "undo" 94 + ; sorting_key = 7.0 87 95 ; description = "Undo the last operation" 88 96 ; make_cmd = (fun () -> Cmd [ "undo" ]) 89 97 } 90 98 ; { 91 99 id = "commit_base" 100 + ; sorting_key = 8.0 92 101 ; description = 93 102 "Describe this change and start working on a new rev (same as `describe` then \ 94 103 `new`)" ··· 98 107 } 99 108 ; { 100 109 id = "commit_no_edit" 110 + ; sorting_key = 9.0 101 111 ; description = "Same as commit but without editing the new commit" 102 112 ; make_cmd = 103 113 (fun () -> ··· 106 116 } 107 117 ; { 108 118 id = "split" 119 + ; sorting_key = 10.0 109 120 ; description = "Split the current commit interacively" 110 121 ; make_cmd = (fun () -> Dynamic_r (fun rev -> Cmd_I [ "split"; "-r"; rev; "-i" ])) 111 122 } 112 123 ; { 113 124 id = "squash_into_parent" 125 + ; sorting_key = 11.0 114 126 ; description = "Squash into parent" 115 127 ; make_cmd = 116 128 (fun () -> ··· 123 135 } 124 136 ; { 125 137 id = "squash_into_rev" 138 + ; sorting_key = 12.0 126 139 ; description = "Squash into any commit" 127 140 ; make_cmd = 128 141 (fun () -> ··· 149 162 } 150 163 ; { 151 164 id = "squash_unsquash" 165 + ; sorting_key = 13.0 152 166 ; description = "Interactivaly unsquash" 153 167 ; make_cmd = 154 168 (fun () -> Dynamic_r (fun rev -> Cmd_I [ "unsquash"; "-r"; rev; "-i" ])) 155 169 } 156 170 ; { 157 171 id = "squash_interactive_parent" 172 + ; sorting_key = 14.0 158 173 ; description = "Interactively choose what to squash into parent" 159 174 ; make_cmd = (fun () -> Dynamic_r (fun rev -> Cmd_I [ "squash"; "-r"; rev; "-i" ])) 160 175 } 161 176 ; { 162 177 id = "squash_interactive_rev" 178 + ; sorting_key = 15.0 163 179 ; description = "Interactively choose what to squash into a commit" 164 180 ; make_cmd = 165 181 (fun () -> ··· 169 185 } 170 186 ; { 171 187 id = "edit" 188 + ; sorting_key = 16.0 172 189 ; description = "Edit the selected revision" 173 190 ; make_cmd = (fun () -> Dynamic_r (fun rev -> Cmd [ "edit"; rev ])) 174 191 } 175 192 ; { 176 193 id = "describe" 194 + ; sorting_key = 17.0 177 195 ; description = "Describe this revision" 178 196 ; make_cmd = 179 197 (fun () -> ··· 181 199 } 182 200 ; { 183 201 id = "describe_editor" 202 + ; sorting_key = 18.0 184 203 ; description = "Describe this revision using an editor" 185 204 ; make_cmd = (fun () -> Dynamic_r (fun rev -> Cmd_I [ "describe"; "-r"; rev ])) 186 205 } 187 206 ; { 188 207 id = "resolve" 208 + ; sorting_key = 19.0 189 209 ; description = "Resolve conflicts at this revision" 190 210 ; make_cmd = (fun () -> Dynamic_r (fun rev -> Cmd_I [ "resolve"; "-r"; rev ])) 191 211 } 192 212 ; { 193 213 id = "rebase_single" 214 + ; sorting_key = 20.0 194 215 ; description = "Rebase single revision " 195 216 ; make_cmd = 196 217 (fun () -> ··· 199 220 } 200 221 ; { 201 222 id = "rebase_with_descendants" 223 + ; sorting_key = 21.0 202 224 ; description = "Rebase revision and its decendents" 203 225 ; make_cmd = 204 226 (fun () -> ··· 210 232 } 211 233 ; { 212 234 id = "rebase_with_bookmark" 235 + ; sorting_key = 22.0 213 236 ; description = "Rebase revision and all other revissions on its bookmark" 214 237 ; make_cmd = 215 238 (fun () -> ··· 220 243 } 221 244 ; { 222 245 id = "git_push" 246 + ; sorting_key = 23.0 223 247 ; description = "git push" 224 248 ; make_cmd = 225 249 (fun () -> ··· 230 254 [ 231 255 { 232 256 key = Key.key_of_string_exn "y" 257 + ; sort_key = 0.0 233 258 ; description = "proceed" 234 259 ; cmd = 235 260 Cmd ··· 238 263 } 239 264 ; { 240 265 key = Key.key_of_string_exn "n" 266 + ; sort_key = 1.0 241 267 ; description = "exit" 242 268 ; cmd = 243 269 Fun ··· 264 290 } 265 291 ; { 266 292 id = "git_fetch" 293 + ; sorting_key = 24.0 267 294 ; description = "git fetch" 268 295 ; make_cmd = (fun () -> Cmd [ "git"; "fetch" ]) 269 296 } 270 297 ; { 271 298 id = "git_fetch_all" 299 + ; sorting_key = 25.0 272 300 ; description = "git fetch all remotes" 273 301 ; make_cmd = (fun () -> Cmd [ "git"; "fetch"; "--all-remotes" ]) 274 302 } 275 303 ; { 276 304 id = "parallelize" 305 + ; sorting_key = 26.0 277 306 ; description = 278 307 "Parallelize commits. Takes 2 commits and makes them have the\n\ 279 308 same parent and child. Run `jj parallelize` --help for details" ··· 285 314 } 286 315 ; { 287 316 id = "abandon" 317 + ; sorting_key = 27.0 288 318 ; description = "Abandon this change(removes just this change and rebases parents)" 289 319 ; make_cmd = 290 320 (fun () -> ··· 297 327 } 298 328 ; { 299 329 id = "bookmark_create" 330 + ; sorting_key = 28.0 300 331 ; description = "Create new bookmark" 301 332 ; make_cmd = 302 333 (fun () -> ··· 309 340 } 310 341 ; { 311 342 id = "bookmark_delete" 343 + ; sorting_key = 29.0 312 344 ; description = "Delete bookmark" 313 345 ; make_cmd = 314 346 (fun () -> ··· 325 357 } 326 358 ; { 327 359 id = "bookmark_forget" 360 + ; sorting_key = 30.0 328 361 ; description = "Forget bookmark" 329 362 ; make_cmd = 330 363 (fun () -> ··· 341 374 } 342 375 ; { 343 376 id = "bookmark_rename" 377 + ; sorting_key = 31.0 344 378 ; description = "Rename bookmark" 345 379 ; make_cmd = 346 380 (fun () -> ··· 352 386 } 353 387 ; { 354 388 id = "bookmark_set" 389 + ; sorting_key = 32.0 355 390 ; description = "Set bookmark to this change" 356 391 ; make_cmd = 357 392 (fun () -> ··· 365 400 } 366 401 ; { 367 402 id = "bookmark_track" 403 + ; sorting_key = 33.0 368 404 ; description = "track given remote bookmark" 369 405 ; make_cmd = 370 406 (fun () -> ··· 375 411 } 376 412 ; { 377 413 id = "bookmark_untrack" 414 + ; sorting_key = 34.0 378 415 ; description = "untrack given remote bookmark" 379 416 ; make_cmd = 380 417 (fun () -> ··· 385 422 } 386 423 ; { 387 424 id = "filter" 425 + ; sorting_key = 35.0 388 426 ; description = "Filter using revset" 389 427 ; make_cmd = 390 428 (fun () -> ··· 399 437 } 400 438 ; { 401 439 id = "absorb" 440 + ; sorting_key = 36.0 402 441 ; description = 403 442 "Absorb: Move changes of each file in this commit into the closest mutable \ 404 443 parent that modified that file" ··· 409 448 |> Seq.map (fun x -> x.id, x) 410 449 |> Hashtbl.of_seq 411 450 ;; 412 - end 451 + end
+32 -11
jj_tui/bin/jj_commands.ml
··· 49 49 (** A command that should be run when it's key is pressed*) 50 50 and 'a command = { 51 51 key : Key.t 52 + ; sort_key : float 52 53 ; description : string 53 54 ; cmd : 'a command_variant 54 55 } ··· 57 58 (* Common type for command definition registry *) 58 59 type 'a command_definition = { 59 60 id : string 61 + ; sorting_key : float 60 62 ; description : string 61 63 ; make_cmd : unit -> 'a command_variant 62 64 } ··· 109 111 let rec render_commands ?(indent_level = 0) commands = 110 112 commands 111 113 |> Key_Map.to_list 112 - |> List.concat_map @@ fun (key,command) -> 114 + |> List.sort_uniq (fun (_, a) (_, b) -> Float.compare a.sort_key b.sort_key) 115 + |> List.concat_map @@ fun (key, command) -> 113 116 match command with 114 117 | { 115 118 key ··· 127 130 | Cmd_r _ 128 131 | Prompt_r _ 129 132 | Dynamic_r _ ) 133 + ; sort_key = _ 130 134 } -> 131 135 [ render_command_line ~indent_level (key_to_string key) description ] 132 - | { key; description; cmd = SubCmd subs } -> 136 + | { key; description; cmd = SubCmd subs; sort_key = _ } -> 133 137 render_command_line ~indent_level (key_to_string key) description 134 138 :: render_commands ~indent_level:(indent_level + 1) subs 135 139 ;; ··· 260 264 | `ASCII k, modifiers -> 261 265 let key = { key = k; modifiers } in 262 266 [%log info "key: %s" (key_to_string key)]; 263 - let cmd = keymap|>Key_Map.find_opt key in 267 + let cmd = keymap |> Key_Map.find_opt key in 264 268 (match cmd with 265 269 | Some cmd -> 266 270 handleCommand cmd.description cmd.cmd; ··· 301 305 include Shared 302 306 303 307 (** A handy command_list that just has this help command for areas that don't have any commands to still show help*) 304 - let rec make_default_list (): string command Key_Map.t= 308 + let rec make_default_list () : string command Key_Map.t = 305 309 [ 306 310 { 307 311 key = { key = '?'; modifiers = [] } 308 312 ; description = "Show help" 313 + ; sort_key = 0.0 309 314 ; cmd = 310 315 Fun 311 316 (fun _ -> 312 317 ui_state.show_popup 313 - $= Some (commands_list_ui ~include_arrows:true (make_default_list ()), "Help"); 318 + $= Some 319 + (commands_list_ui ~include_arrows:true (make_default_list ()), "Help"); 314 320 ui_state.input $= `Mode (fun _ -> `Unhandled)) 315 321 } 316 322 ] ··· 318 324 |> Seq.map (fun x -> x.key, x) 319 325 |> Key_Map.of_seq 320 326 ;; 321 - let default_list=make_default_list() 327 + 328 + let default_list = make_default_list () 322 329 323 330 (**Generate a UI object with all the commands nicely formatted and layed out. Useful for help text*) 324 331 let commands_list_ui = commands_list_ui ··· 326 333 (**`Prompt`:Allows running one command and then running another using the input of the first*) 327 334 let confirm_prompt prompt cmd = 328 335 let key = key_of_string_exn "y" in 329 - 330 - let sub_cmd= Key_Map.of_list [key, { key; description = "Yes I want to " ^ prompt; cmd }] in 336 + let sub_cmd = 337 + Key_Map.of_list 338 + [ key, { key; description = "Yes I want to " ^ prompt; cmd; sort_key = 0.0 } ] 339 + in 331 340 SubCmd sub_cmd 332 341 ;; 333 342 ··· 345 354 346 355 (* Function to build command list from key_map and a command registry *) 347 356 let build_command_list key_map command_registry = 348 - 349 357 (* Process a key_map item *) 350 358 let rec process_key_map_item key item = 351 359 match item with 352 360 | Command { command = id } -> 353 361 (match Hashtbl.find_opt command_registry id with 354 362 | Some cmd_def -> 355 - Some { key; description = cmd_def.description; cmd = cmd_def.make_cmd () } 363 + Some 364 + { 365 + key 366 + ; description = cmd_def.description 367 + ; cmd = cmd_def.make_cmd () 368 + ; sort_key = cmd_def.sorting_key 369 + } 356 370 | None -> 357 371 [%log warn "Unknown command ID: %s" id]; 358 372 None) ··· 365 379 process_key_map_item k v |> Option.map (fun x -> k, x)) 366 380 |> Key_Map.of_seq 367 381 in 368 - Some { key; description = title; cmd = SubCmd sub_cmds } 382 + let sort_key = 383 + match Key_Map.to_seq sub_cmds |> Seq.uncons with 384 + | Some ((_, (x : 'a command)), _) -> 385 + x.sort_key 386 + | None -> 387 + 0.0 388 + in 389 + Some { key; description = title; cmd = SubCmd sub_cmds; sort_key } 369 390 in 370 391 (* Process all items in the key_map *) 371 392 key_map
+3 -1
jj_tui/lib/key_map.ml
··· 205 205 ; cmd "u" "bookmark_untrack" 206 206 ] 207 207 ; cmd "f" "filter" 208 + ; cmd "A" "absorb" 208 209 ] 209 210 ; file = 210 211 k_map ··· 213 214 ; cmd "m" "move_to_rev" 214 215 ; cmd "N" "move_to_child" 215 216 ; cmd "P" "move_to_parent" 216 - ; cmd "d" "discard" 217 + ; cmd "a" "abandon" 218 + ; cmd "A" "absorb" 217 219 ] 218 220 } 219 221 ;;