Compare commits

...

3 Commits

Author SHA1 Message Date
70c6cea591
demo: demonstrate preformatted description text functionality
Throw in a lipsum as well to show off the wrapped text better, while
we're at it.
2023-11-08 22:58:01 -08:00
645ef24a4a
command: preserve subcommand definition order
This was as simple as switching to an order preserving hashmap. This
lets the user decide which order their subcommands should be presented
in.
2023-11-08 22:56:11 -08:00
768a81e2bd
help: hack in support for preformatted lines
This works, but there are probably interesting edge cases around how it
works when directly adjacent to other paragraphs. I will have to think
about it a bit. This wrapping code in general would benefit from term
queries.

Perhaps violating the principle of least astonishment quite severely is
the fact that "> a" and ">" are detected as preformatted, but ">a" is
normal wrapped text. Supporting both ">a" and "> a" leads to
nonobvious whitespace behavior, but this code should not be able to
runtime error outside of the writer dying. This may be reevaluated in
the future, but I will leave it as-is for now.
2023-11-08 22:52:28 -08:00
4 changed files with 32 additions and 9 deletions

View File

@ -11,6 +11,19 @@ const cli = cmd: {
\\The definitive noclip demonstration utility
\\
\\This command demonstrates the functionality of the noclip library. cool!
\\
\\> // implementing factorial recursively is a silly thing to do
\\> pub fn fact(n: u64) u64 {
\\> if (n == 0) return 1;
\\> return n*fact(n - 1);
\\> }
\\
\\Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
\\incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis
\\nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
\\Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore
\\eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident,
\\sunt in culpa qui officia deserunt mollit anim id est laborum.
,
};
cmd.addOption(.{ .OutputType = struct { u8, u8 } }, .{

View File

@ -167,7 +167,7 @@ pub fn CommandBuilder(comptime UserContext: type) type {
return Parser(self, callback){
.arena = arena,
.allocator = arena_alloc,
.subcommands = std.hash_map.StringHashMap(ParserInterface).init(arena_alloc),
.subcommands = parser.CommandMap.init(arena_alloc),
.help_builder = help.HelpBuilder(self).init(arena_alloc),
};
}
@ -188,7 +188,7 @@ pub fn CommandBuilder(comptime UserContext: type) type {
this_parser.* = .{
.arena = arena,
.allocator = arena_alloc,
.subcommands = std.hash_map.StringHashMap(ParserInterface).init(arena_alloc),
.subcommands = parser.CommandMap.init(arena_alloc),
.help_builder = help.HelpBuilder(self).init(arena_alloc),
};

View File

@ -65,6 +65,17 @@ pub fn StructuredPrinter(comptime Writer: type) type {
// we have a trailing line that needs to be cleaned up
if (location > indent)
_ = try self.clearLine(indent);
location = try self.clearLine(indent);
continue;
}
if (line[0] == '>') maybe: {
if (line.len > 1) {
if (line[1] == ' ') {
try self.writer.writeAll(line[2..]);
} else break :maybe;
}
location = try self.clearLine(indent);
continue;
}
@ -101,6 +112,7 @@ pub fn StructuredPrinter(comptime Writer: type) type {
}
if (location > indent)
try self.writer.writeByte(' ');
try self.writer.writeAll(choppee[0..split]);
location = try self.clearLine(indent);
choppee = choppee[split + 1 ..];
@ -348,11 +360,10 @@ pub fn HelpBuilder(comptime command: anytype) type {
defer pairs.deinit();
var just: usize = 0;
var iter = subcommands.keyIterator();
while (iter.next()) |key| {
for (subcommands.keys()) |key| {
const pair: AlignablePair = .{
.left = key.*,
.right = subcommands.get(key.*).?.describe(),
.left = key,
.right = subcommands.get(key).?.describe(),
};
if (pair.left.len > just) just = pair.left.len;
try pairs.append(pair);

View File

@ -73,7 +73,7 @@ pub const ParserInterface = struct {
}
};
pub const CommandMap = std.hash_map.StringHashMap(ParserInterface);
pub const CommandMap = std.StringArrayHashMap(ParserInterface);
// the parser is generated by the bind method of the CommandBuilder, so we can
// be extremely type-sloppy here, which simplifies the signature.
@ -144,8 +144,7 @@ pub fn Parser(comptime command: anytype, comptime callback: anytype) type {
}
pub fn deinitTree(self: @This()) void {
var iterator = self.subcommands.valueIterator();
while (iterator.next()) |subcommand| {
for (self.subcommands.values()) |subcommand| {
subcommand.deinitTree();
}
self.deinit();