mirror of
https://github.com/daylinmorgan/hwylterm.git
synced 2024-12-22 11:00:45 -06:00
Compare commits
No commits in common. "c5f70cec4e40ba396f59162e98c359a1a1ea4fe1" and "f1cc95f86edcc00665fc8280f57edc0e83d461f9" have entirely different histories.
c5f70cec4e
...
f1cc95f86e
3 changed files with 79 additions and 159 deletions
|
@ -138,10 +138,6 @@ 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
|
||||||
|
@ -163,7 +159,6 @@ 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
|
||||||
|
@ -178,25 +173,21 @@ 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] # only supported in subcommands
|
alias*: HashSet[string]
|
||||||
version*: NimNode
|
|
||||||
stopWords*: seq[string]
|
stopWords*: seq[string]
|
||||||
help: CliHelp
|
help: CliHelp
|
||||||
defaultFlagType: NimNode
|
|
||||||
required*: seq[string]
|
|
||||||
settings*: set[CliSetting]
|
|
||||||
subName*: string # used for help generator
|
|
||||||
subcommands: seq[CliCfg]
|
|
||||||
preSub*, postSub*, pre*, post*, run*: NimNode
|
|
||||||
hidden*: seq[string]
|
hidden*: seq[string]
|
||||||
args*: seq[CliArg]
|
subcommands: seq[CliCfg]
|
||||||
|
settings*: set[CliSetting]
|
||||||
|
preSub*, postSub*, pre*, post*, run*: NimNode
|
||||||
|
subName*: string # used for help the generator
|
||||||
|
version*: NimNode
|
||||||
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
|
||||||
|
|
||||||
|
@ -265,14 +256,12 @@ 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 newFlag(f: var CliFlag, n: NimNode) =
|
func startFlag(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
|
||||||
|
@ -291,12 +280,11 @@ func parseCliFlag(n: NimNode): CliFlag =
|
||||||
if n.kind notin [nnkCommand, nnkCall]:
|
if n.kind notin [nnkCommand, nnkCall]:
|
||||||
bad(n, "flags")
|
bad(n, "flags")
|
||||||
|
|
||||||
newFlag(result, n)
|
startFlag(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])
|
||||||
|
@ -306,14 +294,7 @@ func parseCliFlag(n: NimNode): CliFlag =
|
||||||
if result.typeNode == nil:
|
if result.typeNode == nil:
|
||||||
result.typeNode = ident"bool"
|
result.typeNode = ident"bool"
|
||||||
|
|
||||||
func postParse(cfg: var CliCfg) =
|
# TODO: change how this works?
|
||||||
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
|
||||||
|
@ -342,8 +323,10 @@ 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)
|
||||||
|
@ -521,6 +504,8 @@ 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:
|
||||||
##
|
##
|
||||||
|
@ -615,16 +600,13 @@ 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"
|
||||||
|
|
||||||
postParse result
|
# TODO: validate "required" flags exist here
|
||||||
# TODO: validate "required" flags exist here?
|
|
||||||
result.addBuiltinFlags()
|
result.addBuiltinFlags()
|
||||||
|
|
||||||
if root:
|
if root:
|
||||||
|
@ -679,40 +661,36 @@ func generateCliHelpProc(cfg: CliCfg, printHelpName: NimNode): NimNode =
|
||||||
|
|
||||||
result = quote do:
|
result = quote do:
|
||||||
proc `printHelpName`() =
|
proc `printHelpName`() =
|
||||||
echo bb(
|
echo bb(render(newHwylCliHelp(
|
||||||
render(
|
header = `header`,
|
||||||
newHwylCliHelp(
|
footer = `footer`,
|
||||||
header = `header`,
|
usage = `usage`,
|
||||||
footer = `footer`,
|
description = `description`,
|
||||||
usage = `usage`,
|
subcmds = `subcmds`,
|
||||||
description = `description`,
|
flags = `helpFlags`,
|
||||||
subcmds = `subcmds`,
|
styles = `styles`,
|
||||||
flags = `helpFlags`,
|
)))
|
||||||
styles = `styles`,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
proc checkVal(p: OptParser) =
|
proc preParseCheck(key: string, val: string) =
|
||||||
if p.val == "":
|
if val == "":
|
||||||
hwylCliError(
|
hwylCliError(
|
||||||
"expected value for flag: [b]" & p.key
|
"expected value for flag: [b]" & key
|
||||||
)
|
)
|
||||||
|
|
||||||
proc parse*(p: OptParser, target: var bool) =
|
proc parse*(p: OptParser, key: string, val: string, target: var bool) =
|
||||||
target = true
|
target = true
|
||||||
|
|
||||||
proc parse*(p: OptParser, target: var string) =
|
proc parse*(p: OptParser, key: string, val: string, target: var string) =
|
||||||
checkVal p
|
preParseCheck(key, val)
|
||||||
target = p.val
|
target = val
|
||||||
|
|
||||||
proc parse*(p: OptParser, target: var int) =
|
proc parse*(p: OptParser, key: string, val: string, target: var int) =
|
||||||
checkVal p
|
preParseCheck(key, val)
|
||||||
try:
|
try:
|
||||||
target = parseInt(p.val)
|
target = parseInt(val)
|
||||||
except:
|
except:
|
||||||
hwylCliError(
|
hwylCliError(
|
||||||
"failed to parse value for [b]" & p.key & "[/] as integer: [b]" & p.val
|
"failed to parse value for [b]" & key & "[/] as integer: [b]" & val
|
||||||
)
|
)
|
||||||
|
|
||||||
macro enumNames(a: typed): untyped =
|
macro enumNames(a: typed): untyped =
|
||||||
|
@ -722,75 +700,40 @@ 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, target: var E) =
|
proc parse*[E: enum](p: OptParser, key: string, val: string, target: var E) =
|
||||||
checkVal p
|
preParseCheck(key, val)
|
||||||
try:
|
try:
|
||||||
target = parseEnum[E](p.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]" & p.key & "[/] as enum: [b]" & p.val & "[/] expected one of: " & choices
|
"failed to parse value for [b]" & key & "[/] as enum: [b]" & val & "[/] expected one of: " & choices
|
||||||
)
|
)
|
||||||
|
|
||||||
proc parse*(p: OptParser, target: var float) =
|
proc parse*(p: OptParser, key: string, val: string, target: var float) =
|
||||||
checkVal p
|
preParseCheck(key, val)
|
||||||
try:
|
try:
|
||||||
target = parseFloat(p.val)
|
target = parseFloat(val)
|
||||||
except:
|
except:
|
||||||
hwylCliError(
|
hwylCliError(
|
||||||
"failed to parse value for [b]" & p.key & "[/] as float: [b]" & p.val
|
"failed to parse value for [b]" & key & "[/] as float: [b]" & val
|
||||||
)
|
)
|
||||||
|
|
||||||
proc parse*[T](p: var OptParser, target: var seq[T]) =
|
proc parse*[T](p: OptParser, key: string, val: string, target: var seq[T]) =
|
||||||
checkVal p
|
preParseCheck(key, val)
|
||||||
case p.sep
|
var parsed: T
|
||||||
of ",=":
|
parse(p, key, val, parsed)
|
||||||
let baseVal = p.val
|
target.add parsed
|
||||||
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 p.val != "":
|
if val != "":
|
||||||
var num: int
|
var num: int
|
||||||
parse(p, num)
|
parse(p, key, val, 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:
|
||||||
|
@ -818,11 +761,9 @@ 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 nnkStmtList.newTree(
|
branch.add quote do:
|
||||||
nnkCall.newTree(ident("incl"),ident("flagSet"),name),
|
flagSet.incl `name`
|
||||||
if f.node == nil: nnkCall.newTree(ident"parse", ident"p", varName)
|
parse(p, key, val, `varName`)
|
||||||
else: f.node
|
|
||||||
)
|
|
||||||
|
|
||||||
caseStmt.add branch
|
caseStmt.add branch
|
||||||
|
|
||||||
|
@ -856,8 +797,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]
|
||||||
|
@ -922,23 +863,6 @@ 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 =
|
||||||
|
@ -951,7 +875,9 @@ func hwylCliImpl(cfg: CliCfg): NimNode =
|
||||||
optParser = ident("p")
|
optParser = ident("p")
|
||||||
cmdLine = ident"cmdLine"
|
cmdLine = ident"cmdLine"
|
||||||
flagSet = ident"flagSet"
|
flagSet = ident"flagSet"
|
||||||
nArgs = ident"nargs"
|
kind = ident"kind"
|
||||||
|
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)
|
||||||
|
@ -967,9 +893,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`: HashSet[string]
|
var `flagSet` {.used.}: HashSet[string]
|
||||||
var `nArgs`: int
|
|
||||||
|
|
||||||
parserBody.add(
|
parserBody.add(
|
||||||
quote do:
|
quote do:
|
||||||
|
@ -981,23 +907,24 @@ 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(
|
||||||
ident"kind", ident"key", ident"val",
|
kind, key, 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(
|
||||||
ident"kind",
|
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),
|
||||||
argOfBranch(cfg),
|
# TODO: add nArgs to change how cmdArgument is handled ...
|
||||||
|
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)
|
||||||
|
@ -1044,7 +971,6 @@ 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,6 +6,7 @@ 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"
|
||||||
|
@ -71,17 +72,14 @@ hwylCli:
|
||||||
"""
|
"""
|
||||||
flags:
|
flags:
|
||||||
^something
|
^something
|
||||||
thing:
|
auto:
|
||||||
T KV[string, Color]
|
- a
|
||||||
? "some key value string"
|
? "some help"
|
||||||
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"{thing=}, {b=}, {h=}, {def=}"
|
echo fmt"{auto=}, {b=}"
|
||||||
|
|
||||||
|
|
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,10 +22,8 @@
|
||||||
- [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
|
||||||
- [ ] add flag overlap check before case statement generation (after parsing?)
|
- [ ] make proper test suite for cli generator
|
||||||
- [ ] 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
|
||||||
|
|
||||||
|
@ -37,10 +35,8 @@
|
||||||
- [ ] 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