c-blake / cligen

Nim library to infer/generate command-line-interfaces / option / argument parsing; Docs at
https://c-blake.github.io/cligen/
ISC License
496 stars 23 forks source link

Wrapped doc string is only indented in the first line #181

Closed halloleo closed 3 years ago

halloleo commented 3 years ago

When I use cligen's standard wrapping mechanism a help output can look like this:

Usage: opf2tag [required&optional-params] DOCPATH OPFDIR

  Query the ".opf" file to a document DOCPATH for metadata tag information.  
The ".opf" file is looked up in OPFDIR

options:
  -h, --help                           print this cligen-erated help
  ...

I would say, not indenting the second line of the doc string is wrong, but do you think it is a feature? Is there any easy way to tell cligen to indent the subsequent lines of the doc string?

c-blake commented 3 years ago

I cannot reproduce your behavior. For me, this program:

proc opf2tag(paths: seq[string]) =
  ## Query the ".opf" file to a document DOCPATH for metadata tag information.
  ## The ".opf" file is looked up in OPFDIR
  discard
import cligen; dispatch(opf2tag, help={"paths": "DOCPATH OPFPATH"})

produces this output with -h on an 80 column terminal:

Usage:
  opf2tag [optional-params] DOCPATH OPFPATH
Query the ".opf" file to a document DOCPATH for metadata tag information.  The
".opf" file is looked up in OPFDIR
  -h, --help      print this cligen-erated help
  --help-syntax   advanced: prepend,plurals,..

If I instead run it like CLIGEN_WIDTH=76 ./opf2tag -h with this new feature some mysterious fellow on the Internet asked for { ;-) } then I instead get:

Usage:
  opf2tag [optional-params] DOCPATH OPFPATH
Query the ".opf" file to a document DOCPATH for metadata tag information.
The ".opf" file is looked up in OPFDIR
  -h, --help      print this cligen-erated help
  --help-syntax   advanced: prepend,plurals,..

These are the "standard" ways or at least nice ways to format help IMO - "Usage:" with a new line and some amount of indent for the command. Then "outdent" for the description. Then the indented help table where these indent/outdent shapes make sections visually distinct even without blank lines. I guess I could maybe add an hTabIndent for the overall indent..then if people want to use vertical space they can have "--whatnot" be flush with the left margin, but this would be a separate issue.

There is some minimal control of this overall layout via the usage parameter of dispatch or the ClCfg.use/.useMulti. usage defaults to "$command $args\n${doc}Options:\n$options" . In the $CLIGEN config file (~/.config/cligen or ~/.config/cligen/config by default) the CLuser can sometimes fiddle with these knobs to their own liking because what visually pops out or is needed or how big terminals are/how precious screen real estate is/whether the reader is color blind/etc. are all traits of an end CLuser's environment the CLauthor cannot know.

Maybe you know this and are doing something like:

proc opf2tag(paths: seq[string]) =
  ## Query the ".opf" file to a document DOCPATH for metadata tag information.
  ##   The ".opf" file is looked up in OPFDIR
  discard
import cligen
clCfg.use ="$command $args\n  ${doc}Options:\n$options"
dispatch(opf2tag, help={"paths": "DOCPATH OPFPATH"})

to get your indent. Note that I indented the 2nd row in the ## doc comment to get them to line up..kind of hacky/dependent upon CLIGEN_WIDTH or terminal width.

Anyway, in the future it would be helpful for you to include the (skeleton) of the Nim code producing the help output you do not like. Then I do not have to guess blindly what you are doing.

cligen is honestly "not for" people that are supremely picky about help output. Most of its value is the generated help. If you spend hours battling with its knobs to make it do what you want then the value proposition vs. just hammering your own usage strings gets inverted. Having something formated 100% exactly as you want is at odds with automatic generation. You can make the entire usage string yourself by hammering it in your program:

proc opf2tag(paths: seq[string]) = discard
import cligen
clCfg.useHdr = " " # Ack..I guess empty string is ignored.
clCfg.use = """Any text at all (but with
any $$ doubled up)."""
dispatch(opf2tag) # less need for params

That leading space from useHdr is a remnant from a time when Nim had nil valued strings and I could distinguish between "unset" vs "set to empty string". I should probably just accept the empty string for that one.

c-blake commented 3 years ago

This issue title is misleading. So, I am closing it. But feel free to keep discussing.

halloleo commented 3 years ago

Ups, my bad, @c-blake! Totally sorry. I did the indenting and cligen didn't know about it. Again, totally sorry!

And you are very right: Being too picky with help output defeats the purpose of automatic generation. I guess I better relax. 😉