mirror of
https://github.com/daylinmorgan/hwylterm.git
synced 2024-12-21 18:50:44 -06:00
Compare commits
9 commits
f1cc95f86e
...
c5f70cec4e
Author | SHA1 | Date | |
---|---|---|---|
c5f70cec4e | |||
748f7e1bd6 | |||
938131c6cd | |||
ab00305c92 | |||
5a236cd6a5 | |||
88a0bc2ffe | |||
b6a97899fc | |||
fdec798b30 | |||
c80c0d3db9 |
3 changed files with 158 additions and 78 deletions
|
@ -138,6 +138,10 @@ proc bb*(cli: HwylCliHelp): BbString =
|
||||||
type
|
type
|
||||||
Count* = object ## Count type for an incrementing flag
|
Count* = object ## Count type for an incrementing flag
|
||||||
val*: int
|
val*: int
|
||||||
|
KV*[X,Y] = object ## basic key value type
|
||||||
|
key*: X
|
||||||
|
val*: Y
|
||||||
|
KVString* = KV[string, string]
|
||||||
|
|
||||||
type
|
type
|
||||||
CliSetting* = enum
|
CliSetting* = enum
|
||||||
|
@ -159,6 +163,7 @@ type
|
||||||
ident*: NimNode
|
ident*: NimNode
|
||||||
default*: NimNode
|
default*: NimNode
|
||||||
typeNode*: NimNode
|
typeNode*: NimNode
|
||||||
|
node*: NimNode
|
||||||
short*: char
|
short*: char
|
||||||
long*: string
|
long*: string
|
||||||
help*: NimNode
|
help*: NimNode
|
||||||
|
@ -173,21 +178,25 @@ type
|
||||||
CliHelp = object
|
CliHelp = object
|
||||||
header*, footer*, description*, usage*, styles*: NimNode
|
header*, footer*, description*, usage*, styles*: NimNode
|
||||||
|
|
||||||
|
CliArg = object
|
||||||
|
|
||||||
CliCfg = object
|
CliCfg = object
|
||||||
name*: string
|
name*: string
|
||||||
alias*: HashSet[string]
|
alias*: HashSet[string] # only supported in subcommands
|
||||||
|
version*: NimNode
|
||||||
stopWords*: seq[string]
|
stopWords*: seq[string]
|
||||||
help: CliHelp
|
help: CliHelp
|
||||||
hidden*: seq[string]
|
defaultFlagType: NimNode
|
||||||
subcommands: seq[CliCfg]
|
required*: seq[string]
|
||||||
settings*: set[CliSetting]
|
settings*: set[CliSetting]
|
||||||
|
subName*: string # used for help generator
|
||||||
|
subcommands: seq[CliCfg]
|
||||||
preSub*, postSub*, pre*, post*, run*: NimNode
|
preSub*, postSub*, pre*, post*, run*: NimNode
|
||||||
subName*: string # used for help the generator
|
hidden*: seq[string]
|
||||||
version*: NimNode
|
args*: seq[CliArg]
|
||||||
flags*: seq[CliFlag]
|
flags*: seq[CliFlag]
|
||||||
builtinFlags*: seq[BuiltinFlag]
|
builtinFlags*: seq[BuiltinFlag]
|
||||||
flagDefs*: seq[CliFlag]
|
flagDefs*: seq[CliFlag]
|
||||||
required*: seq[string]
|
|
||||||
inherit*: Inherit
|
inherit*: Inherit
|
||||||
root*: bool
|
root*: bool
|
||||||
|
|
||||||
|
@ -256,12 +265,14 @@ func parseFlagParams(f: var CliFlag, node: NimNode) =
|
||||||
f.ident = getFlagParamNode(n).strVal.ident
|
f.ident = getFlagParamNode(n).strVal.ident
|
||||||
of "T":
|
of "T":
|
||||||
f.typeNode = n[1]
|
f.typeNode = n[1]
|
||||||
|
of "node":
|
||||||
|
f.node = n[1]
|
||||||
else:
|
else:
|
||||||
error "unexpected setting: " & n[0].strVal
|
error "unexpected setting: " & n[0].strVal
|
||||||
else:
|
else:
|
||||||
bad(n, "flag params")
|
bad(n, "flag params")
|
||||||
|
|
||||||
func startFlag(f: var CliFlag, n: NimNode) =
|
func newFlag(f: var CliFlag, n: NimNode) =
|
||||||
f.name =
|
f.name =
|
||||||
case n[0].kind
|
case n[0].kind
|
||||||
of nnkIdent, nnkStrLit: n[0].strVal
|
of nnkIdent, nnkStrLit: n[0].strVal
|
||||||
|
@ -280,11 +291,12 @@ func parseCliFlag(n: NimNode): CliFlag =
|
||||||
if n.kind notin [nnkCommand, nnkCall]:
|
if n.kind notin [nnkCommand, nnkCall]:
|
||||||
bad(n, "flags")
|
bad(n, "flags")
|
||||||
|
|
||||||
startFlag(result, n)
|
newFlag(result, n)
|
||||||
# option "some help desc"
|
# option "some help desc"
|
||||||
if n.kind == nnkCommand:
|
if n.kind == nnkCommand:
|
||||||
result.help = n[1]
|
result.help = n[1]
|
||||||
# option:
|
# option:
|
||||||
|
# T string
|
||||||
# help "some help description"
|
# help "some help description"
|
||||||
else:
|
else:
|
||||||
parseFlagParams(result, n[1])
|
parseFlagParams(result, n[1])
|
||||||
|
@ -294,7 +306,14 @@ func parseCliFlag(n: NimNode): CliFlag =
|
||||||
if result.typeNode == nil:
|
if result.typeNode == nil:
|
||||||
result.typeNode = ident"bool"
|
result.typeNode = ident"bool"
|
||||||
|
|
||||||
# TODO: change how this works?
|
func postParse(cfg: var CliCfg) =
|
||||||
|
let defaultTypeNode = cfg.defaultFlagType or ident"bool"
|
||||||
|
for f in cfg.flagDefs.mitems:
|
||||||
|
if f.typeNode == nil:
|
||||||
|
f.typeNode = defaultTypeNode
|
||||||
|
if f.group in ["", "global"]:
|
||||||
|
cfg.flags.add f
|
||||||
|
|
||||||
func parseCliFlags(cfg: var CliCfg, node: NimNode) =
|
func parseCliFlags(cfg: var CliCfg, node: NimNode) =
|
||||||
var group: string
|
var group: string
|
||||||
expectKind node, nnkStmtList
|
expectKind node, nnkStmtList
|
||||||
|
@ -323,10 +342,8 @@ func parseCliFlags(cfg: var CliCfg, node: NimNode) =
|
||||||
of nnkIdent, nnkStrLit:
|
of nnkIdent, nnkStrLit:
|
||||||
cfg.inherit.flags.add n[1].strval
|
cfg.inherit.flags.add n[1].strval
|
||||||
else: bad(n, "flag")
|
else: bad(n, "flag")
|
||||||
|
|
||||||
else: bad(n, "flag")
|
else: bad(n, "flag")
|
||||||
|
|
||||||
cfg.flags = cfg.flagDefs.filterIt(it.group in ["", "global"])
|
|
||||||
|
|
||||||
func parseCliSetting(s: string): CliSetting =
|
func parseCliSetting(s: string): CliSetting =
|
||||||
try: parseEnum[CliSetting](s)
|
try: parseEnum[CliSetting](s)
|
||||||
|
@ -504,8 +521,6 @@ func propagate(c: var CliCfg) =
|
||||||
child.inheritFrom(c)
|
child.inheritFrom(c)
|
||||||
propagate(child)
|
propagate(child)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
func parseCliHelp(c: var CliCfg, node: NimNode) =
|
func parseCliHelp(c: var CliCfg, node: NimNode) =
|
||||||
## some possible DSL inputs:
|
## some possible DSL inputs:
|
||||||
##
|
##
|
||||||
|
@ -600,13 +615,16 @@ func parseCliBody(body: NimNode, name = "", root = false): CliCfg =
|
||||||
result.preSub = node[1]
|
result.preSub = node[1]
|
||||||
of "postSub":
|
of "postSub":
|
||||||
result.postSub = node[1]
|
result.postSub = node[1]
|
||||||
|
of "defaultFlagType":
|
||||||
|
result.defaultFlagType = node[1]
|
||||||
else:
|
else:
|
||||||
error "unknown hwylCli setting: " & name
|
error "unknown hwylCli setting: " & name
|
||||||
|
|
||||||
if result.name == "":
|
if result.name == "":
|
||||||
error "missing required option: name"
|
error "missing required option: name"
|
||||||
|
|
||||||
# TODO: validate "required" flags exist here
|
postParse result
|
||||||
|
# TODO: validate "required" flags exist here?
|
||||||
result.addBuiltinFlags()
|
result.addBuiltinFlags()
|
||||||
|
|
||||||
if root:
|
if root:
|
||||||
|
@ -661,36 +679,40 @@ func generateCliHelpProc(cfg: CliCfg, printHelpName: NimNode): NimNode =
|
||||||
|
|
||||||
result = quote do:
|
result = quote do:
|
||||||
proc `printHelpName`() =
|
proc `printHelpName`() =
|
||||||
echo bb(render(newHwylCliHelp(
|
echo bb(
|
||||||
header = `header`,
|
render(
|
||||||
footer = `footer`,
|
newHwylCliHelp(
|
||||||
usage = `usage`,
|
header = `header`,
|
||||||
description = `description`,
|
footer = `footer`,
|
||||||
subcmds = `subcmds`,
|
usage = `usage`,
|
||||||
flags = `helpFlags`,
|
description = `description`,
|
||||||
styles = `styles`,
|
subcmds = `subcmds`,
|
||||||
)))
|
flags = `helpFlags`,
|
||||||
|
styles = `styles`,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
proc preParseCheck(key: string, val: string) =
|
proc checkVal(p: OptParser) =
|
||||||
if val == "":
|
if p.val == "":
|
||||||
hwylCliError(
|
hwylCliError(
|
||||||
"expected value for flag: [b]" & key
|
"expected value for flag: [b]" & p.key
|
||||||
)
|
)
|
||||||
|
|
||||||
proc parse*(p: OptParser, key: string, val: string, target: var bool) =
|
proc parse*(p: OptParser, target: var bool) =
|
||||||
target = true
|
target = true
|
||||||
|
|
||||||
proc parse*(p: OptParser, key: string, val: string, target: var string) =
|
proc parse*(p: OptParser, target: var string) =
|
||||||
preParseCheck(key, val)
|
checkVal p
|
||||||
target = val
|
target = p.val
|
||||||
|
|
||||||
proc parse*(p: OptParser, key: string, val: string, target: var int) =
|
proc parse*(p: OptParser, target: var int) =
|
||||||
preParseCheck(key, val)
|
checkVal p
|
||||||
try:
|
try:
|
||||||
target = parseInt(val)
|
target = parseInt(p.val)
|
||||||
except:
|
except:
|
||||||
hwylCliError(
|
hwylCliError(
|
||||||
"failed to parse value for [b]" & key & "[/] as integer: [b]" & val
|
"failed to parse value for [b]" & p.key & "[/] as integer: [b]" & p.val
|
||||||
)
|
)
|
||||||
|
|
||||||
macro enumNames(a: typed): untyped =
|
macro enumNames(a: typed): untyped =
|
||||||
|
@ -700,40 +722,75 @@ macro enumNames(a: typed): untyped =
|
||||||
assert ai.kind == nnkSym
|
assert ai.kind == nnkSym
|
||||||
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, target: var E) =
|
||||||
preParseCheck(key, val)
|
checkVal p
|
||||||
try:
|
try:
|
||||||
target = parseEnum[E](val)
|
target = parseEnum[E](p.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]" & p.key & "[/] as enum: [b]" & p.val & "[/] expected one of: " & choices
|
||||||
)
|
)
|
||||||
|
|
||||||
proc parse*(p: OptParser, key: string, val: string, target: var float) =
|
proc parse*(p: OptParser, target: var float) =
|
||||||
preParseCheck(key, val)
|
checkVal p
|
||||||
try:
|
try:
|
||||||
target = parseFloat(val)
|
target = parseFloat(p.val)
|
||||||
except:
|
except:
|
||||||
hwylCliError(
|
hwylCliError(
|
||||||
"failed to parse value for [b]" & key & "[/] as float: [b]" & val
|
"failed to parse value for [b]" & p.key & "[/] as float: [b]" & p.val
|
||||||
)
|
)
|
||||||
|
|
||||||
proc parse*[T](p: OptParser, key: string, val: string, target: var seq[T]) =
|
proc parse*[T](p: var OptParser, target: var seq[T]) =
|
||||||
preParseCheck(key, val)
|
checkVal p
|
||||||
var parsed: T
|
case p.sep
|
||||||
parse(p, key, val, parsed)
|
of ",=":
|
||||||
target.add parsed
|
let baseVal = p.val
|
||||||
|
for v in baseVal.split(","):
|
||||||
|
p.val = v.strip()
|
||||||
|
if p.val == "": continue
|
||||||
|
var parsed: T
|
||||||
|
parse(p, parsed)
|
||||||
|
target.add parsed
|
||||||
|
of "=", "":
|
||||||
|
var parsed: T
|
||||||
|
parse(p, parsed)
|
||||||
|
target.add parsed
|
||||||
|
else: assert false
|
||||||
|
|
||||||
proc parse*(p: OptParser, key: string, val: string, target: var Count) =
|
|
||||||
|
proc parse*(p: OptParser, target: var Count) =
|
||||||
# if value set to that otherwise increment
|
# if value set to that otherwise increment
|
||||||
if val != "":
|
if p.val != "":
|
||||||
var num: int
|
var num: int
|
||||||
parse(p, key, val, num)
|
parse(p, num)
|
||||||
target.val = num
|
target.val = num
|
||||||
else:
|
else:
|
||||||
inc target.val
|
inc target.val
|
||||||
|
|
||||||
|
proc extractKey(p: var OptParser): string =
|
||||||
|
var i: int
|
||||||
|
for c in p.val:
|
||||||
|
if c notin {'=',':'}: inc i
|
||||||
|
else: break
|
||||||
|
if i == p.val.len:
|
||||||
|
hwylCliError(
|
||||||
|
"failed to parse key val flag" &
|
||||||
|
"\nkey: " & p.key.bb("bold") &
|
||||||
|
"\nval: " & p.val.bb("bold") &
|
||||||
|
"\ndid you include a separator (= or :)?"
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
result = p.val[0..<i]
|
||||||
|
p.key = p.key & ":" & result
|
||||||
|
p.val = p.val[(i+1) .. ^1]
|
||||||
|
|
||||||
|
proc parse*[T](p: var OptParser, target: var KV[string, T]) =
|
||||||
|
checkVal p
|
||||||
|
let key = extractKey(p)
|
||||||
|
target.key = key
|
||||||
|
parse(p, target.val)
|
||||||
|
|
||||||
func shortLongCaseStmt(cfg: CliCfg, printHelpName: NimNode, version: NimNode): NimNode =
|
func shortLongCaseStmt(cfg: CliCfg, printHelpName: NimNode, version: NimNode): NimNode =
|
||||||
var caseStmt = nnkCaseStmt.newTree()
|
var caseStmt = nnkCaseStmt.newTree()
|
||||||
if NoNormalize notin cfg.settings:
|
if NoNormalize notin cfg.settings:
|
||||||
|
@ -753,7 +810,7 @@ func shortLongCaseStmt(cfg: CliCfg, printHelpName: NimNode, version: NimNode): N
|
||||||
# add flags
|
# add flags
|
||||||
for f in cfg.flags:
|
for f in cfg.flags:
|
||||||
var branch = nnkOfBranch.newTree()
|
var branch = nnkOfBranch.newTree()
|
||||||
if f.long != "":
|
if f.long != "":
|
||||||
branch.add newLit(
|
branch.add newLit(
|
||||||
if NoNormalize notin cfg.settings: optionNormalize(f.long)
|
if NoNormalize notin cfg.settings: optionNormalize(f.long)
|
||||||
else: f.long
|
else: f.long
|
||||||
|
@ -761,9 +818,11 @@ func shortLongCaseStmt(cfg: CliCfg, printHelpName: NimNode, version: NimNode): N
|
||||||
if f.short != '\x00': branch.add(newLit($f.short))
|
if f.short != '\x00': branch.add(newLit($f.short))
|
||||||
let varName = f.ident
|
let varName = f.ident
|
||||||
let name = newLit(f.name)
|
let name = newLit(f.name)
|
||||||
branch.add quote do:
|
branch.add nnkStmtList.newTree(
|
||||||
flagSet.incl `name`
|
nnkCall.newTree(ident("incl"),ident("flagSet"),name),
|
||||||
parse(p, key, val, `varName`)
|
if f.node == nil: nnkCall.newTree(ident"parse", ident"p", varName)
|
||||||
|
else: f.node
|
||||||
|
)
|
||||||
|
|
||||||
caseStmt.add branch
|
caseStmt.add branch
|
||||||
|
|
||||||
|
@ -797,8 +856,8 @@ func setFlagVars(cfg: CliCfg): NimNode =
|
||||||
else: cfg.flags.filterIt(it.group != "global")
|
else: cfg.flags.filterIt(it.group != "global")
|
||||||
|
|
||||||
result.add flags.mapIt(
|
result.add flags.mapIt(
|
||||||
nnkIdentDefs.newTree(it.ident, it.typeNode, newEmptyNode())
|
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]
|
||||||
|
@ -863,6 +922,23 @@ func genSubcommandHandler(cfg: CliCfg): NimNode =
|
||||||
|
|
||||||
result.add subCommandCase
|
result.add subCommandCase
|
||||||
|
|
||||||
|
func parseArgs(p: OptParser, target: var string) =
|
||||||
|
target = p.key
|
||||||
|
|
||||||
|
func parseArgs[T](p: OptParser, target: var seq[T]) =
|
||||||
|
var val: T
|
||||||
|
parseArgs(p, val)
|
||||||
|
target.add val
|
||||||
|
|
||||||
|
func argOfBranch(cfg: CliCfg): NimNode =
|
||||||
|
result = nnkOfBranch.newTree(ident"cmdArgument")
|
||||||
|
# if cfg.args.len == 0 and cfg.subcommands.len == 0:
|
||||||
|
# result.add quote do:
|
||||||
|
# hwylCliError("unexpected positional argument: [b]" & p.key)
|
||||||
|
# else:
|
||||||
|
result.add quote do:
|
||||||
|
inc nArgs
|
||||||
|
parseArgs(p, result)
|
||||||
|
|
||||||
|
|
||||||
func hwylCliImpl(cfg: CliCfg): NimNode =
|
func hwylCliImpl(cfg: CliCfg): NimNode =
|
||||||
|
@ -875,9 +951,7 @@ func hwylCliImpl(cfg: CliCfg): NimNode =
|
||||||
optParser = ident("p")
|
optParser = ident("p")
|
||||||
cmdLine = ident"cmdLine"
|
cmdLine = ident"cmdLine"
|
||||||
flagSet = ident"flagSet"
|
flagSet = ident"flagSet"
|
||||||
kind = ident"kind"
|
nArgs = ident"nargs"
|
||||||
key = ident"key"
|
|
||||||
val = ident"val"
|
|
||||||
(longNoVal, shortNoVal) = cfg.getNoVals()
|
(longNoVal, shortNoVal) = cfg.getNoVals()
|
||||||
printHelpProc = generateCliHelpProc(cfg, printHelpName)
|
printHelpProc = generateCliHelpProc(cfg, printHelpName)
|
||||||
flagVars = setFlagVars(cfg)
|
flagVars = setFlagVars(cfg)
|
||||||
|
@ -893,9 +967,9 @@ func hwylCliImpl(cfg: CliCfg): NimNode =
|
||||||
|
|
||||||
stopWords = nnkPrefix.newTree(ident"@", stopWords)
|
stopWords = nnkPrefix.newTree(ident"@", stopWords)
|
||||||
|
|
||||||
# should this a CritBitTree?
|
|
||||||
parserBody.add quote do:
|
parserBody.add quote do:
|
||||||
var `flagSet` {.used.}: HashSet[string]
|
var `flagSet`: HashSet[string]
|
||||||
|
var `nArgs`: int
|
||||||
|
|
||||||
parserBody.add(
|
parserBody.add(
|
||||||
quote do:
|
quote do:
|
||||||
|
@ -907,24 +981,23 @@ func hwylCliImpl(cfg: CliCfg): NimNode =
|
||||||
opChars = {','}
|
opChars = {','}
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
# TODO: first key needs to be normalized
|
|
||||||
|
# TODO: first key needs to be normalized?
|
||||||
|
# TODO: don't use getopt? use p.next() instead?
|
||||||
parserBody.add nnkForStmt.newTree(
|
parserBody.add nnkForStmt.newTree(
|
||||||
kind, key, val,
|
ident"kind", ident"key", ident"val",
|
||||||
nnkCall.newTree(nnkDotExpr.newTree(optParser,ident("getopt"))),
|
# nnkCall.newTree(nnkDotExpr.newTree(optParser,ident("getopt"))),
|
||||||
|
nnkCall.newTree(ident"getopt", optParser),
|
||||||
nnkStmtList.newTree(
|
nnkStmtList.newTree(
|
||||||
# # for debugging..
|
# # for debugging..
|
||||||
# quote do:
|
# quote do:
|
||||||
# echo `kind`,"|",`key`,"|",`val`
|
# echo `kind`,"|",`key`,"|",`val`
|
||||||
# ,
|
# ,
|
||||||
nnkCaseStmt.newTree(
|
nnkCaseStmt.newTree(
|
||||||
kind,
|
ident"kind",
|
||||||
nnkOfBranch.newTree(ident("cmdError"), quote do: hwylCliError(p.message)),
|
nnkOfBranch.newTree(ident("cmdError"), quote do: hwylCliError(p.message)),
|
||||||
nnkOfBranch.newTree(ident("cmdEnd"), quote do: assert false),
|
nnkOfBranch.newTree(ident("cmdEnd"), quote do: assert false),
|
||||||
# TODO: add nArgs to change how cmdArgument is handled ...
|
argOfBranch(cfg),
|
||||||
nnkOfBranch.newTree(ident("cmdArgument"),
|
|
||||||
quote do:
|
|
||||||
result.add `key`
|
|
||||||
),
|
|
||||||
nnkOfBranch.newTree(
|
nnkOfBranch.newTree(
|
||||||
ident("cmdShortOption"), ident("cmdLongOption"),
|
ident("cmdShortOption"), ident("cmdLongOption"),
|
||||||
shortLongCaseStmt(cfg, printHelpName, version)
|
shortLongCaseStmt(cfg, printHelpName, version)
|
||||||
|
@ -971,6 +1044,7 @@ func hwylCliImpl(cfg: CliCfg): NimNode =
|
||||||
result.add quote do:
|
result.add quote do:
|
||||||
`runProcName`(`args`[1..^1])
|
`runProcName`(`args`[1..^1])
|
||||||
|
|
||||||
|
|
||||||
macro hwylCli*(body: untyped) =
|
macro hwylCli*(body: untyped) =
|
||||||
## generate a CLI styled by `hwylterm` and parsed by `parseopt3`
|
## generate a CLI styled by `hwylterm` and parsed by `parseopt3`
|
||||||
var cfg = parseCliBody(body, root = true)
|
var cfg = parseCliBody(body, root = true)
|
||||||
|
|
|
@ -6,7 +6,6 @@ type
|
||||||
Color = enum
|
Color = enum
|
||||||
red, blue, green
|
red, blue, green
|
||||||
|
|
||||||
|
|
||||||
hwylCli:
|
hwylCli:
|
||||||
name "example"
|
name "example"
|
||||||
V "0.1.0"
|
V "0.1.0"
|
||||||
|
@ -72,14 +71,17 @@ hwylCli:
|
||||||
"""
|
"""
|
||||||
flags:
|
flags:
|
||||||
^something
|
^something
|
||||||
auto:
|
thing:
|
||||||
- a
|
T KV[string, Color]
|
||||||
? "some help"
|
? "some key value string"
|
||||||
b:
|
b:
|
||||||
T seq[float]
|
T seq[float]
|
||||||
? "multiple floats"
|
? "multiple floats"
|
||||||
h "this will override the builtin 'h' for help"
|
h "this will override the builtin 'h' for help"
|
||||||
|
def:
|
||||||
|
? "a flag with a string default"
|
||||||
|
* "the value"
|
||||||
run:
|
run:
|
||||||
echo "hello from `example b` command"
|
echo "hello from `example b` command"
|
||||||
echo fmt"{auto=}, {b=}"
|
echo fmt"{thing=}, {b=}, {h=}, {def=}"
|
||||||
|
|
||||||
|
|
10
todo.md
10
todo.md
|
@ -8,10 +8,10 @@
|
||||||
|
|
||||||
|
|
||||||
- [ ] addJoinStyle(); works like join except wraps each argument in a style
|
- [ ] addJoinStyle(); works like join except wraps each argument in a style
|
||||||
|
- [ ] add span aware split/splitlines
|
||||||
- [ ] consider reducing illwill surface to only relevant IO (input) features
|
- [ ] consider reducing illwill surface to only relevant IO (input) features
|
||||||
- [ ] revamp spinner api (new threads?)
|
- [ ] revamp spinner api (new threads?)
|
||||||
- [x] add Bbstring ~~indexing operations~~ strutils, that are span aware
|
- [x] add Bbstring ~~indexing operations~~ strutils, that are span aware
|
||||||
- [ ] add a `commands` option for `newHwylCli` in `hwylterm/cli`
|
|
||||||
- [ ] console object with customizable options to apply formatting
|
- [ ] console object with customizable options to apply formatting
|
||||||
|
|
||||||
### cli generator
|
### cli generator
|
||||||
|
@ -22,8 +22,10 @@
|
||||||
- [x] 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
|
- [x] add command aliases to hwylcli help with switch
|
||||||
- [x] don't recreate "global"" variables in var section
|
- [x] don't recreate "global"" variables in var section
|
||||||
- [ ] make proper test suite for cli generator
|
- [ ] add flag overlap check before case statement generation (after parsing?)
|
||||||
|
- [ ] add key-value flag support -> `--setting:a:off`
|
||||||
|
- [x] add defaultFlagType CliCfg setting
|
||||||
|
- [x] add node to flagDef to override builtin `parse(p, varName)`
|
||||||
|
|
||||||
## features
|
## features
|
||||||
|
|
||||||
|
@ -35,8 +37,10 @@
|
||||||
- [ ] support for rgb colors
|
- [ ] support for rgb colors
|
||||||
- [ ] modify 256 colors w/parser changes to be `"[color(9)]red"` instead of `[9]red`
|
- [ ] modify 256 colors w/parser changes to be `"[color(9)]red"` instead of `[9]red`
|
||||||
- [x] improve color detection [ref](https://github.com/Textualize/rich/blob/4101991898ee7a09fe1706daca24af5e1e054862/rich/console.py#L791)
|
- [x] improve color detection [ref](https://github.com/Textualize/rich/blob/4101991898ee7a09fe1706daca24af5e1e054862/rich/console.py#L791)
|
||||||
|
|
||||||
## testing
|
## testing
|
||||||
|
|
||||||
|
- [ ] make proper test suite for cli generator
|
||||||
- [ ] investigate [cap10](https://github.com/crashappsec/cap10) as a means of scripting the testing
|
- [ ] investigate [cap10](https://github.com/crashappsec/cap10) as a means of scripting the testing
|
||||||
|
|
||||||
<!-- generated with <3 by daylinmorgan/todo -->
|
<!-- generated with <3 by daylinmorgan/todo -->
|
||||||
|
|
Loading…
Reference in a new issue