Browse Source

G-045 increment 1: punk::args 0.6.1 - @cmd honours -unindentedfields for -help (project 0.12.4)

arg_error's cmd-help display transform (undent "    "+help, max 4 - the
'#unindentedfields ?' todo site) is now gated by "-help" membership in the
@cmd line's -unindentedfields list, mirroring the existing per-argument
gate. The single transform site feeds both the table and string renderers,
so left-margin-authored @cmd help renders its first line flush with
continuations in both. @cmd -summary carries no indent transform in any
renderer, so -unindentedfields for -summary is vacuously honoured. No
in-tree definitions set -unindentedfields on @cmd - existing rendering is
unchanged. define doc for -unindentedfields now states where the option is
valid.

Tests: rendering_unindentedfields_cmd_help_GAP flipped to
rendering_unindentedfields_cmd_help (aligned expectation, both renderers
measured). Full punk::args suite 175 pass / 1 pre-existing skip / 0 fail;
punk::ns suite 53/53 (arg_error consumer); make.tcl modules builds clean
(tclsh 9.0.3).

Also: G-045 flipped proposed -> active (user direction 2026-07-12);
progress and remaining-work recorded in the detail file.

Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
master
Julian Noble 3 days ago
parent
commit
bb9ff66f51
  1. 4
      CHANGELOG.md
  2. 2
      GOALS.md
  3. 33
      goals/G-045-punkargs-authoring-ergonomics.md
  4. 2
      punkproject.toml
  5. 12
      src/modules/punk/args-999999.0a1.0.tm
  6. 3
      src/modules/punk/args-buildversion.txt
  7. 21
      src/tests/modules/punk/args/testsuites/args/rendering.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.4] - 2026-07-12
- G-045 (increment): punk::args 0.6.1 - the @cmd directive now honours -unindentedfields for -help, so command help authored at the left margin renders its first line flush with continuations in help/usage displays (previously the option was accepted on @cmd but ignored). No shipped definitions used it yet, so existing help rendering is unchanged; the define documentation states where -unindentedfields is valid.
## [0.12.3] - 2026-07-12
- punk::args 0.6.0 synced into the common vfs payload (_vfscommon.vfs): help/usage synopses render small restricted choice sets as literal alternates (module change committed earlier as c309ed47; this ships it in built kits).

2
GOALS.md

@ -210,7 +210,7 @@ Detail: goals/G-043-subshell-definition-plugins.md
Scope: src/modules/punk/repl-999999.0a1.0.tm (editbuf/reader integration, provider seam), src/modules/punk/args-999999.0a1.0.tm + src/modules/punk/ns-999999.0a1.0.tm (introspection surfaces as consumed), src/modules/punk/console-999999.0a1.0.tm (rendering)
Detail: goals/G-044-repl-command-completion.md
### G-045 [proposed] punk::args definition authoring ergonomics: record continuation, @cmd unindented fields, constructed-definition normalization
### G-045 [active] punk::args definition authoring ergonomics: record continuation, @cmd unindented fields, constructed-definition normalization
Scope: src/modules/punk/args-999999.0a1.0.tm (record parsing in resolve, tstr interplay, arg_error @cmd rendering), src/tests/modules/punk/args/testsuites/ (rendering.test/defquoting.test as the safety net), src/modules/punk-999999.0a1.0.tm (::punk::helptopic::define_docs de-hacked as the consumer proof)
Detail: goals/G-045-punkargs-authoring-ergonomics.md

33
goals/G-045-punkargs-authoring-ergonomics.md

