Skip to content

Commit 39865d2

Browse files
committed
new type choices + rewrite spinner module
Signed-off-by: George Lemon <georgelemon@protonmail.com>
1 parent 50ac8c6 commit 39865d2

14 files changed

Lines changed: 1217 additions & 130 deletions

File tree

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,9 @@ htmldocs/
66
nimble.develop
77
nimble.paths
88
nimbledeps
9+
10+
# compiled test binaries and fixtures
11+
tests/test1
12+
tests/test2
13+
tests/fixtures/cliapp.bin
14+
tests/fixtures/cliapp.bin.exe

kapsis.nimble

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Package
22

3-
version = "0.4.2"
3+
version = "0.4.3"
44
author = "George Lemon"
55
description = "Your type of CLI framework"
66
license = "MIT"
@@ -16,3 +16,4 @@ requires "termstyle >= 0.1.0"
1616
requires "nancy >= 0.1.1"
1717
requires "noise >= 0.1.10"
1818
requires "pluginkit >= 0.1.1"
19+
requires "threading >= 0.2.1"

src/kapsis.nim

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
import ./kapsis/[framework, runtime]
88
import ./kapsis/interactive/prompts
9-
export framework, tables
9+
export framework, tables, runtime
1010

1111
when isMainModule:
1212
#
@@ -31,6 +31,9 @@ when isMainModule:
3131
if v.has("--sure"):
3232
displaySuccess "Listen on YouTube 🔈 https://www.youtube.com/watch?v=66OkZGoI7Bk&list=PLG2Yb0-YL20c88ZRUl3YAhjLxTIbPql9u"
3333

34+
proc pickCommand(v: Values) =
35+
echo "picked: " & v.get("flavor").getAny
36+
3437
#
3538
# Init Kapsis with the defined commands
3639
#
@@ -48,6 +51,10 @@ when isMainModule:
4851
greet name.string, ?string(greeting):
4952
## Greeting someone with an optional greeting message
5053

54+
-- "Choice demo"
55+
pick ?any(flavor = ["vanilla", "chocolate", "strawberry"]):
56+
## Pick an ice cream flavor
57+
5158
-- "Colors by Ken Nordine"
5259
colors:
5360
## Colors are cool, let's have some fun with them

src/kapsis/framework.nim

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ type
3535
isOptional*: bool
3636
## When an argument is optional, it means that the user
3737
## doesn't have to provide it when executing the command
38+
choices*: seq[string]
39+
## For `any` arguments, the list of allowed values
3840

3941
CommandType* = enum
4042
## The type of the command, used for parsing and validation at runtime
@@ -217,7 +219,8 @@ proc toCommand*(cmd: PluginCommand): Command =
217219
kind: a.kind,
218220
dataType: a.datatype,
219221
name: a.name,
220-
isOptional: a.isOptional
222+
isOptional: a.isOptional,
223+
choices: a.choices
221224
)
222225

