first draft

This commit is contained in:
atagen 2026-03-18 18:19:37 +11:00
parent ab009ec9af
commit 01ccf64efc
13 changed files with 1311 additions and 239 deletions

82
lib/nushell.ml Normal file
View file

@ -0,0 +1,82 @@
open Parser
(* Map a param name/type hint to a nushell type *)
let nushell_type_of_param = function
| "FILE" | "file" | "PATH" | "path" | "DIR" | "dir" | "DIRECTORY"
| "FILENAME" | "PATTERNFILE" -> "path"
| "NUM" | "N" | "COUNT" | "NUMBER" | "int" | "INT" | "COLS" | "WIDTH"
| "LINES" | "DEPTH" | "depth" -> "int"
| _ -> "string"
(* Escape a nushell string: wrap in double quotes, escape inner quotes *)
let escape_nu s =
let buf = Buffer.create (String.length s + 2) in
String.iter (fun c ->
match c with
| '"' -> Buffer.add_string buf "\\\""
| '\\' -> Buffer.add_string buf "\\\\"
| _ -> Buffer.add_char buf c
) s;
Buffer.contents buf
(* Format a single flag for nushell extern *)
let format_flag entry =
let buf = Buffer.create 64 in
Buffer.add_string buf " ";
(* Flag name *)
(match entry.switch with
| Both (s, l) ->
Buffer.add_string buf (Printf.sprintf "--%s(-%c)" l s)
| Long l ->
Buffer.add_string buf (Printf.sprintf "--%s" l)
| Short s ->
Buffer.add_string buf (Printf.sprintf "-%c" s));
(* Type annotation *)
(match entry.param with
| Some (Mandatory name) ->
Buffer.add_string buf ": ";
Buffer.add_string buf (nushell_type_of_param name)
| Some (Optional name) ->
Buffer.add_string buf ": ";
Buffer.add_string buf (nushell_type_of_param name)
| None -> ());
(* Description as comment *)
if String.length entry.desc > 0 then begin
(* Pad to align comments *)
let current_len = Buffer.length buf in
let target = max (current_len + 1) 40 in
for _ = current_len to target - 1 do
Buffer.add_char buf ' '
done;
Buffer.add_string buf "# ";
Buffer.add_string buf entry.desc
end;
Buffer.contents buf
(* Generate nushell extern definition for a command *)
let generate_extern cmd_name result =
let buf = Buffer.create 1024 in
(* Main extern with flags *)
Buffer.add_string buf (Printf.sprintf "export extern \"%s\" [\n" (escape_nu cmd_name));
List.iter (fun entry ->
Buffer.add_string buf (format_flag entry);
Buffer.add_char buf '\n'
) result.entries;
Buffer.add_string buf "]\n";
(* Subcommand externs *)
List.iter (fun (sc : subcommand) ->
Buffer.add_string buf
(Printf.sprintf "\nexport extern \"%s %s\" [ # %s\n]\n"
(escape_nu cmd_name) (escape_nu sc.name) (escape_nu sc.desc))
) result.subcommands;
Buffer.contents buf
(* Generate a complete nushell module *)
let generate_module cmd_name result =
Printf.sprintf "module %s-completions {\n%s}\n"
cmd_name (generate_extern cmd_name result)
(* Generate from manpage entries (no subcommands) *)
let generate_extern_from_entries cmd_name entries =
let result = { entries; subcommands = [] } in
generate_extern cmd_name result