From 76656231bea3e7819c4b046ff7b77ddaa0037f80 Mon Sep 17 00:00:00 2001 From: atagen Date: Mon, 23 Mar 2026 14:01:11 +1100 Subject: [PATCH] fix subcommands in json model --- bin/main.ml | 7 +++++-- lib/store.ml | 28 ++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/bin/main.ml b/bin/main.ml index fd1e665..99234be 100644 --- a/bin/main.ml +++ b/bin/main.ml @@ -364,7 +364,7 @@ let help_resolve_par ?(timeout=200) cmd rest name = else let at_limit = q_depth >= 5 in let subs = if at_limit then [] else r.subcommands in - Some ({ r with subcommands = [] }, subs)) in + Some (r, subs)) in let oc = Unix.out_channel_of_descr wr in Marshal.to_channel oc (result : (help_result * subcommand list) option) []; close_out oc; @@ -613,10 +613,13 @@ let cmd_complete spans user_dir system_dirs = if String.starts_with ~prefix:"-" partial then candidates := flag_completions partial r.entries else begin + let subs = match r.subcommands with + | _ :: _ -> r.subcommands + | [] -> subcommands_of dirs _matched_name in List.iter (fun (sc : subcommand) -> if partial = "" || String.starts_with ~prefix:partial sc.name then candidates := completion_json sc.name sc.desc :: !candidates - ) r.subcommands; + ) subs; candidates := List.rev !candidates; if partial = "" || !candidates = [] then candidates := !candidates @ flag_completions partial r.entries diff --git a/lib/store.ml b/lib/store.ml index 467b798..2c51e48 100644 --- a/lib/store.ml +++ b/lib/store.ml @@ -308,6 +308,34 @@ let lookup_raw dirs command = let has_command dirs command = find_file dirs command <> None +let subcommands_of dirs command = + let prefix = filename_of_command command ^ "_" in + let plen = String.length prefix in + let module SMap = Map.Make(String) in + let subs = ref SMap.empty in + List.iter (fun dir -> + if Sys.file_exists dir && Sys.is_directory dir then + Array.iter (fun f -> + if String.starts_with ~prefix f then + let base = + if Filename.check_suffix f ".json" then + Some (Filename.chop_suffix f ".json") + else if Filename.check_suffix f ".nu" then + Some (Filename.chop_suffix f ".nu") + else None in + match base with + | Some b -> + let rest = String.sub b plen (String.length b - plen) in + (* Only direct children: no further underscores *) + if not (String.contains rest '_') && String.length rest > 0 then + let name = rest in + if not (SMap.mem name !subs) then + subs := SMap.add name { name; desc = "" } !subs + | None -> () + ) (Sys.readdir dir) + ) dirs; + SMap.fold (fun _ sc acc -> sc :: acc) !subs [] |> List.rev + let all_commands dirs = let module SSet = Set.Make(String) in let cmds = ref SSet.empty in