If you want the second keyword be "none" and not "do", you can use 2 templates/macros and a variable to pass state between them, like: var whileSomeNone: bool template whileSome*(condition: typed, body: untyped) = whileSomeNone = condition if whileSomeNone: while true: body if not condition: break template none*(body: untyped) = if not whileSomeNone: body Run
No check is performed here that `none` follows `whileSome`, as downside. May be used nested: import whilesome var a = 3 # set to >=7 for "none" branch var b = 7 proc c: bool = return a < b whileSome(c()): echo a inc a var i = 0 # set to >=3 for "none" branch whileSome(i<3): echo "i=", i inc i none: echo "i >= 3 initially!" none: echo "No items to display!" Run