1 module pkm.getopt;
2 
3 import std.getopt: Option;
4 import std.algorithm: max;
5 import std.stdio: writefln;
6 import std.array: join;
7 
8 /** 
9  * Prints passed **Option**s and text in aligned manner on stdout, i.e:
10  * ```
11  * A simple cli tool
12  * 
13  * Usage: 
14  *   scli [options] [script] \
15  *   scli run [script]
16  * 
17  * Options: 
18  *   -h, --help   This help information. \
19  *   -c, --check  Check syntax without running. \
20  *   --quiet      Run silently (no output). 
21  * Commands:
22  *   run          Runs script. \
23  *   compile      Compiles script.
24  * ```
25  * Params:
26  *   text = Text to be printed at the beginning of the help output
27  *   usage = Usage string
28  *   com = Commands
29  *   opt = The **Option** extracted from the **getopt** parameter
30  */
31 void printGetopt(string text, string usage, Commands[] com, Option[] opt, string[] custom, string[][] customargs) {
32     size_t maxLen = 0;
33 
34     foreach (it; opt) {
35         int sep = it.optShort == "" ? 0 : 2;
36         maxLen = max(maxLen, it.optShort.length + it.optLong.length + sep);
37     }
38 
39     foreach (it; com) {
40         maxLen = max(maxLen, it.name.length);
41     }
42 
43     foreach (it; custom) {
44         maxLen = max(maxLen, it.length);
45     }
46     
47     if (text != "") {
48         writefln(text);
49     }
50     
51     if (usage != "") {
52         if (text != "") writefln("");
53         writefln("Usage:");
54         writefln("  " ~ usage);
55     }
56 
57     if (com.length != 0) {
58         if (text != "" || usage != "") writefln("");
59         writefln("Options:");
60     }
61 
62     foreach (it; opt) {
63         // writefln("%*s %*s%s%s", 
64         // shortLen, it.optShort,
65         //     longLen, it.optLong,
66         //     it.required ? " Required: " : " ", it.help);
67         string opts = it.optShort ~ (it.optShort == "" ? "" : ", ") ~ it.optLong;
68         writefln("  %-*s  %s", maxLen, opts, it.help);
69     }
70 
71     if (com.length != 0) {
72         if (text != "" || usage != "" || com.length != 0) writefln("");
73         writefln("Commands:");
74     }
75 
76     foreach (it; com) { 
77         writefln("  %-*s  %s", maxLen, it.name, it.help);
78     }
79 
80     if (custom.length != 0) {
81         if (text != "" || usage != "" || com.length != 0) writefln("");
82         writefln("Custom:");
83     }
84 
85     for (int i = 0; i < custom.length; i ++) {
86         writefln("  %-*s  %s", maxLen, custom[i], customargs[i].join(' '));
87     }
88 }
89 
90 struct Commands {
91     string name;
92     string help;
93 }