c-blake / cligen

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

Is there a way to wrap the doc string by say 80 columns? #176

Closed halloleo closed 3 years ago

halloleo commented 3 years ago

cligen assigns the doc string of the main function to the template variable $doc. So far so good. But is it possible to wrap the output of $doc by maximal 80 characters? Can I do this in the CL config or as a customisation to the my dispatch?

(I use a terminal with a very wide virtual width, but this meants that if the doc string is not wrapped you might need to scroll awkwardly quite a bit to the right...)

c-blake commented 3 years ago

cligen trusts what the terminal reports as its width for auto-wrap. Even as you describe your problem, I am confused why you would set your virtual width wide (basically asking programs to use unseen space) and then complain about programs doing exactly what you are asking.

I can suggest an environmental workaround (at least on Unix) that lets you choose the width reported to programs on a per invocation basis. (This is mentioned at the top of test.sh):

x=$COLUMNS; stty columns 80; RUN-SOME-COMMAND; stty columns $x

You could turn this into a shell function with80() { ... } or something. Then when you want wrapped at 80 you would say with80 foo -h and when you do not just foo -h. If you want to be able to set it to any width you could call it tcols for "terminal cols" and say tcols 65 foo -h, say, or tcols 128 foo -h as desired.

c-blake commented 3 years ago

Though https://github.com/c-blake/cligen/issues/172 is more about having empty ./test.sh output, similar topics arise. I guess I mention a shell script rather than shell function there.

c-blake commented 3 years ago

Also, it's hard for me to believe (given your setup as I understand it) that foo --help is the only situation where you would want to control the terminal width as reported to programs. So, this general tcols or w80 or whatever you want to call it function or wrapper script is probably of more general utility to you, and should also solve the cligen problem.

halloleo commented 3 years ago

I totally agree, my setup is a bit "unusual".

I still think the CLI tool creator (in this case me :wink: ) should be able to have some control over the wrapping. For the moment I'm doing this by setting clCfg.use myself, but I can see more elegant solutions:

  1. Have an entry in clCfg for the wrapping column (or AUTO)
  2. Take the doc parameter as is and do not re-wrap it. (Then the caller can provide what ever they want.)
  3. Enable some interpolation syntax in usage/clCfg.use to indicate wrapping (say: $doc:80 or something).

I think I'd prefer 1., but I'm not sure whether I'm with my Nim knowledge at the stage where I could do gobble up a PR...

c-blake commented 3 years ago

Well, those 1/2/3 ideas are not bad and I am not close-minded about it, but in the mean time you can get most of what you want at the cost of just 2 terminal columns and some stylized doc comment formatting. I'm not sure if I documented this feature well, but I have a kind of "auto-preformatted detection". Specifically, if you do this:

import cligen
proc f() =
  ##abc
  ##  ddd ddd ddd ddd ddd ddd ddd ddd ddd ddd ddd ddd ddd ddd ddd ddd ddd ddd ddd ddd ddd ddd ddd
  ##
  ##  ddd ddd ddd ddd ddd ddd ddd ddd ddd ddd ddd ddd ddd ddd ddd ddd ddd ddd ddd ddd ddd ddd ddd

dispatch(f)

and compile & run on an 80 column terminal then those ddds will not be wrapped. You just need doc comment lines to be indented 2 or more (and then stay indented). IIRC, a "de-dent" will move back to wrapped mode.

This has no analogue in Nim's rST processing into HTML/LaTeX and so on, though. But the output & reader contexts there are also very distinct from a terminal anyway.

This might inspire an "idea 4" which would be "how indented to qualify as pre-formatted" where "0" would mean it's always considered pre-formatted. But the current "2" (hard coded IIRC) might also be enough for you almost all the time as is.

halloleo commented 3 years ago

Super interesting! Good to know.

For the moment I stick with setting clCfg.use myself.