223226
proc preparePrintCommand(cmd: Command,
@@ -240,14 +243,23 @@ proc preparePrintCommand(cmd: Command,
240243
parts.add ColoredSegment(text: "?", fg: fgBlack, bright: true)
241244
parts.add ColoredSegment(text: arg.name, fg: fgDefault)
242245
if showTypes:
243-
parts.add ColoredSegment(text: ":" & $arg.dataType, fg: fgCyan)
246+
var typeStr = ":" & $arg.dataType
247+
if arg.dataType == ktAny and arg.choices.len > 0:
248+
typeStr.add "[" & arg.choices.join(",") & "]"
249+
parts.add ColoredSegment(text: typeStr, fg: fgCyan)
244250
parts.add ColoredSegment(text: ">", fg: fgBlack, bright: true)
245251
of cmdLongOption:
246252
if showFlags:
247-
flags.add arg.name & ":" & $arg.dataType
253+
var flagStr = arg.name & ":" & $arg.dataType
254+
if arg.dataType == ktAny and arg.choices.len > 0:
255+
flagStr.add "[" & arg.choices.join(",") & "]"
256+
flags.add flagStr
248257
of cmdShortOption:
249258
if showFlags:
250-
flags.add arg.name & ":" & $arg.dataType
259+
var flagStr = arg.name & ":" & $arg.dataType
260+
if arg.dataType == ktAny and arg.choices.len > 0:
261+
flagStr.add "[" & arg.choices.join(",") & "]"
262+
flags.add flagStr
251263
else: discard
252264
if cmd.arguments.len > 0:
253265
if not showFlags:
@@ -309,16 +321,17 @@ proc printUsage(app: Kapsis,
309321
var isHighlighted = false
310322
if x[1].len > 0:
311323
let plainLen = segmentLen(x[0])
312-
var pad = longestCmd - plainLen + 18
324+
var pad = longestCmd - plainLen + 8
313325
let hasFlagIcon = block:
314326
var found = false
315327
for s in x[0]:
316328
if s.text.contains(""): found = true; break
317329
found
318330
if showTypes:
319-
pad -= 2
331+
pad += 4
320332
elif hasFlagIcon:
321333
pad += 2
334+
if pad < 1: pad = 1
322335
let wrapped = wrapWords(x[1], 60)
323336
let lines = wrapped.splitLines
324337
let descCol = visualLen(x[0]) + pad
@@ -406,6 +419,7 @@ proc parseCommand(cmdName: NimNode, cmdArgs: seq[NimNode] = @[],
406419
# parse arguments and subcommands
407420
var isOptional: bool
408421
var argTypeNode, argNameNode: NimNode
422+
var argChoices: seq[string]
409423
var kind: CmdLineKind
410424
case n.kind
411425
of nnkDotExpr:
@@ -415,6 +429,13 @@ proc parseCommand(cmdName: NimNode, cmdArgs: seq[NimNode] = @[],
415429
of nnkCommand, nnkCall:
416430
argTypeNode = n[0]
417431
argNameNode = n[1]
432+
if argTypeNode.eqIdent"any":
433+
# `any(name = ["a", "b"])` — arg name + allowed choices
434+
if argNameNode.kind != nnkExprEqExpr:
435+
error("`any` arguments require a list of choices: any(name = [\"a\", \"b\"])", n)
436+
for v in argNameNode[1]:
437+
argChoices.add v.strVal
438+
argNameNode = argNameNode[0]
418439
if argNameNode.kind == nnkStrLit and argNameNode.strVal.startsWith("--"):
419440
# we handle long options like `--verbose` by
420441
kind = cmdLongOption
@@ -438,6 +459,13 @@ proc parseCommand(cmdName: NimNode, cmdArgs: seq[NimNode] = @[],
438459
elif n[1].kind == nnkCall:
439460
argTypeNode = n[1][0]
440461
argNameNode = n[1][1]
462+
if argTypeNode.eqIdent"any":
463+
# `?any(name = ["a", "b"])`
464+
if argNameNode.kind != nnkExprEqExpr:
465+
error("`any` arguments require a list of choices: any(name = [\"a\", \"b\"])", n)
466+
for v in argNameNode[1]:
467+
argChoices.add v.strVal
468+
argNameNode = argNameNode[0]
441469
if argNameNode.strVal.startsWith("--"):
442470
kind = cmdLongOption
443471
elif argNameNode.strVal.startsWith("-"):
@@ -462,6 +490,7 @@ proc parseCommand(cmdName: NimNode, cmdArgs: seq[NimNode] = @[],
462490
nnkExprColonExpr.newTree(ident"dataType",newLit(argType)),
463491
nnkExprColonExpr.newTree(ident"name", newLit(argNameNode.strVal)),
464492
nnkExprColonExpr.newTree(ident"isOptional", newLit(isOptional)),
493+
nnkExprColonExpr.newTree(ident"choices", newLit(argChoices)),
465494
)
466495
)
467496

src/kapsis/interactive/prompts.nim

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ import std/[macros, terminal, sequtils, strutils]
22
import pkg/valido
33

44
import pkg/[termstyle, nancy, noise]
5-
import ./spinny, ./spinny/spinners
5+
import ./spinny, ./spinny/[spinners, preloaders]
66

7-
export nancy, spinny, spinners, termstyle
7+
export nancy, spinny, spinners, preloaders, termstyle
88

99
from std/strutils import `%`, spaces, indent
1010
export ForegroundColor, BackgroundColor

0 commit comments

Comments
 (0)