Browse Source

punk::args 0.6.0: small restricted choice sets display as literal alternates in synopses

An argument whose choice pool (-choices plus -choicegroups members,
deduplicated) has 1-3 members and -choicerestricted true (the default) now
renders those words unitalicised joined by | in synopses - e.g 'after cancel'
shows literal cancel, a 3-choice option shows (left|centre|right) - matching
the display style of literal()/literalprefix() type-alternates. Larger or
unrestricted choice sets keep the italicised argname/<type> display, and an
explicit -typesynopsis always takes precedence (textblock::frame -type
unchanged). New shared helper punk::args::private::synopsis_choice_literals
feeds both synopsis render paths (leaders/values via
synopsis_form_arg_display, options inline in synopsis); applies only to
single-element -type lists. Superseded commented-out single-choice sketches
removed; define doc for -choices documents the rule.

tests: synopsis.test 4 -> 13 - characterization coverage for
literal/literalprefix/stringstartswith/stringendswith type-alternates,
option alternate parenthesization, multi-element clause display (?type?
members, argname tail-word hints), -typesynopsis value-element lists and
option passthrough incl documenter ANSI, plus the new choice-literal rule
(leader/option/value positions, choicegroups counting, >3 and unrestricted
fallbacks, -typesynopsis precedence). rendering.test choicelabel fixtures
padded to 4 choices so markercol keeps matching the choices cell rather
than the now-literal synopsis line.

Known residue (deliberate): option-path -typesynopsis ?-trim edge cases
remain (todo comments at the render site) - resolve-time rejection deferred;
any future normalization surgery belongs to punk::ansi::ansistring/opunk::Str.

project 0.12.0

Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
master
Julian Noble 3 days ago
parent
commit
c309ed4782
  1. 4
      CHANGELOG.md
  2. 2
      punkproject.toml
  3. 66
      src/modules/punk/args-999999.0a1.0.tm
  4. 3
      src/modules/punk/args-buildversion.txt
  5. 2
      src/tests/modules/AGENTS.md
  6. 9
      src/tests/modules/punk/args/testsuites/args/rendering.test
  7. 182
      src/tests/modules/punk/args/testsuites/args/synopsis.test

4
CHANGELOG.md

