-
Notifications
You must be signed in to change notification settings - Fork 56
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Better SYNOPSIS section #42
Comments
Fair enough. Would it be possible for the |
The problem is that it is a little bit difficult to control from a layout point of view, consider e.g. only the common options a subcommand like Did you consider defining the |
Ok that could work if I could somehow get access to or $(substitute) the subcommands' auto-generated SYNOPSIS so I can include it in the main command's SYNOPSIS. |
In fact it is What you propose may be feasible but I don't have these things in my head I'll see this once I get to work on it again. |
I think at least the subcommands should be listed together somewhere (perhaps SYNOPSIS). Actually cmdliner is not alone in using Take your time to think about it and we can pick up the discussion when you're on cmdliner again. What may look like the right layout for one application may not work so well for another. |
I'm still a little bit unsure what to do here. Programs tend to have dozens of commands (e.g. Personally I don't find the Maybe we should leave the task of making usable man synopses to humans. Note that a side effect of 618a3d3 means more precise synopses for positional arguments. |
Would it be possible to provide a function that folds over the components of a Or maybe this should be decided at |
As mentioned in my position linked earlier I'm not very fond of configurability. Because it's not in favour of the end-user for which uniformity is more important as it allows her to derive consistent patterns and form habits. However providing an API to be able to extract data from terms is certainly something that is needed if only to solve issue #1. But then for typesetting your manpage the |
My concern with just specifying the synposis manually as a string is that it might get out of date (command-line flags could get removed/added, etc.). It is hard to come up with a single rule that would work for all applications' synopsis, so how about cmdliner would only verify the user supplied synposis, but not automatically generate it. For example if user writes this in synopsis:
Then cmdliner would check that Then the user would be free to write synposis like the one for rsync, assuming cmdliner is able to find the proper place to start parsing (right after the name of the application, in this case
A similar mechanism would be useful for writing an example section (I often find it much easier to learn a command if it has good examples of its main use-cases, especially if it has a lot of flags). This is by no means easy to implement though, what do you think? |
If you take the idea that we can extract info for terms and that you write the man page in a closure then we can reverse the idea. You'd have: let man t =
let eopt_syn = Term.opt_synopsis "e" t in
let eopt = Term.opt "e" t in
[ `S Manpage.s_synopsis;
`P (strf "$(tname) %s" eopt_syn);
`S Manpage.s_examples;
`P "To search for pattern mysearch issue:";
`P ("$(mname) %s mysearchpattern" eopt); ] and these But these sprintfs may not be very convenient for doc authors. |
A but this we can handle by defining a substitution environment that has to be returned by the fun. let man t =
let ctx = Manvars.(opt_synopsis empty "esyn" ~opt:"e" t) in
let ctx = Manvars.(opt ctx "eopt" ~opt:"e" t) in
ctx,
[ `S Manpage.s_synopsis;
`P "$(tname) $(esyn)";
`S Manpage.s_examples;
`P "To search for pattern mysearch issue:";
`P "$(mname) $(eopt) mysearchpattern"; ] |
I'm a little bit tempted by this |
I like the idea of substitution, one needs to use it anyway for things like let man t =
[ `S Manpage.s_synopsis;
`P "$(tname) $(OPTIONS)"; (* OPTIONS predefined to part of the default synopsis *)
`P "$(tname) $([-e])"; (* here '[-e]' was predefined to be the same as eopt_syn above, i.e. [-e PATTERN]*)
`S Manpage.s_examples;
`P "To search for pattern mysearch issue:";
example("$(mname) $(-e) mysearchpattern"; ]) (* here '-e' was predefined to be '-e' if it exists *)
|
A yes of course, I could do that, you then don't even need the man function. |
So here's a tentative. The first goal is to make sure that what you refer to in the documentation actually exists in the program (hence the [Invalid_argument] raises). The second goal is that this should be sufficient to recreate what cmdliner does for you automatically without pain if you want full control (in fact it would be good if cmdliner's would use this internally) The idea is to be able to project the term, argument and environment variable information OCaml values the client defines in the manpages and be able to access their components and derived information via an optional selector following a dot. A few things that are not covered/problematic:
Commands
The selector are:
Optional arguments
Environment variables
|
To see if I understood this right, is this translation of your earlier example code correct? [ `S Manpage.s_synopsis;
`P "$(tname) $(tname.-e.syn)";
`S Manpage.s_examples;
`P "To search for pattern mysearch issue:";
`P "$(mname) $(mname.-e) $(b,mysearchpattern)"; ] (or maybe I think it is good that the substitutions are fairly comprehensive, though it could get overwhelming trying to pick the right one when actually writing the manpage. Have you considered adding a debug mode? |
Yes.
Not really. I'm not sure that's really needed the debug mode is to actually ask for the manpage and see the result, errors will throw. As for what you are allowed to write it's only a matter of looking at your term definitions. |
What do you suggest in the case of terms provided by upstream libraries? Would you recommend those libraries libraries provide terms with matching man fragments? |
Anything can do. Your library can provide man fragments or simply function that defines arguments. In the latter case you should simply allow the client to specify the man page section in which the arguments should be listed see for example here. |
One thing that should be mentioned in the synopsis is required optional arguments (#82) |
I think the idea here is overkill. In the end I think manually specifying your synopses is "good enough". One thing that I plan to improve though is to specify the synopses of commands in E.g. in
have:
|
Btw @edwintorok cmdliner 1.1.0 will now show options in synopses according to the heuristic spelled out in this message dae9c17 |
Thanks, it might also be useful to automatically list all the subcommands in the main auto-generated synopsis.
But if I were to remove the manual SYNOPSIS and see how an autogenerated one would look like I get this instead:
Although all the subcommands are available further down, having a quick overview at the top might be useful (within reason, probably wouldn't like to put all subcommands there for something like git, for a command with a lot of subcommands a manually curated list of commonly used subcommands in the synopsis might be better). |
I have tried a few things along these lines but so far I was not really convinced, it made it very redundant with the For now I'm happy with hand-crafted synopsis sections. |
I'd like to have a
Help (
Compact, None) that prints output similar to runninggit
,darcs
, oropam
without any arguments, i.e. a list of subcommands and a one-line description for each, enumerating all optional flags in the usage line and a message on how to get the full help.This can be useful to get a quick overview if you have a command with lots of subcommands or lots of flag (for example if you remember what a command/flag does but not what its name was); and it'd also look more familiar to what usual Unix commands do on
--help
.I wouldn't mind if I'd have to do this formatting in my application if Cmdliner provided me with a way to access the flag/subcommand names and their documentation from a
Term.t
, so I'm opening this bug for discussion.The text was updated successfully, but these errors were encountered: