From 17a44c17f7309d7ec67b9b1fb5688f3d81f74931 Mon Sep 17 00:00:00 2001 From: Daylin Morgan Date: Tue, 28 Jan 2025 15:19:15 -0600 Subject: [PATCH] infer short flags --- src/hwylterm/hwylcli.nim | 29 +++++++++++++++++++++++------ tests/cli/clis/inferShort.nim | 25 +++++++++++++++++++++++++ tests/cli/tester.nim | 3 +++ 3 files changed, 51 insertions(+), 6 deletions(-) create mode 100644 tests/cli/clis/inferShort.nim diff --git a/src/hwylterm/hwylcli.nim b/src/hwylterm/hwylcli.nim index def3867..ab6e193 100644 --- a/src/hwylterm/hwylcli.nim +++ b/src/hwylterm/hwylcli.nim @@ -191,11 +191,12 @@ type ShowHelp, ## If cmdline empty show help NoNormalize, ## Don't normalize flags and commands NoPositional, ## Raise error if any remaing positional arguments DEPRECATED - HideDefault ## Don't show default values - # ExactArgs, ## Raise error if missing positional argument + HideDefault, ## Don't show default values + InferShort ## Autodefine short flags CliFlagSetting* = enum - HideDefault ## Don't show default values + HideDefault, ## Don't show default values + NoShort ## Counter option to Parent's InferShort BuiltinFlag = object name*: string @@ -269,6 +270,9 @@ template `<<<`(n: NimNode) {.used.} = ## for debugging macros <<< treeRepr n +template `<<<`(n: untyped) {.used.} = + debugEcho n, "|||", instantiationInfo().line + func `<<<`(f: CliFlag) {.used.}= var s: string let fields = [ @@ -398,6 +402,19 @@ func parseCliFlag(n: NimNode): CliFlag = if result.ident == nil: result.ident = result.name.ident +func inferShortFlags(cfg: var CliCfg) = + ## supplement existing short flags based on initial characters of long flags + let taken = cfg.flags.mapIt(it.short).toHashSet() - toHashSet(['\x00']) + var candidates = cfg.flags.mapIt(it.long[0]).toHashSet() - taken + for f in cfg.flags.mitems: + + if f.short != '\x00' or NoShort in f.settings: continue + let c = f.long[0] + if c in candidates: + f.short = c + candidates.excl c + + func postParse(cfg: var CliCfg) = if cfg.name == "": error "missing required option: name" @@ -417,6 +434,9 @@ func postParse(cfg: var CliCfg) = if count > 1: cfg.err "more than one positional argument is variadic" + if InferShort in cfg.settings: + inferShortFlags cfg + func parseCliFlags(cfg: var CliCfg, node: NimNode) = var group: string expectKind node, nnkStmtList @@ -613,9 +633,6 @@ func postPropagateCheck(c: CliCfg) = if f.short in short: let conflict = short[f.short] c.err "conflicting short flags for: " & f.name & " and " & conflict.name - # hwylCliImplError c, ( - # "conflicting short flags for: " & f.name & " and " & conflict.name - # ) else: short[f.short] = f diff --git a/tests/cli/clis/inferShort.nim b/tests/cli/clis/inferShort.nim new file mode 100644 index 0000000..86f4bf0 --- /dev/null +++ b/tests/cli/clis/inferShort.nim @@ -0,0 +1,25 @@ +import std/strformat +import hwylterm, hwylterm/hwylcli + +hwylCli: + name "inferred short flags" + settings InferShort + flags: + input: + T string + ? "the input var" + output: + T string + ? "the output var" + count: + T int + ? "a number" + - n + nancy: + ? "needed a flag that starts with n :)" + ignore: + S NoShort + ? "a flag to not infer" + run: + echo fmt"{input=}, {output=}, {count=}, {nancy=}, {ignore=}" + diff --git a/tests/cli/tester.nim b/tests/cli/tester.nim index 4d7b657..2e37617 100644 --- a/tests/cli/tester.nim +++ b/tests/cli/tester.nim @@ -114,3 +114,6 @@ inside sub c failWithArgs( "errorOverride", "--flag","override the default error\nerror unknown flag: flag" ) + okWithArgs( + "inferShort", "-i input -o output","""input=input, output=output, count=0, nancy=false, ignore=false""" + )