@ -5,6 +5,10 @@ The latest `## [X.Y.Z]` header must match the `version` field in `punkproject.to
Entries are newest-first; one bullet per notable change. See the root `AGENTS.md`
"Project Versioning" section for the bump policy.
## [0.12.0] - 2026-07-11
- punk::args 0.6.0: command synopses (`s <cmd>`, `i <cmd>`, usage headers) now display small restricted choice sets as literal alternates — an argument whose choice pool (`-choices` plus `-choicegroups` members) has 1–3 members and `-choicerestricted` true renders those words unitalicised joined by `|` (e.g. `after cancel` shows literal `cancel`; a 3-choice option shows `(left|centre|right)`), matching the existing display style of `literal()`/`literalprefix()` type-alternates. Larger or unrestricted choice sets keep the italicised argname/type display and an explicit `-typesynopsis` always wins, so e.g. `textblock::frame -type (choice|<dict>)` is unchanged. Synopsis rendering of type-alternates, `-typesynopsis` passthrough (including documenter ANSI styling), and multi-element clause display gained characterization test coverage (`synopsis.test`).
## [0.11.0] - 2026-07-11
- G-001 achieved: an interactive REPL can be launched against a non-detectable terminal-like device via an `::opunk::Console` subclass — `repl::init -console <spec>` selects the console (channel pair, anchored instance name, or object value), `repl::start`'s input channel defaults to it, and the repl's output (prompts, results, and the code interp's stdout/stderr — diverted via shellfilter junction stacks and emitted per run) routes through the selected console's channels, with eof/size/capability answered by the subclass overrides (punk::repl 0.4.0; base `::opunk::Console` and `punk::console` untouched). Verified end-to-end by child-process driver tests: an `::opunk::SshConsole` socket session whose scripted remote terminal answers `CSI 6n` (size resolved over the socket) and a `::opunk::TkConsole` text widget wired as a live console by new `opunk::console::tk::console` (reflected output channel rendering into the widget + Return-binding input pipe, opunk::console::tk 0.2.0). Process-console behaviours (tcl_interactive prompt gating, stdin reopen on eof, raw-mode re-enable, the windows line re-decode experiment) now apply only when no foreign console is selected; default stdin/stdout repl behaviour is unchanged.

2
punkproject.toml

@ -1,3 +1,3 @@
[project]
name = "punkshell"
version = "0.11.0"
version = "0.12.0"

66
src/modules/punk/args-999999.0a1.0.tm

@ -905,6 +905,13 @@ tcl::namespace::eval punk::args {
-choices {<choicelist>}
A list of allowable values for an argument.
The -default value doesn't have to be in the list.
Synopsis display: a choice set of 1 to 3 members (counting
-choicegroups members) with -choicerestricted true displays
in the synopsis as unitalicised literal alternates
(e.g cancel, or left|centre|right) in the same style as
literal()/literalprefix() type-alternatives. Larger or
unrestricted choice sets display as the italicised argument
name or type, and a -typesynopsis always takes precedence.
If a -type is specified - it doesn't apply to choice members.
It will only be used for validation if the -choicerestricted
option is set to false. If all choices are specified in values
@ -11598,6 +11605,34 @@ tcl::namespace::eval punk::args {
}
proc private::synopsis_choice_literals {arginfo} {
#Small restricted choice sets display in synopses as unitalicised literal alternates,
#matching the display style of literal()/literalprefix() type-alternatives.
#Returns a list of list-protected choice words, or an empty list when the rule doesn't apply:
# - more than 3 choices (reader should refer to the full help for the choice list)
# - -choicerestricted 0 (other values are also acceptable - bare literals would be misleading)
#A defined -typesynopsis always takes precedence - callers consult it before this.
set allchoices [list]
if {[dict exists $arginfo -choices]} {
set allchoices [dict get $arginfo -choices]
}
foreach {groupname members} [Dict_getdef $arginfo -choicegroups {}] {
lappend allchoices {*}$members
}
set allchoices [punk::args::lib::lunique $allchoices]
if {[llength $allchoices] == 0 || [llength $allchoices] > 3} {
return [list]
}
if {![Dict_getdef $arginfo -choicerestricted 1]} {
return [list]
}
set literals [list]
foreach c $allchoices {
lappend literals [list $c]
}
return $literals
}
proc private::synopsis_form_arg_display {formdict argname} {
#non-colour SGR such as bold/italic/strike - so we don't need to worry about NOCOLOR settings
set I "\x1b\[3m" ;#[punk::ansi::a+ italic]
@ -11624,6 +11659,12 @@ tcl::namespace::eval punk::args {
} else {
set tp_displaylist [lrepeat [llength $typelist] ""]
}
if {[llength $typelist] == 1} {
set choice_literals [private::synopsis_choice_literals $arginfo]
} else {
#choice semantics for multi-element clauses are per-clause - keep name/type display hints
set choice_literals [list]
}
foreach typespec $typelist td $tp_displaylist elementname $name_tail {
#elementname will commonly be empty after first iteration
@ -11663,7 +11704,9 @@ tcl::namespace::eval punk::args {
#and if there are enough tail words in the argname to match the position in the type list
#empty strings can be put in -typesynopsis positions to only override the type information for certain elements of the clause
#- e.g for a type list of {string int} we could specify a typesynopsis of {"" "count"} to get display of "FILENAME count" for an argname of "file FILENAME FILECOUNT"
if {[llength $name_tail] >= [llength $typelist]} {
if {[llength $choice_literals]} {
lappend alternates {*}$choice_literals
} elseif {[llength $name_tail] >= [llength $typelist]} {
#important to list protect $elementname e.g look at ::apply
#The name may contain spaces e.g "{args body ?namespace?}"
#This must not be split into multiple words - it is a single element name that happens to contain spaces.
@ -11696,13 +11739,6 @@ tcl::namespace::eval punk::args {
set display "\[$clause\]..."
} else {
set display "\[$clause\]"
#if {[dict exists $arginfo -choices] && [llength [dict get $arginfo -choices]] == 1} {
# set display "?[lindex [dict get $arginfo -choices] 0]?"
#} elseif {[dict get $arginfo -type] eq "literal"} {
# set display "?$argname?"
#} else {
# set display "?$I$argname$NI?"
#}
}
} else {
if {[dict get $arginfo -multiple]} {
@ -11710,13 +11746,6 @@ tcl::namespace::eval punk::args {
set display "$clause \[$clause\]..."
} else {
set display $clause
#if {[dict exists $arginfo -choices] && [llength [dict get $arginfo -choices]] == 1} {
# set display "[lindex [dict get $arginfo -choices] 0]"
#} elseif {[dict get $arginfo -type] eq "literal"} {
# set display $argname
#} else {
# set display "$I$argname$NI"
#}
}
}
return $display
@ -11885,6 +11914,7 @@ tcl::namespace::eval punk::args {
} else {
set alternates [list];#alternate acceptable types e.g literal(yes)|literal(ok) or indexpression|literal(first)
set choice_literals [private::synopsis_choice_literals $arginfo]
set type_alternatives [private::split_type_expression $tp]
foreach tp_alternative $type_alternatives {
set match [lindex $tp_alternative 1]
@ -11902,7 +11932,11 @@ tcl::namespace::eval punk::args {
lappend alternates [list *$match]
}
default {
lappend alternates $I<$tp_alternative>$NI
if {[llength $choice_literals]} {
lappend alternates {*}$choice_literals
} else {
lappend alternates $I<$tp_alternative>$NI
}
}
}
}

3
src/modules/punk/args-buildversion.txt

@ -1,6 +1,7 @@
0.5.0
0.6.0
#First line must be a semantic version number
#all other lines are ignored.
#0.6.0 - synopsis display: small restricted choice sets now render as literal alternates - an argument whose choice pool (-choices plus -choicegroups members, deduplicated) has 1-3 members and -choicerestricted true (the default) displays those words unitalicised joined by | in synopses (e.g 'after cancel' shows literal cancel; a 3-choice option shows (left|centre|right)), matching the display style of literal()/literalprefix() type-alternatives. Larger or unrestricted (-choicerestricted 0) choice sets keep the italicised argname/<type> display, and an explicit -typesynopsis always takes precedence. New private helper punk::args::private::synopsis_choice_literals shared by both synopsis render paths (leaders/values via synopsis_form_arg_display, options inline in synopsis); applies only to single-element -type lists (multi-element clause display unchanged). define doc for -choices documents the rule. Tests: synopsis.test - new characterization coverage for literal/literalprefix/stringstartswith/stringendswith type-alternates, option alternate parenthesization, multi-element clause display, -typesynopsis (value element lists, option passthrough incl documenter ANSI), plus the new choice-literal rule (small sets in leader/option/value positions, choicegroups counting, >3 and unrestricted fallbacks, -typesynopsis precedence)
#0.5.0 - G-049 parse-status data model: new punk::args::parse_status - runs a parse attempt (withid/withdef) and returns a documented status structure instead of raising on validation failure (overall ok/status valid|invalid|incomplete/scheme/message/errorcode-minus-argspecs/failureclass/badarg/id/form/receivednames + per-argument argstatus with class/status ok|bad|unparsed/received/positions/hasvalue/value-in-effect incl -default fill). arg_error: new -parsestatus option - both renderers (table and string) now derive goodarg/badarg row marking and choice value-in-effect highlighting from the structure (built internally from -badarg/-parsedargs when not supplied), replacing the transient goodargs/badarg locals; scheme colours resolve per-render into a local array (scheme renders no longer mutate the shared arg_error_CLR array - the -nocolour leak) and the DOCUMENTED -scheme choice value 'nocolour' (and 'nocolor') now takes effect instead of falling through to leftover colours. parse: new -caller option overriding the %caller% frame-walk substitution in validation failure messages (parse_status defaults it to the definition's @cmd -name). get_dict: missingrequiredvalue/missingrequiredleader allocation failures now carry -badarg (type-failed words get badarg marking, not just choice violations). Tests: parsestatus.test (new), usagemarking.test nocolour/leak GAP pins flipped + -parsestatus render parity
#0.4.2 - G-046: display-field deferral - resolve no longer tstr-expands display-only content during argument resolution: ${...} in -help (@cmd/@examples/argument records) and @formdisplay -header/-body is masked with inert tokens (spec key DISPLAY_DEFERRED) and expanded on demand at display time (arg_error/eg/resolved_def/@default-copyfrom hooks; separate argdefcache_display cache for non-dynamic defs; @dynamic display content re-expands per render preserving provider refresh). First parse of heavily documented commands drops accordingly (punk::ansi::mark_columns ~4.3s -> ~12ms; tclcore ::lseq resolve ~184ms -> ~2ms) and -help content that calls punk::args-parsing commands (including against its own id) no longer stalls or loops - plus a display-time reentrancy guard (raw ${...} source substituted on nested expansion of the same id). Record splitter factored to private::split_definition_records. Also: @dynamic second-round multiline substitutions into deferred fields now get the 'line' paramindents alignment (rendering_atdynamic_multiline_help_insertion GAP flipped); prefix/alias choice normalization writeback no longer list-quotes single-element-clause values ({\Deleted} shape bug, choicegroups_imap_prefix_shape GAP flipped); -return string renderer aligns cmd-help continuations under the Description label and its Example line shows the example instead of the doc url. Tests: deferredhelp.test (new), rendering.test/choicegroups.test updated per G-046 acceptance
#0.4.1 - fixed ensemble_subcommands_definition building the definition against unloaded argdocs: subhelp/doctype-punkargs choiceinfo entries and synopsis choicelabels were omitted for documented subcommands whose registered namespace (::punk::args::register::NAMESPACES) had not yet been lazily loaded - e.g first 'i ansistring' in a fresh shell rendered the autogenerated ensemble help without subcommand-help markers until something else loaded ::punk::ansi::ansistring. The generator now runs update_definitions for the namespaces its id_exists checks could resolve in before testing them (tests: punk/args ensembledef.test, punk/ns cmdhelp.test cmdhelp_ensemble_lazy_registered_argdocs)

2
src/tests/modules/AGENTS.md

@ -40,7 +40,7 @@ Unit tests for editable source modules under `src/modules/`, `src/modules_tcl8/`
- `opunk/console/` — ::opunk::Console backend subclass tests (`testsuites/console/backends.test`, G-001): virtual dispatch of subclass overrides through base-class calls and punk::console::console_spec_resolve (both unchanged), TestConsole determinism + probe-free at_eof, SshConsole capability/eof + the flagship size-via-ANSI-query-over-socket case (a scripted remote terminal answers CSI 6n), TkConsole widget size/eof (gated behind env PUNK_TEST_TK=1 - Tk in the shared testinterp has side effects; also verifiable standalone under a tk-capable kit e.g `punk91 src <script>`)
- `punkcheck/` — punkcheck module tests (install, summarize_install_resultdict, installtrack)
- `punk/ansi/` — punk::ansi tests (`testsuites/ansi/`): ansistrip/ansimerge, plus characterization of the ANSI-at-position mechanisms (`ansistring.test`: INDEX/INDEXCODE/INDEXCHAR/RANGE/INSERT grapheme indexing with SGR-prefix merging, INDEXCOLUMNS/COLUMNINDEX double-wide column mapping, trim/VIEW), code splitting invariants (`ta.test`: detect/detectcode distinction, split_codes/split_codes_single/split_at_codes shapes and round-trip) and single-code/effective-state semantics (`codetype.test`: is_sgr_reset/has_sgr_leadingreset, has_any/all_effective, sgr_merge, sequence_type classify). ANSI codes in these tests are literal escape strings so results are colour-state independent
- `punk/args/` — punk::args tests (`testsuites/args/`): parsing, choices/choicegroups, forms, rendering/indentation characterization, usage-marking characterization (`usagemarking.test`: -parsedargs/-badarg/-parsestatus/-scheme marking primitives plus goodchoice highlighting of selected/default-in-effect choice words, asserted by SGR-parameter subset against the live colour arrays; the G-049 nocolour/colour-leak GAP pins flipped 2026-07-10 to scheme-statelessness assertions), the G-049 parse-status structure (`parsestatus.test`: punk::args::parse_status overall/per-argument statuses, badarg for type/allocation failures, -caller attribution, errorcode -argspecs stripping), and tclcore doc/interpreter behavioural parity (`tclcoreparity.test`, G-054, gated on have_tclcoredocs: 'string is' class choices equal the live-harvested set, per-class docids exist, error-vs-ok agreement across the probe matrix, version-note labels conditional on class presence - expectations derived from the running interpreter, green on 8.6/8.7/9.0; under 8.6 run the file directly via a plain tclkit + tcltest driver since runtests' harness needs newer infrastructure)
- `punk/args/` — punk::args tests (`testsuites/args/`): parsing, choices/choicegroups, forms, rendering/indentation characterization, synopsis display characterization (`synopsis.test`: basic italic argname/`<type>` styling, longopt `--x=` alias forms, literal/literalprefix/stringstartswith/stringendswith type-alternates rendering unitalicised, option alternate parenthesization, multi-element clause display incl `?type?` members and argname tail-word hints, `-typesynopsis` value-element lists and option passthrough incl documenter ANSI, and the small-restricted-choice-set literal rule: 1-3 restricted choices render as unitalicised `|`-joined literals in leader/option/value positions with choicegroups counted, >3 or `-choicerestricted 0` falling back to italics, `-typesynopsis` taking precedence), usage-marking characterization (`usagemarking.test`: -parsedargs/-badarg/-parsestatus/-scheme marking primitives plus goodchoice highlighting of selected/default-in-effect choice words, asserted by SGR-parameter subset against the live colour arrays; the G-049 nocolour/colour-leak GAP pins flipped 2026-07-10 to scheme-statelessness assertions), the G-049 parse-status structure (`parsestatus.test`: punk::args::parse_status overall/per-argument statuses, badarg for type/allocation failures, -caller attribution, errorcode -argspecs stripping), and tclcore doc/interpreter behavioural parity (`tclcoreparity.test`, G-054, gated on have_tclcoredocs: 'string is' class choices equal the live-harvested set, per-class docids exist, error-vs-ok agreement across the probe matrix, version-note labels conditional on class presence - expectations derived from the running interpreter, green on 8.6/8.7/9.0; under 8.6 run the file directly via a plain tclkit + tcltest driver since runtests' harness needs newer infrastructure)
- `punk/ns/` — punk::ns tests (`testsuites/ns/`): cmdwhich/cmdinfo/cmd_traverse doc-lookup flow (`cmdflow.test`, G-040 parity) and cmdhelp usage-rendering integration (`cmdhelp.test`: scheme selection, goodarg/badarg marking incl type/allocation failures, goodchoice highlighting of supplied/default choice words, alias path, cmdinfo result shape, queried-command failure attribution, and `-return dict` parse-status returns (G-049 - its GAP pins flipped 2026-07-10); remaining GAP pins for pseudo-command cmdtype + space-form docid prefixes (G-051, real `string is` pins behind the have_tclcoredocs constraint), TclOO undocumented-method fallback (G-052), and synopsis marking absence (G-050))
- `punk/mix/` — punk::mix::cli tests (prune helpers, punkcheck virtual sources), punk::mix::commandset::repo fossil move/rename characterization tests (`testsuites/repo/`, FOSSIL_HOME-isolated; GAP-marked tests pin behaviour G-022 will change), punk::mix::commandset::loadedlib tests (`testsuites/loadedlib/libsearch.test`: 'dev lib.search' match semantics via -return list — wrap-glob default, =exact prefix, case rules, explicit globs, version aggregation — plus the loadedlib 0.2.0 contract: deep discovery by default (deep .tm modules found without -refresh, registration persists), -refresh = genuine re-scan (epoch incr + rediscovery picks up .tm files added to already-scanned dirs), and highlight working without the shell-global a+ alias; shared provisioned child interp sourcing the source-tree libunknown directly — see the file's ORDERING NOTE), and the MULTISHELL polyglot build machinery (`testsuites/scriptwrap/multishell.test`: scriptset wrap via the punk.multishell.cmd template - structure/LF-only/determinism, checkfile 512-byte label validation of fresh wraps AND the committed bin/runtime.cmd, the runtime scriptset round-trip byte-identity pin, and platform-gated execution smoke: cmd.exe→powershell payload on windows, sh payload on unix or via the `wsllinux` capability constraint from `src/tests/testsupport/wslprobe.tcl` - staged to the WSL distro's native filesystem, G-059)
- `punk/lib/` — punk::lib tests (`testsuites/lib/`): range/index/parse/compat/interp_sync utilities, G-058 static-baseline seeding (`staticseed.test`: interp_sync_package_paths/snapshot_package_paths propagate a simulated ::punkboot static baseline and seed `load {} <prefix>` ifneeded mappings; no-op without a baseline), and the repl command-completeness engine (`commandcomplete.test`: punk::lib::system::incomplete pending-opener stacks - the info-complete quoting quirk progression (`set x "{*}{"` standalone vs in-proc-body), single openers, tabs, escapes, incomplete<->info-complete parity property; pre-repl-refactor characterization, see goals/G-044 detail preserve-list)

9
src/tests/modules/punk/args/testsuites/args/rendering.test

@ -310,6 +310,9 @@ GFLUSH line"
-result [list 0 2 4]
#--- choicelabels conventions ----------------------------------------------------------
#choicelabel fixtures use 4+ choices: a restricted choice set of 1-3 members displays as
#literal alternates in the usage synopsis line (2026-07-11), which would make markercol
#match choice-name markers there instead of in the choices cell being measured.
test rendering_choicelabel_one_space_convention {a single-line choicelabel's leading one-space indent (the 'i string is' convention) is preserved relative to its choice name}\
-setup $common -body {
@ -320,7 +323,7 @@ GFLUSH line"
-help\
"cmd help."
@values -min 1 -max 1
mode -choices {LCALPHA LCBETA} -choicelabels {
mode -choices {LCALPHA LCBETA LCPAD3 LCPAD4} -choicelabels {
LCALPHA " LALABEL text"
LCBETA " LBLABEL text"
} -help\
@ -351,7 +354,7 @@ GFLUSH line"
-help\
"cmd help."
@values -min 1 -max 1
mode -choices {MLEQUAL MLDEEP} -choicelabels {
mode -choices {MLEQUAL MLDEEP MLPAD3 MLPAD4} -choicelabels {
MLEQUAL\
" QLA_L1 label line
QLA_L2 label line"
@ -591,7 +594,7 @@ GFLUSH line"
-help\
"cmd help."
@values -min 1 -max 1
ftype -choices {arta artb} -unindentedfields {-choicelabels} -choicelabels {
ftype -choices {arta artb artc artd} -unindentedfields {-choicelabels} -choicelabels {
${$DYN_RART}
} -help\
"ftype help."

182
src/tests/modules/punk/args/testsuites/args/synopsis.test

@ -71,7 +71,10 @@ namespace eval ::testspace {
namespace delete ::testspace::testns
}\
-result [list\
"# summary\n::testspace::testns::t1 \[[a+ italic]subcmd[a+ noitalic]\]"\
{*}[
#subcmd has 2 restricted choices -> displays as unitalicised literal alternates c1|c2
]\
"# summary\n::testspace::testns::t1 \[c1|c2\]"\
"# summary\n::testspace::testns::t1 c1 [a+ italic]v1[a+ noitalic]"
]
@ -178,6 +181,183 @@ namespace eval ::testspace {
expected-error1\
{--verbose received}
]
#added 2026-07-11 (agent) - characterization of synopsis literal-vs-italic display: type-alternates,
# -typesynopsis passthrough (incl documenter ANSI), and the small-restricted-choice-set literal rule
test synopsis_typealternates_literals {literal()/literalprefix()/stringstartswith()/stringendswith() type-alternates display unitalicised in value position}\
-setup $common -body {
namespace eval testns {
punk::args::define {
@id -id ::testspace::testns::t1
@cmd -summary summary
@values -min 1 -max 2
mode -type literalprefix(text)|literalprefix(binary) -optional 0
pat -type stringstartswith(pre)|stringendswith(.txt) -optional 1
}
}
lappend result [punk::ansi::grepstr -h + -return matched -v {^##} [punk::ns::synopsis ::testspace::testns::t1]]
}\
-cleanup {
namespace delete ::testspace::testns
}\
-result [list\
"# summary\n::testspace::testns::t1 text|binary \[pre*|*.txt\]"
]
test synopsis_typealternates_option_parens {alternates on an option value are parenthesized to disambiguate from flag-alias pipes; non-matching alternative stays italic <type>}\
-setup $common -body {
namespace eval testns {
punk::args::define {
@id -id ::testspace::testns::t1
@cmd -summary summary
-o1 -type literal(auto)|int
}
}
lappend result [punk::ansi::grepstr -h + -return matched -v {^##} [punk::ns::synopsis ::testspace::testns::t1]]
}\
-cleanup {
namespace delete ::testspace::testns
}\
-result [list\
"# summary\n::testspace::testns::t1 \[-o1 (auto|[a+ italic]<int>[a+ noitalic])\]"
]
test synopsis_clause_multielement {multi-element clause type: argname tail words display per element, ?type? members wrap in brackets}\
-setup $common -body {
namespace eval testns {
punk::args::define {
@id -id ::testspace::testns::t1
@cmd -summary summary
@values -min 1 -max 1
{v1 A B} -type {string ?int?} -optional 0
}
}
lappend result [punk::ansi::grepstr -h + -return matched -v {^##} [punk::ns::synopsis ::testspace::testns::t1]]
}\
-cleanup {
namespace delete ::testspace::testns
}\
-result [list\
"# summary\n::testspace::testns::t1 [a+ italic]A[a+ noitalic] \[[a+ italic]B[a+ noitalic]\]"
]
test synopsis_typesynopsis_value_elements {-typesynopsis list on a clause value: empty members keep default display, non-empty members display verbatim unitalicised}\
-setup $common -body {
namespace eval testns {
punk::args::define {
@id -id ::testspace::testns::t1
@cmd -summary summary
@values -min 1 -max 1
{file FNAME FCOUNT} -type {string int} -typesynopsis {{} count} -optional 0
}
}
lappend result [punk::ansi::grepstr -h + -return matched -v {^##} [punk::ns::synopsis ::testspace::testns::t1]]
}\
-cleanup {
namespace delete ::testspace::testns
}\
-result [list\
"# summary\n::testspace::testns::t1 [a+ italic]FNAME[a+ noitalic] count"
]
test synopsis_typesynopsis_option_passthrough {-typesynopsis on an option passes through verbatim - including documenter-supplied ANSI styling}\
-setup $common -body {
namespace eval testns [string map [list %TS% "[a+ italic]n[a+ noitalic]"] {
punk::args::define {
@id -id ::testspace::testns::t1
@cmd -summary summary
-x -type string -typesynopsis <n>
-y -type string -typesynopsis %TS%
}
}]
lappend result [punk::ansi::grepstr -h + -return matched -v {^##} [punk::ns::synopsis ::testspace::testns::t1]]
}\
-cleanup {
namespace delete ::testspace::testns
}\
-result [list\
"# summary\n::testspace::testns::t1 \[-x <n>\] \[-y [a+ italic]n[a+ noitalic]\]"
]
test synopsis_choices_small_literal {restricted choice sets of 1-3 members display as unitalicised literal alternates in leader, option and value positions}\
-setup $common -body {
namespace eval testns {
punk::args::define {
@id -id ::testspace::testns::t1
@cmd -summary summary
@leaders -min 1 -max 1
cancel -choices {cancel}
@opts
-align -choices {left centre right}
@values -min 1 -max 1
where -optional 0 -choices {top bottom}
}
}
lappend result [punk::ansi::grepstr -h + -return matched -v {^##} [punk::ns::synopsis ::testspace::testns::t1]]
}\
-cleanup {
namespace delete ::testspace::testns
}\
-result [list\
"# summary\n::testspace::testns::t1 cancel \[-align (left|centre|right)\] top|bottom"
]
test synopsis_choicegroups_counted {choicegroups members count toward the small-choice-set literal display}\
-setup $common -body {
namespace eval testns {
punk::args::define {
@id -id ::testspace::testns::t1
@cmd -summary summary
@values -min 1 -max 1
mode -optional 0 -choicegroups {g1 {a b}}
}
}
lappend result [punk::ansi::grepstr -h + -return matched -v {^##} [punk::ns::synopsis ::testspace::testns::t1]]
}\
-cleanup {
namespace delete ::testspace::testns
}\
-result [list\
"# summary\n::testspace::testns::t1 a|b"
]
test synopsis_choices_fallback_italic {more than 3 choices, or -choicerestricted 0, fall back to italic argname/type display}\
-setup $common -body {
namespace eval testns {
punk::args::define {
@id -id ::testspace::testns::t1
@cmd -summary summary
-t -type dict -choices {a b} -choicerestricted 0
@values -min 1 -max 1
mode -optional 0 -choices {a b c d}
}
}
lappend result [punk::ansi::grepstr -h + -return matched -v {^##} [punk::ns::synopsis ::testspace::testns::t1]]
}\
-cleanup {
namespace delete ::testspace::testns
}\
-result [list\
"# summary\n::testspace::testns::t1 \[-t [a+ italic]<dict>[a+ noitalic]\] [a+ italic]mode[a+ noitalic]"
]
test synopsis_choices_typesynopsis_precedence {an explicit -typesynopsis overrides the small-choice-set literal display}\
-setup $common -body {
namespace eval testns {
punk::args::define {
@id -id ::testspace::testns::t1
@cmd -summary summary
-t -choices {x y} -typesynopsis FOO
}
}
lappend result [punk::ansi::grepstr -h + -return matched -v {^##} [punk::ns::synopsis ::testspace::testns::t1]]
}\
-cleanup {
namespace delete ::testspace::testns
}\
-result [list\
"# summary\n::testspace::testns::t1 \[-t FOO\]"
]
}
tcltest::cleanupTests ;#needed to produce test summary line.

Loading…
Cancel
Save