@ -1,6 +1,6 @@
# G-045 punk::args definition authoring ergonomics: record continuation, @cmd unindented fields, constructed-definition normalization
Status: proposed
Status: active
Scope: src/modules/punk/args-999999.0a1.0.tm (record parsing in resolve, tstr interplay, arg_error @cmd rendering), src/tests/modules/punk/args/testsuites/ (rendering.test/defquoting.test as the safety net), src/modules/punk-999999.0a1.0.tm (::punk::helptopic::define_docs de-hacked as the consumer proof)
Goal: authoring punk::args definitions no longer requires backslash line-continuations or ad-hoc workarounds for multi-line records and constructed definitions - a parser-recognised record-continuation mechanism (candidate: an unquoted trailing -& token, with the detail file recording the collision analysis and the element-count disambiguation alternative), -unindentedfields honoured for @cmd fields, and constructed (string-built) definitions able to opt into the same whole-block indent normalization file-style definitions get - with the container quoting rules (braced=literal, quoted=Tcl backslash semantics, \$\{ escape) promoted from defquoting.test into the define documentation.
Acceptance: a definition using the chosen record-continuation mechanism parses identically to its backslash-continuation equivalent (existing definitions unchanged - continuation is additive), with the token's collision rules documented and an escape/rejection story for values that legitimately match it; @cmd -help/-summary honour -unindentedfields (the rendering.test GAP rendering_unindentedfields_cmd_help_GAP flips to aligned); a constructed definition can request whole-block normalization so embedded continuation indentation behaves as in file-style definitions (the rendering_constructed_def_indent_characterization expectations updated to the chosen semantics), and ::punk::helptopic::define_docs drops its manual pre-normalization to prove it; the quoting rules from defquoting.test appear in the punk::args::define -help documentation; the full punk::args suite (128 tests incl. the rendering invariants: nesting independence, relative-indent preservation) passes with GAP tests flipped, none weakened.
@ -95,3 +95,34 @@ punk::imap4's {\Deleted}/{$MDNSent} choice values) have them stated, not just te
experimental define_docs hack (uncommitted punk.tm working-tree diff at the time of
drafting - superseded by this goal when implemented).
- Archived-goal references in this file: G-046 achieved 2026-07-10 (goals/archive/G-046-punkargs-deferred-help-and-fixes.md).
## Progress
### 2026-07-12 increment 1: @cmd -unindentedfields honoured (punk::args 0.6.1)
- arg_error's cmd-help display transform (undent " "+help, max 4 - the
'#unindentedfields ?' todo site) is now gated by "-help" membership in the @cmd
line's -unindentedfields list, mirroring the existing per-argument gate. The
single transform site feeds both the table and string renderers.
- rendering_unindentedfields_cmd_help_GAP flipped to
rendering_unindentedfields_cmd_help (expects aligned; both renderers measured).
- @cmd -summary: verified no renderer applies an indent transform to -summary (it
is only used inline in synopsis "# ..." lines), so -unindentedfields membership
for -summary is accepted and vacuously honoured - nothing to gate. This
satisfies the acceptance's "-help/-summary honour" clause for -summary.
- Blast radius checked before the change: no in-tree definition sets
-unindentedfields on a @cmd line, so no existing rendering changed.
- define doc for -unindentedfields now states where the option is valid
(argument lines and the @cmd directive's -help).
- Verified (tclsh 9.0.3): full punk::args suite 175 pass / 1 pre-existing skip /
0 fail; punk::ns suite 53/53 (arg_error consumer); make.tcl modules builds
clean.
Remaining for acceptance:
- record-continuation mechanism (the -& candidate): collision rules, escape
story, parses identically to backslash-continuation equivalent, documented
- constructed-definition whole-block normalization opt-in, with
rendering_constructed_def_indent_characterization expectations updated and
::punk::helptopic::define_docs de-hacked as the consumer proof
- defquoting.test container quoting rules promoted into the punk::args::define
-help documentation

2
punkproject.toml

@ -1,4 +1,4 @@
[project]
name = "punkshell"
version = "0.12.3"
version = "0.12.4"
license = "BSD-2-Clause"

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

@ -1037,6 +1037,8 @@ tcl::namespace::eval punk::args {
should have their value strings placed with reference to the
left margin in the source code. ie all whitespace in the source
is preserved.
Valid on argument lines (e.g -help, -choicelabels) and on the
@cmd directive (-help).
-minsize (type dependant)
-maxsize (type dependant)
-mincap {only valid for regex type - min number of captures}
@ -4965,9 +4967,13 @@ tcl::namespace::eval punk::args {
set cmdsummary [Dict_getdef $spec_dict cmd_info -summary ""]
set cmdhelp [Dict_getdef $spec_dict cmd_info -help ""]
#===========
#unindentedfields ?
set maxundent 4
set cmdhelp [punk::lib::undent " $cmdhelp" $maxundent]
#@cmd -unindentedfields {-help} means the help text is authored at the left
#margin: skip the display-time indent transform (goal G-045; same gate as
#argument -help below)
if {"-help" ni [Dict_getdef $spec_dict cmd_info -unindentedfields {}]} {
set maxundent 4
set cmdhelp [punk::lib::undent " $cmdhelp" $maxundent]
}
#===========
set docname [Dict_getdef $spec_dict doc_info -name "Manual:"]

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

@ -1,6 +1,7 @@
0.6.0
0.6.1
#First line must be a semantic version number
#all other lines are ignored.
#0.6.1 - G-045: @cmd honours -unindentedfields for -help - arg_error's display-time indent transform (undent " "+help, max 4) is now gated by "-help" membership in the @cmd line's -unindentedfields list (same gate argument -help already had), so left-margin-authored cmd help renders its first line flush with continuations in both the table and string renderers. Previously the option was accepted on @cmd but ignored (rendering.test rendering_unindentedfields_cmd_help_GAP - flipped to rendering_unindentedfields_cmd_help). No in-tree definitions set @cmd -unindentedfields, so existing rendering is unchanged. Note: @cmd -summary has no indent transform in any renderer, so -unindentedfields membership for -summary is accepted and vacuously honoured. define doc for -unindentedfields now states where the option is valid.
#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

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

@ -15,8 +15,8 @@ package require punk::ansi
# P2 relative-indent preservation: the documenter's continuation-line indentation
# conventions (e.g. lines 2+ indented by 2) survive to display, measured relative
# to the first line - punk::args preserves but does not enforce them
# P3 -unindentedfields: left-margin authoring works for argument -help (and is
# currently accepted but IGNORED for @cmd -help - pinned as a GAP)
# P3 -unindentedfields: left-margin authoring works for argument -help and for
# @cmd -help (the @cmd gate was a pinned GAP until G-045 honoured it, 2026-07-12)
# P4 constructed (string-built) definitions receive no whole-block indent
# normalization ('constructed' - not to be confused with the @dynamic directive):
# embedded continuation indentation is interpreted via the display-time
@ -251,12 +251,13 @@ namespace eval ::testspace {
}\
-result [list 2]
test rendering_unindentedfields_cmd_help_GAP {GAP: @cmd accepts -unindentedfields but ignores it - left-margin authored cmd-help misaligns (first line +4 vs continuations)}\
test rendering_unindentedfields_cmd_help {@cmd -help with -unindentedfields: left-margin authoring renders aligned}\
-setup $common -body {
#the display transform undent(" "+help, max 4) still applies: with
#continuations at the left margin the common prefix is 0, nothing is
#removed, and the first line keeps its injected 4-space prefix.
#(see punk::args arg_error cmd_info handling: '#unindentedfields ?' todo)
#-unindentedfields {-help} on the @cmd line gates the display transform
#undent(" "+help, max 4), so left-margin authored cmd-help keeps its
#first line flush with continuations.
#(was rendering_unindentedfields_cmd_help_GAP pinning the ignored-option
#behaviour - first line +4; flipped by G-045 2026-07-12)
punk::args::define {
@id -id ::testspace::rcmdunind
@cmd -name testspace::rcmdunind -summary\
@ -268,13 +269,15 @@ GFLUSH line"
@values -min 0 -max 0
}
set r [render_table ::testspace::rcmdunind]
#pinned CURRENT behaviour: first line renders 4 right of its continuation
lappend result [expr {[markercol $r GFIRST] - [markercol $r GFLUSH]}]
#and the string renderer shares the gated transform
set rs [render_string ::testspace::rcmdunind]
lappend result [expr {[markercol $rs GFIRST] - [markercol $rs GFLUSH]}]
}\
-cleanup {
punk::args::undefine ::testspace::rcmdunind 1
}\
-result [list 4]
-result [list 0 0]
#--- P4 constructed (string-built) definitions -----------------------------------------

Loading…
Cancel
Save