From 15c10637964e32282503e9ae9211c93396bfe896 Mon Sep 17 00:00:00 2001 From: Julian Noble Date: Sun, 12 Jul 2026 18:51:17 +1000 Subject: [PATCH] vfs: sync punk::args 0.6.0 payload into _vfscommon.vfs (module work committed in c309ed47) Replaces args-0.5.0.tm with the built 0.6.0 (small restricted choice sets display as literal alternates in synopses). Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com --- .../punk/{args-0.5.0.tm => args-0.6.0.tm} | 72 ++++++++++++++----- 1 file changed, 53 insertions(+), 19 deletions(-) rename src/vfs/_vfscommon.vfs/modules/punk/{args-0.5.0.tm => args-0.6.0.tm} (99%) diff --git a/src/vfs/_vfscommon.vfs/modules/punk/args-0.5.0.tm b/src/vfs/_vfscommon.vfs/modules/punk/args-0.6.0.tm similarity index 99% rename from src/vfs/_vfscommon.vfs/modules/punk/args-0.5.0.tm rename to src/vfs/_vfscommon.vfs/modules/punk/args-0.6.0.tm index 811ef21e..233dd0d3 100644 --- a/src/vfs/_vfscommon.vfs/modules/punk/args-0.5.0.tm +++ b/src/vfs/_vfscommon.vfs/modules/punk/args-0.6.0.tm @@ -8,7 +8,7 @@ # (C) 2024 # # @@ Meta Begin -# Application punk::args 0.5.0 +# Application punk::args 0.6.0 # Meta platform tcl # Meta license # @@ Meta End @@ -18,7 +18,7 @@ # doctools header # ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++ #*** !doctools -#[manpage_begin punkshell_module_punk::args 0 0.5.0] +#[manpage_begin punkshell_module_punk::args 0 0.6.0] #[copyright "2024"] #[titledesc {args parsing}] [comment {-- Name section and table of contents description --}] #[moddesc {args to nested dict of opts and values}] [comment {-- Description at end of page heading --}] @@ -905,6 +905,13 @@ tcl::namespace::eval punk::args { -choices {} 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 + } } } } @@ -13670,7 +13704,7 @@ package provide punk::args [tcl::namespace::eval punk::args { tcl::namespace::path {::punk::args::lib ::punk::args::system} variable pkg punk::args variable version - set version 0.5.0 + set version 0.6.0 }] return