Closed kaushalmodi closed 5 years ago
Internally, a multiple dispatch command is just a generated proc that does the sub-command dispatching which is itself auto-wrapped by dispatchGen
. My hope had been to be able to tune top-level command dispatchGen
parameters (like your usage
need) via the "multi" subcommand as in test/FullyAutoMulti.nim
. That fails to compile in a test I just tried (because the keyword usage
gets sent twice to the generated call to dispatchGen
).
I'm not sure if it ever worked. { I really like my top-level default and haven't tested tweaking it. :-) } In my code I tried to "provide a default", but let the caller override it via this paramPresent
/paramValue
protocol that seems to work in other situations. Let me look into this a little.
In my code I tried to "provide a default", but let the caller override it via this paramPresent/paramValue protocol that seems to work in other situations. Let me look into this a little.
Thank you. Just to better demonstrate the need for usage
, I have this little utility called p4x
. If a user new to this does p4x -h
, they get:
Usage:
p4x {CMD} [sub-command options & parameters]
where {CMD} is one of:
help print comprehensive or per-cmd help
..
There, I would like to give a 1-line description of what p4x
exactly is.
Oh, I get it. What might really be best for your use case is doc
being somewhere in the top level usage template. { doc
is a dispatchGen
keyword param to replace the ##
comment-inferred documentation for the overall function of a wrapped proc. When I first started Nim had a bug where this ##
AST nodes weren't reliable, but it also made sense to let CLI authors override what the API said since CLI users and API users are at least potentially distinct subpopulations of humans. }
With some kind of $doc
interpolation, you wouldn't have to update the usage
or your doc
when you add new subcommands. I just tested that and it doesn't work either, though. :-) I think I may understand my bug, though.
What might really be best for your use case is doc being somewhere in the top level usage template.
Yes, that would work.
As a bonus, can the project url be parsed from a special doc comment, and if found, can that be auto-inserted at an appropriate place in the default help?
Maybe. I might do some staticRead
of a .nimble
file and provide some docFromNimble
proc the way test/Version.nim
does. Or we could do both that and a docFromElsewhere
proc and the CLI author can just put a doc=docFromX()
in the [ "multi", .. ]
section of their dispatchMulti
. That's all the "easy" part. First thing is to get [ "multi", doc="foo" ]
working.
Once I get everything working properly, you should be able both to set doc
and override usage
to say where $doc
goes. In the interest of you needing to do "least of all", though, where do you think that one-liner should go?
The message is a bunch of sub-commands probably "summarized" by the $doc
, and summaries earlier make sense since they give context to the details. So, it's mostly a question of before vs after "Usage:\n". I sort of feel like before looks best, as in:
Convert Helix Version Control / Perforce (p4)-ztag output to JSON
Usage:
p4ztag_to_json {CMD} [sub-command options & parameters]
where {CMD} is one of:
...
(I've been a little of two minds about the extra blank lines in there).
The other question of where we try to grab/default $doc
from is tricky as it kind of depends on how verbose the CLI author wants the usage message/how verbose various text might be. description
out of .nimble
is on the one hand text that was "engineered to be a useful, terse one-line summary".
Another idea might be to default doc
to the module doc comment. That's probably what you meant. In your case something like
The ``p4ztag_to_json`` module converts the Perforce P4 "Ztag" format to JSON.
The pros of that are that it's pretty unlikely a single nim file would compile to more than one dispatchMulti
, and also pretty likely that any overall module doc comment would be the right sort of level of description for the whole group of multi-commands. But it also might be really expansive about methods and context. So, we might want to limit to just the first paragraph or something (or at least have an option for that). That formatting might also be RST for nim doc
instead of plain text which might confuse a CLI user or look ugly.
I'm also not sure if there is a way to get at that module doc comment from within a macro. The nim doc
stuff are all special compiler passes. macros.lineinfo
gives us the path to the source file. So, it might be possible to staticExec
out to some whole customizable pipeline that is given the name of the source file. Anyway, the short of it is that a CLI author might have to say doc=docFromModule()
anyway with some proc that takes at least a few parameters (1st paragraph only, reformat, etc). So, it might be best to have CLI authors "forced to choose a source" for that text than to try to default it to anywhere/anything but ""
.
These are just some of my thoughts on the matter..Not trying to be a last word on anything.
Just for reference, this is what I have for my ntangle project:
NAME
ntangle - Command-line utility for Tangling of Org mode documents
USAGE
ntangle [optional-params] [orgFilesOrDirs: string...]
OPTIONS
-h, --help print this cligen-erated help
--help-syntax advanced: prepend,plurals,..
--version bool false print version
URL
https://github.com/OrgTangle/ntangle
It inspired from perl docs I believe.
where do you think that one-liner should go?
I like your proposal, except that ..
(I've been a little of two minds about the extra blank lines in there).
I like newlines between usage sections .. so may be the below? :)
Convert Helix Version Control / Perforce (p4)-ztag output to JSON
Usage:
p4ztag_to_json {CMD} [sub-command options & parameters]
where {CMD} is one of:
description out of .nimble is on the one hand text that was "engineered to be a useful, terse one-line summary".
I would be fine with that.
So, we might want to limit to just the first paragraph or something (or at least have an option for that).
But I like the parsing of module doc comment, if that's even possible. A cligen user would then need to take care to not use RST in the first paragraph.
Anyway, the short of it is that a CLI author might have to say doc=docFromModule() anyway with some proc that takes at least a few parameters (1st paragraph only, reformat, etc).
No issues with that! I am already liking how I can specify how to construct the --version
string. So this will be something similar, I believe? clCfg.doc = ..
?
Ok. I kind of like your blank line proposal. That's who pijul help
works, too. So, I will probably switch to that as part of fixing this issue (which may take a couple days).
As far as not using RST..Well, part of the idea of cligen
is that the CLI may just be a wrapper around some elsewise-maintained API module, in principle maybe even by two independent people/projects. So, I don't like solutions like "the CLI author can just avoid xyz" when the xyz may not be under their control. Preferred instead are some filtering mechanisms where the CLI author can adapt whatever the API author did/does in the future to the needs of the CLI. { This 3 level aspect of cligen
is not something a lot of people really internalize because they operate on sub-sets of the 3-levels..I myself am API author, CLI author, and CLI user for everything I do with cligen
, but I try to put on my layering abstraction hat in questions like this. } So, some kind of rst2ascii
filter run out of staticExec
is the sort of solution I would tilt towards.
The sub-command dispatcher is its own proc, not unlike one you might just write with its own (currently buggy) dispatchGen
call. That subcommand dispatcher proc doesn't really have parameters with default values. It supports --help
and maybe --version
just in a "can type those options anywhere and get something useful" sort of way. So, of the various interpolating things in usage
(command
, args
, doc
, options
) maybe only $command
and $doc
really make sense. Presently, the usage
used by that one dispatchGen
of the subcmd dispatcher is inflexible. It just hardwires command
to basename(srcfile) and has nothing else. It should probably interpolate just command
and doc
from a ["multi", ..]
overridable usage
. That's what I'm working on now.
To make an overlong response even longer, in the larger world, these "multi-commands" are really not nearly as "standardized" as single-issue commands (not that even thing like --long=, -l=
vs -l=,--long=
or even -h
for --help
are so uniform! --help
is thankfully very standard, but that's about it). cvs
was the first multi-command I ever heard of back in the early 90s. svn
copied that and then the DVCS crowd of hg
/git
/etc. I guess docker
picked up on that which might be creating some converts and busybox
is some other family. And maybe nim
itself, though I think it is more of "mix" than a strict sub-command structure. nim help
does nothing.
Even so, all the multi-dispatch commands in common use probably number in the "low 10s" rather than "many thousands" of regular commands in my /usr/bin
. So, there's just at least two or three orders of magnitude less guidance as to "what people do or expect to happen". Sane default behavior becomes a highly personal thing, dragged around by individuals' experience of their many iterations over very small samples. A "help" subcmd seems mostly standard, but git help
doesn't list all available sub-commands unless you say git help -a
. For others help -a
doesn't work at all. In cligen
the idea that ./test/MultMultMult a c y --ho=2
"just works" might blow some minds [ in maybe both good & bad ways ;-) ].
Something that may interest you is that I've been considering adding an automatic version
subcommand much like the help
subcommand, but only if clCfg.version
is set. hg|git|docker version
all work the same anyway..more so than their respective help
systems. It's more rare than a help
subcommand, though. multi help
is about as universal as single --help
.
cligen
HEAD seems to be working for me. Lets you override a usage
template for dispatchMulti
(and doc
and cmdName
, though cmdName
becomes $command
in the template as with regular dispatch
).
The default template clUseMulti
puts a $doc
right at the beginning. test/FullyAutoMulti.nim
seems to work fine, anyway.
I decided the "where" clause looked better tight up against it's introducer, but if you hate that you can either change the template via ["multi", usage=x]
or you can try to persuade me to not use "where" at all but a "SubCommands:\n"
style section header.
Assuming this all works for you, I think this issue is probably ready to close except for possibly a few minor refinements:
1) Try writing a proc to get a doc
line out of the module doc comment.
2) There are a couple of other help dumps (search for "subcommand-opts" in cligen.nim
) that are not templated yet. We could maybe add a usage2
and usage3
or something. I'm not sure how popular comprehensive help mode even is, though.
3) We could potentially make that burb from "no args at all" to "comprehensive help" into another interpolation variable, but I kind of feel like that material is pretty helpful to people new to multi-commands.
The default template clUseMulti puts a $doc right at the beginning. test/FullyAutoMulti.nim seems to work fine, anyway.
Thanks. Following the changes in that test worked for me too!
Btw TIL that the "multi"
string in there is special : https://github.com/c-blake/cligen/blob/de0ed585766b63696d90d817e4bfd19e40e32e15/test/FullyAutoMulti.nim#L34
I decided the "where" clause looked better tight up against it's introducer, but if you hate that you can either change the template via ["multi", usage=x]
I don't have a strong opinion about that missing blank line before the "where" clause. If it irks me, I will use the usage
key. So thanks for adding that too... Or I might need to use usage
anyways to add the URL bit.
Try writing a proc to get a doc line out of the module doc comment.
This will be nice.
Please feel free to close this issue.
Ok. Closing. Also, if you like the location of the doc line in my default usage
you can just use doc = "my doc line"
. But, yeah, you can just write the entire message in usage
. There could be trouble if you want a literal substring that looks like an interpolation variable, though, like $command
. Maybe there's a way to quote that $
in strutils.%
?
Or I might need to use usage anyways to add the URL bit.
I was trying this ..
dispatchMulti(
[ "multi",
usage = "\nNAME\n p4x (pitchforks) - " & docLine & "\n" &
"USAGE\n $command $args\n\n" &
"OPTIONS\n$options\n" &
"URL\n " & url & "\n" ],
..
but that gives me this error:
cligen.nim(832) p4x
cligen.nim(510) multiSubs
cligen.nim(743) multi
cligen.nim(653) topLevelHelp
strutils.nim(2711) %
strutils.nim(2657) addf
strutils.nim(2600) invalidFormatString
Error: unhandled exception: invalid format string [ValueError]
Let me play with which of the dispatch
-available special $
vars are available with dispatchMulti
too.
There is no $options
for the "multi" usage
. Only $command
, $doc
, $subcmds
, $ifVersion
. See clUseMulti
definition in cligen.nim
.
I could add $options
that expanded to the empty string, but really there aren't any useful options to the multi-cmd dispatch proc (besides -h
/--help
and maybe --version
). "multi", usage=
is not really a cut&paste target for single-dispatch usage
s. This should be documented better, obviously, but you were part of the feature discussion.
Thanks.
I tried adding $subcmds
, but that gives an error too:
dispatchMulti(
[ "multi",
usage = "$subcmds" ],
..
cligen.nim(832) p4x
cligen.nim(362) multiSubs
strutils.nim(2711) %
strutils.nim(2657) addf
strutils.nim(2600) invalidFormatString
Error: unhandled exception: invalid format string [ValueError]
hmm.. order matters...
Update: Doesn't work; the last "multi" element is ineffective in this case.
dispatchMulti(
[ subcmd1 ],
[ subcmd2 ],
[ "multi",
usage = "$subcmds" ]
)
dispatchMulti(
[ "multi",
usage = "$subcmds" ],
[ subcmd1 ],
[ subcmd2 ]
)
Yeah. Order matters. There is at least one place I only check [0]
for that nnkStrLit
node type of the first bracket slot.
Actually, I was wrong .. while putting ["multi",..]
at the end compiles, that whole array is ineffective... the usage
I specify in there is not used at all.
I could probably do some work to allow [ "multi" ] anywhere. To me it makes most sense to me visually at the top since it organizes the subsequent sub-commands. Anyway, it sounds like the at-the-top form is working for you.
Yes, it makes sense to be only at the top; just that $subcmds
doesn't work when "multi" is at top.
Huh. I just confirmed that myself. Not sure why. I will look into this tomorrow. Re-opening until I fix that.
Oh, I see the issue. It's that doc
and usage
are being passed through to the dispatchGen
of the "proc multi" that does the dispatching but that template doesn't understand either $subcmds
or $ifVersion
. This will take a bit to fix, but I'll do it with fresher eyes in my morning. The pass through only happens with explicit passing in the ["multi",..]
bracket. So, for tonight you only have doc
that works. Can't quite change the usage
template.
I think this all works now ("multi" still required to be first slot).
Thank you! I confirm the fix. There was also another issue introduced from my side.. I was doing something like:
usage = "something something $ifVersion" &
"URL" & url
I forgot the "\n"
in there, so the usage
got constructed as something something $ifVersionURL" & url
, and the $ifVersionURL
gave:
cligen.nim(510) p4x
cligen.nim(653) topLevelHelp
strutils.nim(2711) %
strutils.nim(2657) addf
strutils.nim(2600) invalidFormatString
Error: unhandled exception: invalid format string [ValueError]
Now I am bash-style wrapping all the internal cligen vars .. so ${ifVersion}
and so on.
Yeah. I had to do ${doc}Usage:"
. Also, just now I added that docFrom Module
idea as the default if the CLI author specifies no ["multi", doc=x]
. So, you may be able to only tweak usage
. Or if you like my clUseMulti
do nothing at all.
On this sort of topic, though, do you know is there a way to "quote" the $
so that if a doc comment just happens to include the literal substring $command
we don't interpolate it by accident? { Probably in strutils.%
documentation somewhere. I realize I'm just being lazy asking. }
Looks like double-dollar - $$
is the way to quote it. Undocumented - I had to read the parser. ;-)
It looks like the ${}
is also undocumented.
The usage
support was really needed for me. Thanks for adding it.
I now have:
NAME
p4x (pitchforks)
Wrapper around the Perforce p4 binary that cuts down the redundancy and makes life colorful.
USAGE
p4x {SUBCMD} [sub-command options, parameters]
SUBCOMMANDS
help print comprehensive or per-cmd help
edit Open / Check out one or more files for editing.
opened List opened files.
revert Revert one or more files. By default, only unmodified files are reverted.
diff Diff files with respect to the workarea.
changes List changelists.
sync Sync workarea.
files List files in depot.
filelog Show details about files.
describe Describe changelists.
p4x {-h|--help} or with no args at all prints this message.
p4x --help-syntax gives general cligen syntax help.
Run "p4x {help SUBCMD|SUBCMD --help}" to see help for just SUBCMD.
Run "p4x help" to get *comprehensive* help.
Top-level --version also available
URL
https://gitlab.company.com/user/p4x
Also, just now I added that docFrom Module idea as the default if the CLI author specifies no ["multi", doc=x].
Thanks! I just git pulled and tried that and it works.
Just a minor nitpick.. can you please call .strip()
on that parsed doc from module into the internal variable $doc
.. it's adding few extra newlines at the end.
If not, it's not a big deal; I'll use the new docFromModule
.
Well, I already call strip()
, but I add a double newline in that doc
(as well as the demo one in test/FullyAutoMulti.nim
) to get a blank between the one-liner/brief summary and "Usage:"
since the default usage
template is set up to look good with either empty string $doc
or populated $doc
.
I am turning out to be a pain..
the signature of docFromModule
is proc docFromModule*(n: NimNode): string =
.. so I cannot use it directly in my package it seems. How do I get the NimNode
?
ok.. I will also use ${doc}USAGE
as you do then. Earlier I had ${doc}\nUSAGE
.
Update: This works: http://ix.io/1Kxt, but I wish I didn't need to stick the USAGE
bit right next to ${doc}
(I later do [ "multi", usage = topLvlUse.join("\n") ]
).
Yeah. That's why I have protocol be default to the doc comment. Users who have a non-empty module doc comment now need to actively suppress it with ["multi", doc=""]
(or I guess an empty line at top of file). I don't really like that either, but I didn't see an easy workaround. Totally open to suggestions on this, though. If you can come up with a proc we can call from the ["multi", doc=x]
context I will happily include it (and might change the protocol).
As for "${doc}USAGE"
, I am open to suggestions but I don't see a simpler solution that supports both empty and populated $doc
, both of which seem likely cases. I could try some $ifDoc
, but then it gets even uglier. I could put a newline in there, but then that mandates an initial blank for an empty $doc
.
Yeah, I see the reason to do ${doc}USAGE
. I am fine with it because the most importantly, it works as I want! :)
Cool. It just seems easier to have users put in however many blanks they want - zero, one, two, than for me to try to take them out later in some conditional way.
Let me know if you come up with a ["multi", doc=docFromMod()]
that works. If we want to change this it would be ideal to do it before the next cligen
release. I didn't try very hard. I had this macros.lineinfo
thing I had already used to default cmdName
for dispatchMulti
to the basename of the source file. There may be other entry points to that data.
Also, I would not be opposed to putting definitions of clUse
, clUsage
, clUseMulti
into some separate file under cligen/defaults.nim
(or something) and having a "library" of definitions available like clUseMulti2
, clUseMulti3
, etc. That could simplify the call to ["multi", usage=clUseMulti3]
. Or we could name them ["multi", usage=clUseMultiPerlDoc]
or whatever.
having a "library" of definitions available like clUseMulti2, clUseMulti3, etc.
I'd like that. I've become a fan of enum indexed array. So you can have a const clMultiUsage*: array[ClMultiUsage, string] = [ "..", ..]
, where ClMultiUsage
is an enum with values clmuDflt
, clmuPerlDoc
, ..
User then uses .. usage=clMultiUsage[clmuPerlDoc], ..
.
Well, some 3rd party cannot extend my enum sequence, but they can extend the prefixed naming convention. So, if the 2..4 versions distributed with cligen
aren't enough, but they want to make it look similar, they can call it clMultiUsageMine
and put it somewhere convenient for import
/include
if they have several multi-commands. If they want it to look dissimilar, they can do that, too. Plus, just the varname style is shorter.
I'm not against enum indexed arrays, though. I just put one in cligen
for the new style hTabCols*: seq[ClHelpCol]
. I just think for this specific context they're not quite as good as just a variable name.
Well, I went ahead and pushed something along the lines of what I am thinking. I think you can say (roughly) this to get your current message:
usage = clUseMultiPerlish &
"\n\nURI\n " & uriFromNimble(nimbl) &
"\n\nAUTHOR\n " & authorFromNimble(nimbl)
I know it does not look very good when ${doc}
is empty string, but eh..People can use their own string template or just use another clUseMultiX
. All templates looking good with all inputs feels like an overreach. Also, obviously you could inline string literal data instead of using those two new nimble extractors.
Also, maybe now that there are 4 Nimble metadata extractors it should just become fromNimble(field: string, data: string)
. Those calls are all almost brand new. So, I doubt it even needs a deprecation.
I just cleaned up the growing manyFromNimble mess. So, my above example would now become:
usage = clUseMultiPerlish &
"\n\nURI\n " & fromNimble("uri", nimbl) &
"\n\nAUTHOR\n " & fromNimble("author", nimbl)
Let me know if you'd like any changes to clUseMultiPerlish
.
We can let this sit for the weekend, but unless you have a docFromModule()
impl idea or change request for clUseMultiPerlish
by, oh, Monday or so, I am going to punch a new release around then. ["multi",doc=""]
is a pretty terse suppression mechanism (as well as good to know for such users to learn how to set doc
to whatever) and module doc comment is probably the right default, much like proc doc comment is for that situation. I'm less certain about clUseMultiPerlish
, but honestly it's mostly a string just for you. So, feel free to issue a PR or just tell me what would be better. (That's less time sensitive than settling on the new doc
-defaulting protocol.) Have a good weekend.
This Friday turned out to be a whole lot busier than I expected (at work). I intended to try out the new clUseMultiPerlish
(nice name) and give my feedback, but I never got to it.
It read through your changes and they look good. I had earlier suggested enum-indexed array because I did not think that you intended to open up the help string library for 3rd party. So what you have now makes perfect sense.
unless you have a docFromModule() impl idea
I have almost zero experience dealing with macros, so I won't be able to give any valuable idea regarding that.
or change request for clUseMultiPerlish
As soon as I am able to update cligen and try it out, I will definitely give my feedback.
But don't hold off the release for that.
Have a good weekend :)
I think staticRead
could work for docFromMod
(just as it does for fromNimble
) except getting the source file name in the first place. Thinking about it a little more, it isn't so hard. We could do a template sourceOf(pro: typed{nkSym})
or some static string
or something and probably have the proc call that. I really didn't try hard to do it before switching tactics. About the only upside to all that jazz over the current docFromModule
is just A) allow "parameterization" of what paragraph boundaries mean and how much to take (more natural to pass than set in clCfg
?) and B) make docFromModule
callers specify some specific symbol to ID the module in case there are variety of sources of modules defining symbols. But B) is a mixed bag - it's also nice to not have CLI author's have to say anything and get a good default. Inside the dispatchMulti
, I can just take "brackets[1]" (or even search for the first wrapped proc belonging to a module with a non-empty 1st paragraph), but on the flip side there's no way to give docFromMod(sym)
a default parameter equal to some user-defined symbol.
So, mostly it comes down to how likely to be correct we think the current default behavior is/how unnatural parametrizing it through clCfg
would be. The current way is "less work on the lazy CLI author but more of a guestimate". It's hard to assess such likelihood in a vacuum and I don't really have a mailing list of users to ask. It's probably an ok default. We can see if anyone complains, I guess. I don't know how many dispatchMulti
users there even are. I feel like I'm getting close to a near feature complete 1.0 sort of release..Next month or two, really. So, I'm being a little more conscious of interfaces staying mostly backward compatible moving forward.
Things like clUseMultiPerlish
can mutate all around forever, though. I don't think help format changes would ever constitute a breaking change (though any change may be disliked by someone).
Well, I made docFromModuleOf
(note "Of") work the way we had talked about. If a user wants to define their own, they can just define a new string to string extractor like cligen/macUt.summaryOfModule(sourceContents)
and also define their own macro docFromMod*(sym: typed{nkSym}): untyped
to call it and then use it in their doc=
line.
In terms of the default summaryOfModule
, looking at the Nim stdlib all the files start with some single-pound '#' marked copyright notice and blank line. So, we might want to change the logic there to skip all such non-code before the first double-sharp '##' doc comment and call the first "doc paragraph" the first blank-ish thing in that block. I don't know how many Nim modules in the wild will start with a paragraph that is a useful summary in the context of a dispatchMulti
generated command.
For your code, you'll probably just tune your top of module comment text to work right, though. Such a "general functionality summary" to kick off any top-of-module description doesn't strike me as likely to be perceived as bad style by many. So, even if you didn't control that module text, it's unlikely a request to change the text to something like that would be received badly. { And, of course, if you don't want to cede control of your help message to a 3rd party you can just set doc="whatever". }
I just got a chance to get back to my computer.
I quickly tried out the update, and clUseMultiPerlish
looks great!
I also added the extra uri and author (and even version) info to it as suggested from your snippet. Note the I cannot put custom keywords like uri
in the .nimble .. nimble
doesn't like it. I get error when doing nimble install
if the .nimble has any custom keywords.
For your code, you'll probably just tune your top of module comment text to work right, though.
I am already doing that, so not an issue :)
You have put in a whole lot of work from my feature request, and I'm really grateful for this. Thanks!
I also tried out docFromModuleOf
as:
dispatchMulti(
[ "multi", doc = docFromModuleOf(<MODULENAME>), usage = topLvlUse ],
..
May I suggest updating the readme to clarify that docFromModuleOf
take identifier input where the identifier can be the module name (i.e. for a package named foo.nim
, the identifer would be foo
), or a an exported proc identifier in that module (e.g. foo.exportedProc1
). I see that you have the example of using MODULE.PROC
in your tests.
Glad you like clUseMultiPerlish
. docFromModuleOf
probably works with any identifier - type name, proc name, template, module, iterator, etc. I think it's just any "symbol" defined in the module you want to select, module-qualified or unqualified. I try to suggest that in the release notes and the doc comment for docFromModuleOf
by saying mySym
/mySymbol
. I assume you meant RELEASE_NOTES.md not README.md. I'll try to make it more explicit. That a module name works probably relates to one of my issues over at the Nim compiler: https://github.com/nim-lang/Nim/issues/11052 where Araq told us that modules contain themselves intentionally which was news to me.
Actually, while docFromModuleOf
works with various idents, it always gets the source file for the caller of dispatchMulti
, not the module defining the target symbol (those are different if you are wrapping an import
ed symbol). So, I just dropped documentation/highlighting of that entirely until maybe someday we get a better impl and punched a release.
Hello,
For a single
dispatch
, I like using a customusage
string pattern like below:But how can I do that for the top-most level command in
dispatchMulti
?I tried doing below but that of course didn't work:
My main purpose to specify the
usage
is so that I can add a brief description of what the command does, and put in the url of the source at the end.