diff --git a/CHANGELOG.md b/CHANGELOG.md index 2b5e05f..c5adf7c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,10 @@ * Added `help_vertical_space` property for configuring number of extra newlines between help strings for different arguments and options in autogenerated help string. +* Added `usage_margin` and `usage_max_width` properties for configuring + usage string autogeneration. +* Added `help_usage_margin` and `help_description_margin` properties + for configuring help string autogeneration. ### Improvements diff --git a/spec/help_spec.lua b/spec/help_spec.lua index 48e811f..4a268c6 100644 --- a/spec/help_spec.lua +++ b/spec/help_spec.lua @@ -463,4 +463,37 @@ Options: -h, --help Show this help message and exit.]], cmd2:get_help()) end) + + it("allows configuring margins using help_usage_margin and help_description_margin", function() + local parser = Parser "foo" + :help_usage_margin(2) + :help_description_margin(15) + + parser:argument "arg1" + :description "Argument number one." + parser:argument "arg2" + :description "Argument number two." + + parser:flag "-p" + :description "This is a thing." + parser:option "-f --foo" + :description [[ +And this things uses many lines. +Because it has lots of complex behaviour. +That needs documenting.]] + + assert.equal([[ +Usage: foo [-p] [-f ] [-h] + +Arguments: + arg1 Argument number one. + arg2 Argument number two. + +Options: + -p This is a thing. + -f , And this things uses many lines. + --foo Because it has lots of complex behaviour. + That needs documenting. + -h, --help Show this help message and exit.]], parser:get_help()) + end) end) diff --git a/spec/usage_spec.lua b/spec/usage_spec.lua index 4c37f24..3d93f10 100644 --- a/spec/usage_spec.lua +++ b/spec/usage_spec.lua @@ -307,4 +307,38 @@ Usage: foo ([--opt1 ] | [--opt3 ] | [--opt5 ]) ([] | [--opt4 ])]=], parser:get_usage() ) end) + + it("allows configuring usage margin using usage_margin property", function() + local parser = Parser "foo" + :usage_margin(2) + + parser:argument "long_argument_name" + parser:argument "very_long_words" + + parser:option "--set-important-property" + parser:option "--include" + :args "*" + + assert.equals([=[ +Usage: foo [--set-important-property ] [-h] + [--include [] ...]]=], parser:get_usage()) + end) + + it("allows configuring max usage width using usage_max_width property", function() + local parser = Parser "foo" + :usage_max_width(50) + + parser:argument "long_argument_name" + parser:argument "very_long_words" + + parser:option "--set-important-property" + parser:option "--include" + :args "*" + + assert.equals([=[ +Usage: foo + [--set-important-property ] + [-h] + [--include [] ...]]=], parser:get_usage()) + end) end) diff --git a/src/argparse.lua b/src/argparse.lua index 698bf75..36d3887 100644 --- a/src/argparse.lua +++ b/src/argparse.lua @@ -247,6 +247,10 @@ local Parser = class({ typechecked("action", "function"), typechecked("command_target", "string"), typechecked("help_vertical_space", "number"), + typechecked("usage_margin", "number"), + typechecked("usage_max_width", "number"), + typechecked("help_usage_margin", "number"), + typechecked("help_description_margin", "number"), add_help }) @@ -265,6 +269,10 @@ local Command = class({ typechecked("action", "function"), typechecked("command_target", "string"), typechecked("help_vertical_space", "number"), + typechecked("usage_margin", "number"), + typechecked("usage_max_width", "number"), + typechecked("help_usage_margin", "number"), + typechecked("help_description_margin", "number"), typechecked("hidden", "boolean"), add_help }, Parser) @@ -638,7 +646,6 @@ function Parser:group(name, ...) return self end -local max_usage_width = 70 local usage_welcome = "Usage: " function Parser:get_usage() @@ -646,13 +653,15 @@ function Parser:get_usage() return self._usage end + local usage_margin = self:_inherit_property("usage_margin", #usage_welcome) + local max_usage_width = self:_inherit_property("usage_max_width", 70) local lines = {usage_welcome .. self:_get_fullname()} local function add(s) if #lines[#lines]+1+#s <= max_usage_width then lines[#lines] = lines[#lines] .. " " .. s else - lines[#lines+1] = (" "):rep(#usage_welcome) .. s + lines[#lines+1] = (" "):rep(usage_margin) .. s end end @@ -773,11 +782,6 @@ function Parser:get_usage() return table.concat(lines, "\n") end -local margin_len = 3 -local margin2_len = 25 -local margin = (" "):rep(margin_len) -local margin2 = (" "):rep(margin2_len) - local function split_lines(s) if s == "" then return {} @@ -796,7 +800,7 @@ local function split_lines(s) return lines end -local function get_element_help(element) +function Parser:_get_element_help(element) local label_lines = element:_get_label_lines() local description_lines = split_lines(element:_get_description()) @@ -806,13 +810,19 @@ local function get_element_help(element) -- If too long, start description after all the label lines. -- Otherwise, combine label and description lines. - if #label_lines[1] >= (margin2_len - margin_len) then + local usage_margin_len = self:_inherit_property("help_usage_margin", 3) + local usage_margin = (" "):rep(usage_margin_len) + local description_margin_len = self:_inherit_property("help_description_margin", 25) + local description_margin = (" "):rep(description_margin_len) + + + if #label_lines[1] >= (description_margin_len - usage_margin_len) then for _, label_line in ipairs(label_lines) do - table.insert(result_lines, margin .. label_line) + table.insert(result_lines, usage_margin .. label_line) end for _, description_line in ipairs(description_lines) do - table.insert(result_lines, margin2 .. description_line) + table.insert(result_lines, description_margin .. description_line) end else for i = 1, math.max(#label_lines, #description_lines) do @@ -822,11 +832,11 @@ local function get_element_help(element) local line = "" if label_line then - line = margin .. label_line + line = usage_margin .. label_line end if description_line and description_line ~= "" then - line = line .. (" "):rep(margin2_len - #line) .. description_line + line = line .. (" "):rep(description_margin_len - #line) .. description_line end table.insert(result_lines, line) @@ -852,7 +862,7 @@ function Parser:_add_group_help(blocks, added_elements, label, elements) for _, element in ipairs(elements) do if not element._hidden and not added_elements[element] then added_elements[element] = true - table.insert(buf, get_element_help(element)) + table.insert(buf, self:_get_element_help(element)) end end