Skip to content

Commit bd7873f

Browse files
committed
feat: Introduce an ability to display proper arg's value placeholder in help
Signed-off-by: prajwalch <[email protected]>
1 parent b620052 commit bd7873f

File tree

3 files changed

+56
-29
lines changed

3 files changed

+56
-29
lines changed

examples/ls.zig

+9-2
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,15 @@ pub fn main() anyerror!void {
3030
try myls.addArg(Arg.booleanOption("one-line", '1', "List each entries in new line"));
3131
try myls.addArg(Arg.booleanOption("size", 's', "Display file size"));
3232
try myls.addArg(Arg.booleanOption("version", null, "Display program version number"));
33-
try myls.addArg(Arg.singleValueOption("ignore", 'I', "Ignore the given pattern"));
34-
try myls.addArg(Arg.singleValueOption("hide", null, "Don't display hidden entries"));
33+
34+
var ignore_opt = Arg.singleValueOption("ignore", 'I', "Ignore the given pattern");
35+
ignore_opt.setValuePlaceholder("PATTERN");
36+
37+
var hide_opt = Arg.singleValueOption("hide", null, "Don't display hidden entries");
38+
hide_opt.setValuePlaceholder("PATTERN");
39+
40+
try myls.addArg(ignore_opt);
41+
try myls.addArg(hide_opt);
3542
try myls.addArg(Arg.singleValueOptionWithValidValues(
3643
"color",
3744
'C',

src/Arg.zig

+37
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ short_name: ?u8 = null,
3030
long_name: ?[]const u8 = null,
3131
min_values: ?usize = null,
3232
max_values: ?usize = null,
33+
value_placeholder: ?[]const u8 = null,
3334
valid_values: ?[]const []const u8 = null,
3435
values_delimiter: ?[]const u8 = null,
3536
index: ?usize = null,
@@ -321,6 +322,42 @@ pub fn setMaxValues(self: *Arg, num: usize) void {
321322
self.max_values = if (num >= 1) num else null;
322323
}
323324

325+
/// Sets the placeholder for the argument value in the help message.
326+
///
327+
/// The placeholder is only used to display on help message and by default,
328+
/// if the placeholder is not set, argument name is displayed.
329+
///
330+
/// **NOTE:** If the argument doesn't take value, placeholder is ignored.
331+
///
332+
/// ## Examples
333+
///
334+
/// ```zig
335+
/// var app = App.init(allocator, "myapp", "My app description");
336+
/// defer app.deinit();
337+
///
338+
/// var root = app.rootCommand();
339+
///
340+
/// var arg = Arg.singleValueOption("exp-time", 't', "Set max expire time")
341+
/// arg.setValuePlaceholder("SECS");
342+
///
343+
/// root.addArg(arg);
344+
/// ```
345+
///
346+
/// On command line:
347+
///
348+
/// ```sh
349+
/// $ myapp -h
350+
/// My app description
351+
///
352+
/// Usage: myapp [OPTIONS]
353+
///
354+
/// Options:
355+
/// -t, --exp-time=<SECS> Set max expire time
356+
/// ```
357+
pub fn setValuePlaceholder(self: *Arg, placeholder: []const u8) void {
358+
self.value_placeholder = placeholder;
359+
}
360+
324361
/// Sets the valid values for an argument.
325362
///
326363
/// ## Examples

src/HelpMessageWriter.zig

+10-27
Original file line numberDiff line numberDiff line change
@@ -141,34 +141,12 @@ fn writeOption(self: *HelpMessageWriter, option: *const Arg) !void {
141141

142142
// Value name.
143143
if (option.hasProperty(.takes_value)) {
144-
try signature_writer.writeByte('=');
144+
// Otherwise print the option actual value name or option name itself.
145+
const value_name = option.value_placeholder orelse option.name;
146+
try signature_writer.print("=<{s}>", .{value_name});
145147

146-
// If the option has set acceptable values, print that.
147-
if (option.valid_values) |valid_values| {
148-
try signature_writer.writeByte('<');
149-
150-
for (valid_values, 0..) |value, idx| {
151-
try signature_writer.print("{s}", .{value});
152-
153-
// Don't print `|` at first and last.
154-
//
155-
// For e.x.: --format=<json|toml|yaml>
156-
if (idx < (valid_values.len - 1)) {
157-
try signature_writer.writeByte('|');
158-
}
159-
}
160-
161-
try signature_writer.writeByte('>');
162-
} else {
163-
// Otherwise print the option name.
164-
//
165-
// TODO: Add new `Arg.placeholderName()` to display correct value
166-
// or placeholder name. For e.x.: --time=SECS.
167-
try signature_writer.print("<{s}>", .{option.name});
168-
169-
if (option.hasProperty(.takes_multiple_values)) {
170-
try signature_writer.writeAll("...");
171-
}
148+
if (option.hasProperty(.takes_multiple_values)) {
149+
try signature_writer.writeAll("...");
172150
}
173151
}
174152

@@ -178,6 +156,11 @@ fn writeOption(self: *HelpMessageWriter, option: *const Arg) !void {
178156
// Then write the description.
179157
if (option.description) |description| {
180158
try writer.print("\t\t{s}", .{description});
159+
160+
if (option.valid_values) |valid_values| {
161+
// FIXME: Remove this hacky implmentation
162+
try writer.print("\n\t\t\t\t\t\t values: {s}", .{valid_values});
163+
}
181164
}
182165

183166
// End of line.

0 commit comments

Comments
 (0)