mirror of
https://github.com/daylinmorgan/hwylterm.git
synced 2025-01-02 15:30:44 -06:00
Compare commits
7 commits
2a5dce888d
...
cbeefd675c
Author | SHA1 | Date | |
---|---|---|---|
cbeefd675c | |||
2b2bf15fb9 | |||
de798fff70 | |||
9e35d4ea12 | |||
88572a6ce4 | |||
b21a889a8d | |||
22fbc66c8b |
3 changed files with 156 additions and 60 deletions
|
@ -14,13 +14,16 @@ type
|
||||||
HwylFlagHelp* = tuple
|
HwylFlagHelp* = tuple
|
||||||
short, long, description: string
|
short, long, description: string
|
||||||
HwylSubCmdHelp* = tuple
|
HwylSubCmdHelp* = tuple
|
||||||
name, desc: string
|
name, aliases, desc: string
|
||||||
|
HwylCliStyleSetting = enum
|
||||||
|
Aliases
|
||||||
HwylCliStyles* = object
|
HwylCliStyles* = object
|
||||||
header* = "bold cyan"
|
header* = "bold cyan"
|
||||||
flagShort* = "yellow"
|
flagShort* = "yellow"
|
||||||
flagLong* = "magenta"
|
flagLong* = "magenta"
|
||||||
flagDesc* = ""
|
flagDesc* = ""
|
||||||
cmd* = "bold"
|
cmd* = "bold"
|
||||||
|
settings*: set[HwylCliStyleSetting] = {Aliases}
|
||||||
HwylCliHelp* = object
|
HwylCliHelp* = object
|
||||||
usage*: string
|
usage*: string
|
||||||
desc*: string
|
desc*: string
|
||||||
|
@ -41,8 +44,12 @@ func newHwylCliHelp*(
|
||||||
styles = HwylCliStyles()
|
styles = HwylCliStyles()
|
||||||
): HwylCliHelp =
|
): HwylCliHelp =
|
||||||
result.desc = dedent(desc).strip()
|
result.desc = dedent(desc).strip()
|
||||||
result.subcmds =
|
if Aliases in styles.settings:
|
||||||
subcmds.mapIt((it.name, it.desc.firstLine))
|
result.subcmds =
|
||||||
|
subcmds.mapIt((it.name & " " & it.aliases, it.aliases, it.desc.firstLine))
|
||||||
|
else:
|
||||||
|
result.subcmds =
|
||||||
|
subcmds.mapIt((it.name, it.aliases, it.desc.firstLine))
|
||||||
result.usage = dedent(usage).strip()
|
result.usage = dedent(usage).strip()
|
||||||
result.flags = @flags
|
result.flags = @flags
|
||||||
result.styles = styles
|
result.styles = styles
|
||||||
|
@ -147,6 +154,7 @@ type
|
||||||
long*: string
|
long*: string
|
||||||
help*: NimNode
|
help*: NimNode
|
||||||
group*: string
|
group*: string
|
||||||
|
inherited*: bool
|
||||||
|
|
||||||
Inherit = object
|
Inherit = object
|
||||||
settings: set[CliSetting]
|
settings: set[CliSetting]
|
||||||
|
@ -154,6 +162,8 @@ type
|
||||||
groups: seq[string]
|
groups: seq[string]
|
||||||
|
|
||||||
CliCfg = object
|
CliCfg = object
|
||||||
|
name*: string
|
||||||
|
alias*: HashSet[string]
|
||||||
stopWords*: seq[string]
|
stopWords*: seq[string]
|
||||||
styles: NimNode
|
styles: NimNode
|
||||||
hidden*: seq[string]
|
hidden*: seq[string]
|
||||||
|
@ -161,7 +171,6 @@ type
|
||||||
settings*: set[CliSetting]
|
settings*: set[CliSetting]
|
||||||
preSub*, postSub*, pre*, post*, run*: NimNode
|
preSub*, postSub*, pre*, post*, run*: NimNode
|
||||||
desc*: NimNode
|
desc*: NimNode
|
||||||
name*: string
|
|
||||||
subName*: string # used for help the generator
|
subName*: string # used for help the generator
|
||||||
version*, usage*: NimNode
|
version*, usage*: NimNode
|
||||||
flags*: seq[CliFlag]
|
flags*: seq[CliFlag]
|
||||||
|
@ -171,12 +180,33 @@ type
|
||||||
inherit*: Inherit
|
inherit*: Inherit
|
||||||
root*: bool
|
root*: bool
|
||||||
|
|
||||||
# some debug procs I use to wrap my ahead aroung the magic of *macro*
|
template `<<<`(s: string) {.used.} =
|
||||||
func `<<<`(n: NimNode) {.used.} =
|
let pos = instantiationInfo()
|
||||||
## for debugging macros
|
debugEcho "$1:$2" % [pos.filename, $pos.line]
|
||||||
debugEcho treeRepr n
|
|
||||||
func `<<<`(s: string) {.used.} =
|
|
||||||
debugEcho s
|
debugEcho s
|
||||||
|
debugEcho "^^^^^^^^^^^^^^^^^^^^^"
|
||||||
|
|
||||||
|
# some debug procs I use to wrap my ahead aroung the magic of *macro*
|
||||||
|
template `<<<`(n: NimNode) {.used.} =
|
||||||
|
## for debugging macros
|
||||||
|
<<< treeRepr n
|
||||||
|
|
||||||
|
|
||||||
|
func `<<<`(f: CliFlag) {.used.}=
|
||||||
|
var s: string
|
||||||
|
let fields = [
|
||||||
|
("name", f.name),
|
||||||
|
("long", f.long),
|
||||||
|
("short", $f.short),
|
||||||
|
("typeNode", f.typeNode.lispRepr),
|
||||||
|
("group", f.group)
|
||||||
|
]
|
||||||
|
s.add "CliFlag(\n"
|
||||||
|
for (k,v) in fields:
|
||||||
|
s.add "$1 = $2\n" % [k,v]
|
||||||
|
s.add ")"
|
||||||
|
<<< s
|
||||||
|
|
||||||
|
|
||||||
func bad(n: NimNode, argument: string = "") =
|
func bad(n: NimNode, argument: string = "") =
|
||||||
var msg = "unexpected node kind: " & $n.kind
|
var msg = "unexpected node kind: " & $n.kind
|
||||||
|
@ -258,7 +288,6 @@ func parseCliFlags(cfg: var CliCfg, node: NimNode) =
|
||||||
var group: string
|
var group: string
|
||||||
expectKind node, nnkStmtList
|
expectKind node, nnkStmtList
|
||||||
for n in node:
|
for n in node:
|
||||||
<<< n
|
|
||||||
var flag: CliFlag
|
var flag: CliFlag
|
||||||
case n.kind
|
case n.kind
|
||||||
of nnkCall, nnkCommand:
|
of nnkCall, nnkCommand:
|
||||||
|
@ -372,28 +401,30 @@ func inheritFrom(child: var CliCfg, parent: CliCfg) =
|
||||||
|
|
||||||
for f in flags:
|
for f in flags:
|
||||||
if f notin pflags:
|
if f notin pflags:
|
||||||
error "expected parent command to define flag: " & f
|
error "expected parent command to have flag: " & f
|
||||||
else:
|
else:
|
||||||
child.flags.add pflags[f]
|
child.flags.add pflags[f]
|
||||||
|
# so subcommands can continue the inheritance
|
||||||
|
child.flagDefs.add pflags[f]
|
||||||
|
|
||||||
for g in groups:
|
for g in groups:
|
||||||
if g notin pgroups:
|
if g notin pgroups:
|
||||||
error "expected parent command to define flag group " & g
|
error "expected parent command to have flag group " & g
|
||||||
else:
|
else:
|
||||||
child.flags &= pgroups[g]
|
child.flags.add pgroups[g]
|
||||||
|
# so subcommands can continue the inheritance
|
||||||
|
child.flagDefs.add pgroups[g]
|
||||||
|
|
||||||
func parseCliSubcommands(cfg: var CliCfg, node: NimNode) =
|
func parseCliSubcommands(cfg: var CliCfg, node: NimNode) =
|
||||||
expectKind node[1], nnkStmtList
|
expectKind node[1], nnkStmtList
|
||||||
for (name, s) in sliceStmts(node[1]):
|
for (name, s) in sliceStmts(node[1]):
|
||||||
cfg.stopWords.add name
|
|
||||||
var subCfg = parseCliBody(
|
var subCfg = parseCliBody(
|
||||||
nnkStmtList.newTree(node[1][s]), cfg.name & " " & name
|
nnkStmtList.newTree(node[1][s]), cfg.name & " " & name
|
||||||
)
|
)
|
||||||
subCfg.subName = name
|
subCfg.subName = name
|
||||||
subCfg.inheritFrom(cfg)
|
cfg.stopWords.add name
|
||||||
cfg.subcommands.add subCfg
|
cfg.stopWords.add subCfg.alias.toSeq()
|
||||||
|
cfg.subcommands.add subCfg
|
||||||
|
|
||||||
func parseHiddenFlags(cfg: var CliCfg, node: NimNode) =
|
func parseHiddenFlags(cfg: var CliCfg, node: NimNode) =
|
||||||
template check =
|
template check =
|
||||||
|
@ -443,9 +474,30 @@ func addBuiltinFlags(cfg: var CliCfg) =
|
||||||
node: versionNode
|
node: versionNode
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
func pasrseCliAlias(cfg: var CliCfg, node: NimNode) =
|
||||||
|
# node[0] is "alias"
|
||||||
|
for n in node[1..^1]:
|
||||||
|
case n.kind
|
||||||
|
of nnkIdent, nnkStrLit:
|
||||||
|
cfg.alias.incl n.strVal
|
||||||
|
of nnkAccQuoted:
|
||||||
|
let s = n.mapIt(it.strVal).join("")
|
||||||
|
cfg.alias.incl s
|
||||||
|
else: bad(n, "alias")
|
||||||
|
|
||||||
|
func propagate(c: var CliCfg) =
|
||||||
|
for child in c.subcommands.mitems:
|
||||||
|
child.pre = c.preSub
|
||||||
|
child.post = c.postSub
|
||||||
|
child.inheritFrom(c)
|
||||||
|
propagate(child)
|
||||||
|
|
||||||
|
|
||||||
func parseCliBody(body: NimNode, name = "", root = false): CliCfg =
|
func parseCliBody(body: NimNode, name = "", root = false): CliCfg =
|
||||||
result.name = name
|
result.name = name
|
||||||
result.root = root
|
result.root = root
|
||||||
|
# TDOO: change call to n or node?
|
||||||
for call in body:
|
for call in body:
|
||||||
if call.kind notin [nnkCall, nnkCommand, nnkPrefix]:
|
if call.kind notin [nnkCall, nnkCommand, nnkPrefix]:
|
||||||
error "unexpected node kind: " & $call.kind
|
error "unexpected node kind: " & $call.kind
|
||||||
|
@ -454,6 +506,9 @@ func parseCliBody(body: NimNode, name = "", root = false): CliCfg =
|
||||||
of "name":
|
of "name":
|
||||||
expectKind call[1], nnkStrLit
|
expectKind call[1], nnkStrLit
|
||||||
result.name = call[1].strVal
|
result.name = call[1].strVal
|
||||||
|
of "alias":
|
||||||
|
if root: error "alias not supported for root command"
|
||||||
|
pasrseCliAlias(result, call)
|
||||||
of "version", "V":
|
of "version", "V":
|
||||||
result.version = call[1]
|
result.version = call[1]
|
||||||
of "usage", "?":
|
of "usage", "?":
|
||||||
|
@ -482,16 +537,19 @@ func parseCliBody(body: NimNode, name = "", root = false): CliCfg =
|
||||||
result.postSub = call[1]
|
result.postSub = call[1]
|
||||||
else:
|
else:
|
||||||
error "unknown hwylCli setting: " & name
|
error "unknown hwylCli setting: " & name
|
||||||
|
#
|
||||||
for sub in result.subcommands.mitems:
|
# for sub in result.subcommands.mitems:
|
||||||
sub.pre = result.preSub
|
# # sub.inheritFrom(result)
|
||||||
sub.post = result.postSub
|
# sub.pre = result.preSub
|
||||||
|
# sub.post = result.postSub
|
||||||
|
|
||||||
if result.name == "":
|
if result.name == "":
|
||||||
error "missing required option: name"
|
error "missing required option: name"
|
||||||
|
|
||||||
# TODO: validate "required" flags exist here
|
# TODO: validate "required" flags exist here
|
||||||
result.addBuiltinFlags()
|
result.addBuiltinFlags()
|
||||||
|
if root:
|
||||||
|
propagate(result)
|
||||||
|
|
||||||
func flagToTuple(f: CliFlag | BuiltinFlag): NimNode =
|
func flagToTuple(f: CliFlag | BuiltinFlag): NimNode =
|
||||||
let
|
let
|
||||||
|
@ -515,9 +573,10 @@ func subCmdsArray(cfg: CliCfg): NimNode =
|
||||||
result = newTree(nnkBracket)
|
result = newTree(nnkBracket)
|
||||||
for s in cfg.subcommands:
|
for s in cfg.subcommands:
|
||||||
let cmd = newLit(s.subName)
|
let cmd = newLit(s.subName)
|
||||||
|
let aliases = newLit(s.alias.mapIt("($1)" % [it]).join(" "))
|
||||||
let desc = s.desc or newLit("")
|
let desc = s.desc or newLit("")
|
||||||
result.add quote do:
|
result.add quote do:
|
||||||
(`cmd`, `desc`)
|
(`cmd`, `aliases`, `desc`)
|
||||||
|
|
||||||
proc hwylCliError*(msg: string | BbString) =
|
proc hwylCliError*(msg: string | BbString) =
|
||||||
quit $(bb("error ", "red") & bb(msg))
|
quit $(bb("error ", "red") & bb(msg))
|
||||||
|
@ -547,13 +606,21 @@ func generateCliHelperProc(cfg: CliCfg, printHelpName: NimNode): NimNode =
|
||||||
styles = `styles`,
|
styles = `styles`,
|
||||||
)))
|
)))
|
||||||
|
|
||||||
|
proc preParseCheck(key: string, val: string) =
|
||||||
|
if val == "":
|
||||||
|
hwylCliError(
|
||||||
|
"expected value for flag: [b]" & key
|
||||||
|
)
|
||||||
|
|
||||||
proc parse*(p: OptParser, key: string, val: string, target: var bool) =
|
proc parse*(p: OptParser, key: string, val: string, target: var bool) =
|
||||||
target = true
|
target = true
|
||||||
|
|
||||||
proc parse*(p: OptParser, key: string, val: string, target: var string) =
|
proc parse*(p: OptParser, key: string, val: string, target: var string) =
|
||||||
|
preParseCheck(key, val)
|
||||||
target = val
|
target = val
|
||||||
|
|
||||||
proc parse*(p: OptParser, key: string, val: string, target: var int) =
|
proc parse*(p: OptParser, key: string, val: string, target: var int) =
|
||||||
|
preParseCheck(key, val)
|
||||||
try:
|
try:
|
||||||
target = parseInt(val)
|
target = parseInt(val)
|
||||||
except:
|
except:
|
||||||
|
@ -569,15 +636,17 @@ macro enumNames(a: typed): untyped =
|
||||||
result.add newLit ai.strVal
|
result.add newLit ai.strVal
|
||||||
|
|
||||||
proc parse*[E: enum](p: OptParser, key: string, val: string, target: var E) =
|
proc parse*[E: enum](p: OptParser, key: string, val: string, target: var E) =
|
||||||
|
preParseCheck(key, val)
|
||||||
try:
|
try:
|
||||||
target = parseEnum[E](val)
|
target = parseEnum[E](val)
|
||||||
except:
|
except:
|
||||||
let choices = enumNames(E).join(",")
|
let choices = enumNames(E).join(",")
|
||||||
hwylCliError(
|
hwylCliError(
|
||||||
"failed to parse value for [b]" & key & "[/] as enum: [b]" & val & "[/], expected one of: " & choices
|
"failed to parse value for [b]" & key & "[/] as enum: [b]" & val & "[/] expected one of: " & choices
|
||||||
)
|
)
|
||||||
|
|
||||||
proc parse*(p: OptParser, key: string, val: string, target: var float) =
|
proc parse*(p: OptParser, key: string, val: string, target: var float) =
|
||||||
|
preParseCheck(key, val)
|
||||||
try:
|
try:
|
||||||
target = parseFloat(val)
|
target = parseFloat(val)
|
||||||
except:
|
except:
|
||||||
|
@ -586,6 +655,7 @@ proc parse*(p: OptParser, key: string, val: string, target: var float) =
|
||||||
)
|
)
|
||||||
|
|
||||||
proc parse*[T](p: OptParser, key: string, val: string, target: var seq[T]) =
|
proc parse*[T](p: OptParser, key: string, val: string, target: var seq[T]) =
|
||||||
|
preParseCheck(key, val)
|
||||||
var parsed: T
|
var parsed: T
|
||||||
parse(p, key, val, parsed)
|
parse(p, key, val, parsed)
|
||||||
target.add parsed
|
target.add parsed
|
||||||
|
@ -655,11 +725,15 @@ func getNoVals(cfg: CliCfg): tuple[long: NimNode, short: NimNode] =
|
||||||
result = (nnkPrefix.newTree(ident"@",long), short)
|
result = (nnkPrefix.newTree(ident"@",long), short)
|
||||||
|
|
||||||
func setFlagVars(cfg: CliCfg): NimNode =
|
func setFlagVars(cfg: CliCfg): NimNode =
|
||||||
result = nnkVarSection.newTree().add(
|
## generate all variables not covered in global module
|
||||||
cfg.flags.mapIt(
|
result = nnkVarSection.newTree()
|
||||||
nnkIdentDefs.newTree(it.ident, it.typeNode, newEmptyNode())
|
let flags =
|
||||||
)
|
if cfg.root: cfg.flags
|
||||||
)
|
else: cfg.flags.filterIt(it.group != "global")
|
||||||
|
|
||||||
|
result.add flags.mapIt(
|
||||||
|
nnkIdentDefs.newTree(it.ident, it.typeNode, newEmptyNode())
|
||||||
|
)
|
||||||
|
|
||||||
func literalFlags(f: CliFlag): NimNode =
|
func literalFlags(f: CliFlag): NimNode =
|
||||||
var flags: seq[string]
|
var flags: seq[string]
|
||||||
|
@ -694,6 +768,38 @@ func addPostParseCheck(cfg: CliCfg, body: NimNode) =
|
||||||
if `name` notin `flagSet`:
|
if `name` notin `flagSet`:
|
||||||
`target` = `default`
|
`target` = `default`
|
||||||
|
|
||||||
|
func hwylCliImpl(cfg: CliCfg): NimNode
|
||||||
|
|
||||||
|
func genSubcommandHandler(cfg: CliCfg): NimNode =
|
||||||
|
let args = ident"args"
|
||||||
|
result = nnkStmtList.newTree()
|
||||||
|
result.add quote do:
|
||||||
|
if `args`.len == 0:
|
||||||
|
hwylCliError("expected subcommand")
|
||||||
|
|
||||||
|
var subCommandCase = nnkCaseStmt.newTree()
|
||||||
|
if NoNormalize notin cfg.settings:
|
||||||
|
subCommandCase.add(quote do: optionNormalize(`args`[0]))
|
||||||
|
else:
|
||||||
|
subCommandCase.add(quote do: `args`[0])
|
||||||
|
|
||||||
|
for sub in cfg.subcommands:
|
||||||
|
var branch = nnkOfBranch.newTree()
|
||||||
|
branch.add newLit(optionNormalize(sub.subName))
|
||||||
|
for a in sub.alias:
|
||||||
|
branch.add newLit(optionNormalize(a))
|
||||||
|
branch.add hwylCliImpl(sub)
|
||||||
|
subcommandCase.add branch
|
||||||
|
|
||||||
|
subcommandCase.add nnkElse.newTree(
|
||||||
|
quote do:
|
||||||
|
hwylCliError("unknown subcommand: [b]" & `args`[0])
|
||||||
|
)
|
||||||
|
|
||||||
|
result.add subCommandCase
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
func hwylCliImpl(cfg: CliCfg): NimNode =
|
func hwylCliImpl(cfg: CliCfg): NimNode =
|
||||||
let
|
let
|
||||||
version = cfg.version or newLit("")
|
version = cfg.version or newLit("")
|
||||||
|
@ -779,29 +885,7 @@ func hwylCliImpl(cfg: CliCfg): NimNode =
|
||||||
runBody.add cfg.post
|
runBody.add cfg.post
|
||||||
|
|
||||||
if cfg.subcommands.len > 0:
|
if cfg.subcommands.len > 0:
|
||||||
var handleSubCommands = nnkStmtList.newTree()
|
runBody.add genSubcommandHandler(cfg)
|
||||||
handleSubCommands.add quote do:
|
|
||||||
if `args`.len == 0:
|
|
||||||
hwylCliError("expected subcommand")
|
|
||||||
|
|
||||||
var subCommandCase = nnkCaseStmt.newTree()
|
|
||||||
if NoNormalize notin cfg.settings:
|
|
||||||
subCommandCase.add(quote do: optionNormalize(`args`[0]))
|
|
||||||
else:
|
|
||||||
subCommandCase.add(quote do: `args`[0])
|
|
||||||
|
|
||||||
for sub in cfg.subcommands:
|
|
||||||
subCommandCase.add nnkOfBranch.newTree(
|
|
||||||
newLit(optionNormalize(sub.subName)),
|
|
||||||
hwylCliImpl(sub)
|
|
||||||
)
|
|
||||||
|
|
||||||
subcommandCase.add nnkElse.newTree(
|
|
||||||
quote do:
|
|
||||||
hwylCliError("unknown subcommand: [b]" & `args`[0])
|
|
||||||
)
|
|
||||||
|
|
||||||
runBody.add handleSubCommands.add subCommandCase
|
|
||||||
|
|
||||||
result.add quote do:
|
result.add quote do:
|
||||||
# block:
|
# block:
|
||||||
|
@ -814,7 +898,6 @@ func hwylCliImpl(cfg: CliCfg): NimNode =
|
||||||
let `args` {.used.} = `parserProcName`(`cmdLine`)
|
let `args` {.used.} = `parserProcName`(`cmdLine`)
|
||||||
`runBody`
|
`runBody`
|
||||||
|
|
||||||
# if cfg.root and (GenerateOnly notin cfg.settings):
|
|
||||||
if cfg.root:
|
if cfg.root:
|
||||||
if GenerateOnly notin cfg.settings:
|
if GenerateOnly notin cfg.settings:
|
||||||
result.add quote do:
|
result.add quote do:
|
||||||
|
|
|
@ -13,6 +13,9 @@ hwylCli:
|
||||||
... "a description of hwylterm"
|
... "a description of hwylterm"
|
||||||
flags:
|
flags:
|
||||||
[global]
|
[global]
|
||||||
|
color:
|
||||||
|
T Color
|
||||||
|
? "a color (red, green, blue)"
|
||||||
yes:
|
yes:
|
||||||
T bool
|
T bool
|
||||||
? "set flag to yes"
|
? "set flag to yes"
|
||||||
|
@ -25,10 +28,12 @@ hwylCli:
|
||||||
* @["config.yml"]
|
* @["config.yml"]
|
||||||
preSub:
|
preSub:
|
||||||
echo "this is run after subcommand parsing but before its run block"
|
echo "this is run after subcommand parsing but before its run block"
|
||||||
|
echo fmt"{yes=}, {color=}"
|
||||||
run:
|
run:
|
||||||
echo "this is always run prior to subcommand parsing"
|
echo "this is always run prior to subcommand parsing"
|
||||||
|
echo fmt"{yes=}, {color=}"
|
||||||
subcommands:
|
subcommands:
|
||||||
[onelonger]
|
[one]
|
||||||
... """
|
... """
|
||||||
the first subcommand
|
the first subcommand
|
||||||
|
|
||||||
|
@ -36,15 +41,21 @@ hwylCli:
|
||||||
it also inherits the `[[shared]` flag group
|
it also inherits the `[[shared]` flag group
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
alias o
|
||||||
flags:
|
flags:
|
||||||
color:
|
|
||||||
T Color
|
|
||||||
? "a color (red, green, blue)"
|
|
||||||
verbose:
|
verbose:
|
||||||
T Count
|
T Count
|
||||||
? "a count flag"
|
? "a count flag"
|
||||||
- v
|
- v
|
||||||
^[shared]
|
^[shared]
|
||||||
|
subcommands:
|
||||||
|
[subsub]
|
||||||
|
... "another level down subcommand"
|
||||||
|
flags:
|
||||||
|
^config
|
||||||
|
run:
|
||||||
|
echo fmt"{color=}"
|
||||||
|
|
||||||
run:
|
run:
|
||||||
echo "hello from `example one` command!"
|
echo "hello from `example one` command!"
|
||||||
echo args
|
echo args
|
||||||
|
@ -52,7 +63,7 @@ hwylCli:
|
||||||
echo fmt"{verbose=}"
|
echo fmt"{verbose=}"
|
||||||
echo fmt"{config=}"
|
echo fmt"{config=}"
|
||||||
|
|
||||||
["two-longer"]
|
[two]
|
||||||
... """
|
... """
|
||||||
some second subcommand
|
some second subcommand
|
||||||
|
|
||||||
|
|
6
todo.md
6
todo.md
|
@ -18,8 +18,10 @@
|
||||||
|
|
||||||
- [ ] add support for types(metavars)/defaults/required in help output
|
- [ ] add support for types(metavars)/defaults/required in help output
|
||||||
- [ ] add nargs to CliCfg
|
- [ ] add nargs to CliCfg
|
||||||
- [ ] add support for inheriting a single flag from parent (even from a "group")
|
- [x] add support for inheriting a single flag from parent (even from a "group")
|
||||||
- [ ] add support to either (lengthen commands) or provide an alias for a subcommand
|
- [x] add support to either (lengthen commands) or provide an alias for a subcommand
|
||||||
|
- [x] add command aliases to hwylcli help with switch
|
||||||
|
- [ ] don't recreate "global"" variables in var section
|
||||||
|
|
||||||
|
|
||||||
## features
|
## features
|
||||||
|
|
Loading…
Reference in a new issue