fix subcommands in json model

This commit is contained in:
atagen 2026-03-23 14:01:11 +11:00
parent 640732de4b
commit 76656231be
2 changed files with 33 additions and 2 deletions

View file

@ -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

View file

@ -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