Browse Source

table and interactive documentation fixes

master
Julian Noble 2 months ago
parent
commit
5336b12bd5
  1. 27
      src/bootsupport/modules/overtype-1.6.5.tm
  2. 15
      src/bootsupport/modules/punk-0.1.tm
  3. 145
      src/bootsupport/modules/punk/ansi-0.1.1.tm
  4. 1114
      src/bootsupport/modules/punk/args-0.1.0.tm
  5. 15
      src/bootsupport/modules/punk/cap/handlers/templates-0.1.0.tm
  6. 12
      src/bootsupport/modules/punk/config-0.1.tm
  7. 8
      src/bootsupport/modules/punk/console-0.1.1.tm
  8. 6
      src/bootsupport/modules/punk/du-0.1.0.tm
  9. 8
      src/bootsupport/modules/punk/fileline-0.1.0.tm
  10. 26
      src/bootsupport/modules/punk/lib-0.1.1.tm
  11. 3
      src/bootsupport/modules/punk/mix/commandset/doc-0.1.0.tm
  12. 6
      src/bootsupport/modules/punk/mix/commandset/layout-0.1.0.tm
  13. 18
      src/bootsupport/modules/punk/mix/commandset/loadedlib-0.1.0.tm
  14. 13
      src/bootsupport/modules/punk/mix/commandset/module-0.1.0.tm
  15. 8
      src/bootsupport/modules/punk/mix/commandset/scriptwrap-0.1.0.tm
  16. 34
      src/bootsupport/modules/punk/nav/fs-0.1.0.tm
  17. 421
      src/bootsupport/modules/punk/ns-0.1.0.tm
  18. 6
      src/bootsupport/modules/punk/path-0.1.0.tm
  19. 84
      src/bootsupport/modules/punk/repo-0.1.1.tm
  20. 19
      src/bootsupport/modules/punk/zip-0.1.1.tm
  21. 139
      src/bootsupport/modules/textblock-0.1.2.tm
  22. 46
      src/modules/argparsingtest-999999.0a1.0.tm
  23. 15
      src/modules/patternpunk-1.1.tm
  24. 20
      src/modules/poshinfo-999999.0a1.0.tm
  25. 13
      src/modules/punk-0.1.tm
  26. 145
      src/modules/punk/ansi-999999.0a1.0.tm
  27. 1114
      src/modules/punk/args-999999.0a1.0.tm
  28. 494
      src/modules/punk/args/tclcore-999999.0a1.0.tm
  29. 18
      src/modules/punk/blockletter-999999.0a1.0.tm
  30. 15
      src/modules/punk/cap/handlers/templates-999999.0a1.0.tm
  31. 12
      src/modules/punk/config-0.1.tm
  32. 8
      src/modules/punk/console-999999.0a1.0.tm
  33. 6
      src/modules/punk/du-999999.0a1.0.tm
  34. 8
      src/modules/punk/fileline-999999.0a1.0.tm
  35. 26
      src/modules/punk/lib-999999.0a1.0.tm
  36. 3
      src/modules/punk/mix/commandset/doc-999999.0a1.0.tm
  37. 6
      src/modules/punk/mix/commandset/layout-999999.0a1.0.tm
  38. 13
      src/modules/punk/mix/commandset/loadedlib-999999.0a1.0.tm
  39. 13
      src/modules/punk/mix/commandset/module-999999.0a1.0.tm
  40. 8
      src/modules/punk/mix/commandset/scriptwrap-999999.0a1.0.tm
  41. 34
      src/modules/punk/nav/fs-999999.0a1.0.tm
  42. 421
      src/modules/punk/ns-999999.0a1.0.tm
  43. 6
      src/modules/punk/path-999999.0a1.0.tm
  44. 84
      src/modules/punk/repo-999999.0a1.0.tm
  45. 28
      src/modules/punk/safe-999999.0a1.0.tm
  46. 8
      src/modules/punk/sixel-999999.0a1.0.tm
  47. 19
      src/modules/punk/zip-999999.0a1.0.tm
  48. 139
      src/modules/textblock-999999.0a1.0.tm
  49. 27
      src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/overtype-1.6.5.tm
  50. 15
      src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk-0.1.tm
  51. 145
      src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/ansi-0.1.1.tm
  52. 1114
      src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/args-0.1.0.tm
  53. 15
      src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/cap/handlers/templates-0.1.0.tm
  54. 12
      src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/config-0.1.tm
  55. 8
      src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/console-0.1.1.tm
  56. 6
      src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/du-0.1.0.tm
  57. 8
      src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/fileline-0.1.0.tm
  58. 26
      src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/lib-0.1.1.tm
  59. 3
      src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/mix/commandset/doc-0.1.0.tm
  60. 6
      src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/mix/commandset/layout-0.1.0.tm
  61. 18
      src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/mix/commandset/loadedlib-0.1.0.tm
  62. 13
      src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/mix/commandset/module-0.1.0.tm
  63. 8
      src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/mix/commandset/scriptwrap-0.1.0.tm
  64. 34
      src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/nav/fs-0.1.0.tm
  65. 421
      src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/ns-0.1.0.tm
  66. 6
      src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/path-0.1.0.tm
  67. 84
      src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/repo-0.1.1.tm
  68. 19
      src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/zip-0.1.1.tm
  69. 139
      src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/textblock-0.1.2.tm
  70. 27
      src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/overtype-1.6.5.tm
  71. 15
      src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk-0.1.tm
  72. 145
      src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/ansi-0.1.1.tm
  73. 1114
      src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/args-0.1.0.tm
  74. 15
      src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/cap/handlers/templates-0.1.0.tm
  75. 12
      src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/config-0.1.tm
  76. 8
      src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/console-0.1.1.tm
  77. 6
      src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/du-0.1.0.tm
  78. 8
      src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/fileline-0.1.0.tm
  79. 26
      src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/lib-0.1.1.tm
  80. 3
      src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/mix/commandset/doc-0.1.0.tm
  81. 6
      src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/mix/commandset/layout-0.1.0.tm
  82. 18
      src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/mix/commandset/loadedlib-0.1.0.tm
  83. 13
      src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/mix/commandset/module-0.1.0.tm
  84. 8
      src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/mix/commandset/scriptwrap-0.1.0.tm
  85. 34
      src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/nav/fs-0.1.0.tm
  86. 421
      src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/ns-0.1.0.tm
  87. 6
      src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/path-0.1.0.tm
  88. 84
      src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/repo-0.1.1.tm
  89. 19
      src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/zip-0.1.1.tm
  90. 139
      src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/textblock-0.1.2.tm
  91. 27
      src/vendormodules/overtype-1.6.5.tm
  92. 46
      src/vfs/_vfscommon.vfs/modules/argparsingtest-0.1.0.tm
  93. 27
      src/vfs/_vfscommon.vfs/modules/overtype-1.6.5.tm
  94. 15
      src/vfs/_vfscommon.vfs/modules/patternpunk-1.1.tm
  95. 20
      src/vfs/_vfscommon.vfs/modules/poshinfo-0.1.0.tm
  96. 15
      src/vfs/_vfscommon.vfs/modules/punk-0.1.tm
  97. 145
      src/vfs/_vfscommon.vfs/modules/punk/ansi-0.1.1.tm
  98. 1114
      src/vfs/_vfscommon.vfs/modules/punk/args-0.1.0.tm
  99. 494
      src/vfs/_vfscommon.vfs/modules/punk/args/tclcore-0.1.0.tm
  100. 18
      src/vfs/_vfscommon.vfs/modules/punk/blockletter-0.1.0.tm
  101. Some files were not shown because too many files have changed in this diff Show More

27
src/bootsupport/modules/overtype-1.6.5.tm

@ -402,7 +402,10 @@ tcl::namespace::eval overtype {
set looplimit [expr {[tcl::string::length $overblock] + 10}]
}
set scheme 3
#overblock height/width isn't useful in the presence of an ansi input overlay with movements. The number of lines may bear little relationship to the output height
#lassign [blocksize $overblock] _w overblock_width _h overblock_height
set scheme 4
switch -- $scheme {
0 {
#one big chunk
@ -443,11 +446,18 @@ tcl::namespace::eval overtype {
set inputchunks [lindex [list $lflines [unset lflines]] 0]
}
4 {
set inputchunks [list]
foreach ln [split $overblock \n] {
lappend inputchunks [string cat $ln \n]
}
if {[llength $inputchunks]} {
lset inputchunks end [tcl::string::range [lindex $inputchunks end] 0 end-1]
}
}
}
#overblock height/width isn't useful in the presence of an ansi input overlay with movements. The number of lines may bear little relationship to the output height
#lassign [blocksize $overblock] _w overblock_width _h overblock_height
set replay_codes_underlay [tcl::dict::create 1 ""]
@ -495,7 +505,7 @@ tcl::namespace::eval overtype {
}
#review insert_mode. As an 'overtype' function whose main function is not interactive keystrokes - insert is secondary -
#but even if we didn't want it as an option to the function call - to process ansi adequately we need to support IRM (insertion-replacement mode) ESC [ 4 h|l
set renderargs [list -experimental $opt_experimental\
set renderopts [list -experimental $opt_experimental\
-cp437 $opt_cp437\
-info 1\
-crm_mode [tcl::dict::get $vtstate crm_mode]\
@ -510,11 +520,8 @@ tcl::namespace::eval overtype {
-expand_right $opt_expand_right\
-cursor_column $col\
-cursor_row $row\
$undertext\
$overtext\
]
set LASTCALL $renderargs
set rinfo [renderline {*}$renderargs]
set rinfo [renderline {*}$renderopts $undertext $overtext]
set instruction [tcl::dict::get $rinfo instruction]
tcl::dict::set vtstate crm_mode [tcl::dict::get $rinfo crm_mode]
@ -1237,8 +1244,8 @@ tcl::namespace::eval overtype {
append debugmsg "looplimit $looplimit reached\n"
append debugmsg "data_mode:$data_mode\n"
append debugmsg "opt_appendlines:$opt_appendlines\n"
append debugmsg "prev_row :[tcl::dict::get $LASTCALL -cursor_row]\n"
append debugmsg "prev_col :[tcl::dict::get $LASTCALL -cursor_column]\n"
append debugmsg "prev_row :[tcl::dict::get $renderopts -cursor_row]\n"
append debugmsg "prev_col :[tcl::dict::get $renderopts -cursor_column]\n"
tcl::dict::for {k v} $rinfo {
append debugmsg "${Y}$k [ansistring VIEW -lf 1 -vt 1 $v]$RST" \n
}

15
src/bootsupport/modules/punk-0.1.tm

@ -306,10 +306,11 @@ namespace eval punk {
#get last command result that was run through the repl
proc ::punk::get_runchunk {args} {
set argd [punk::args::get_dict {
*opts
@id -id ::punk::get_runchunk
@opts
-1 -optional 1 -type none
-2 -optional 1 -type none
*values -min 0 -max 0
@values -min 0 -max 0
} $args]
#todo - make this command run without truncating previous runchunks
set runchunks [tsv::array names repl runchunks-*]
@ -7152,8 +7153,8 @@ namespace eval punk {
}
punk::args::definition {
*id punk::inspect
*proc -name punk::inspect -help\
@id -id ::punk::inspect
@cmd -name punk::inspect -help\
"Function to display values - used pimarily in a punk pipeline.
The raw value arguments (not options) are always returned to pass
forward in the pipeline.
@ -7227,9 +7228,9 @@ namespace eval punk {
Does not affect return value."
-- -type none -help\
"End of options marker.
It is advisable to use this, as data in a pipeline may often being with -"
It is advisable to use this, as data in a pipeline may often begin with -"
*values -min 0 -max -1
@values -min 0 -max -1
arg -type string -optional 1 -multiple 1 -help\
"value to display"
}
@ -7261,7 +7262,7 @@ namespace eval punk {
foreach {k v} $flags {
if {$k ni [dict keys $defaults]} {
#error "inspect: unknown option $k. Known options: [dict keys $defaults]. If data contains flaglike elements, consider calling with end-of-opts marker. e.g inspect --"
punk::args::get_by_id punk::inspect $args
punk::args::get_by_id ::punk::inspect $args
}
}
set opts [dict merge $defaults $flags]

145
src/bootsupport/modules/punk/ansi-0.1.1.tm

@ -134,27 +134,27 @@ tcl::namespace::eval punk::ansi::class {
}
lappend ::punk::ansi::class::PUNKARGS [list {
*id "punk::ansi::class::class_ansi render_to_input_line"
*proc -name "punk::ansi::class::class_ansi render_to_input_line" -help\
@id -id "::punk::ansi::class::class_ansi render_to_input_line"
@cmd -name "punk::ansi::class::class_ansi render_to_input_line" -help\
"render string from line 0 to line
(experimental/debug)"
-dimensions -type string -help\
"WxH where W is integer width >= 1 and H is integer heigth >= 1"
-minus -type integer -help\
"number of chars to exclude from end"
*values -min 1 -max 1
@values -min 1 -max 1
line -type indexexpression
}]
method render_to_input_line {args} {
if {[llength $args] < 1} {
puts stderr "render_to_input_line usage: ?-dimensions WxH? ?-minus charcount? x"
punk::args::get_by_id "punk::ansi::class::class_ansi render_to_input_line" $args
punk::args::get_by_id "::punk::ansi::class::class_ansi render_to_input_line" $args
}
set x [lindex $args end]
set arglist [lrange $args 0 end-1]
if {[llength $arglist] %2 != 0} {
puts stderr "render_to_input_line usage: ?-dimensions WxH? ?-minus charcount? x"
punk::args::get_by_id "punk::ansi::class::class_ansi render_to_input_line" $args
punk::args::get_by_id "::punk::ansi::class::class_ansi render_to_input_line" $args
}
set opts [tcl::dict::create\
-dimensions 80x24\
@ -167,7 +167,7 @@ tcl::namespace::eval punk::ansi::class {
}
default {
puts stderr "render_to_input_line unexpected argument '$k' usage: ?-dimensions WxH? ?-minus charcount? x"
punk::args::get_by_id "punk::ansi::class::class_ansi render_to_input_line" $args
punk::args::get_by_id "::punk::ansi::class::class_ansi render_to_input_line" $args
}
}
}
@ -588,20 +588,20 @@ tcl::namespace::eval punk::ansi {
}
lappend PUNKARGS [list -dynamic 1 {
*id punk::ansi::example
*proc -name punk::ansi::example -help "Display .ans image files in a grid that will fit in console
@id -id ::punk::ansi::example
@cmd -name punk::ansi::example -help "Display .ans image files in a grid that will fit in console
"
-colwidth -default 82 -help "Width of each column - default of 82 will fit a standard 80wide ansi image (when framed)
You can specify a narrower width to truncate images on the right side"
-folder -default "${[punk::ansi::Get_ansifolder]}" -help "Base folder for files if relative paths are used.
Defaults to <projectbase>/src/testansi - where projectbase is determined from current directory.
"
*values -min 0 -max -1
@values -min 0 -max -1
files -default {belinda.ans bot.ans flower.ans fish.ans} -multiple true -help "List of filenames - leave empty to display 4 defaults"
} ""]
proc example {args} {
set argd [punk::args::get_by_id punk::ansi::example $args]
set argd [punk::args::get_by_id ::punk::ansi::example $args]
set colwidth [dict get $argd opts -colwidth]
set ansifolder [file normalize [dict get $argd opts -folder]]
set fnames [dict get $argd values files]
@ -2355,21 +2355,21 @@ Brightblack 100 Brightred 101 Brightgreen 102 Brightyellow 103 Brightblu
#sgr_cache clear called by punk::console::ansi when set to off
#punk::args depends on punk::ansi - REVIEW
lappend PUNKARGS [list {
@id -id ::punk::ansi::sgr_cache
@cmd -name punk::ansi::sgr_cache -help\
"Convenience function to view and optionally clear the ansi character attribute cache (ansi SGR codes)
"
-action -default "" -choices "clear" -help\
"-action clear will unset the keys in the punk::ansi::sgr_cache dict
This is called automatically when setting 'colour false' in the console"
-pretty -default 1 -type boolean -help\
"use 'pdict punk::ansi::sgr_cache */%str,%ansiview' output"
@values -min 0 -max 0
}]
proc sgr_cache {args} {
set argdef {
*id punk::ansi::sgr_cache
*proc -name punk::ansi::sgr_cache -help\
"Convenience function to view and optionally clear the ansi character attribute cache (ansi SGR codes)
"
-action -default "" -choices "clear" -help\
"-action clear will unset the keys in the punk::ansi::sgr_cache dict
This is called automatically when setting 'colour false' in the console"
-pretty -default 1 -type boolean -help\
"use 'pdict punk::ansi::sgr_cache */%str,%ansiview' output"
*values -min 0 -max 0
}
set argd [punk::args::get_dict $argdef $args]
set argd [punk::args::get_by_id ::punk::ansi::sgr_cache $args]
set action [dict get $argd opts -action]
set pretty [dict get $argd opts -pretty]
@ -2412,34 +2412,7 @@ Brightblack 100 Brightred 101 Brightgreen 102 Brightyellow 103 Brightblu
return [join $lines \n]
}
lappend PUNKARGS [list {
*id punk::ansi::a+
*proc -name "punk::ansi::a+" -help\
"Returns an ANSI sgr escape sequence based on the list of supplied codes.
Unlike punk::ansi::a - it is not prefixed with an ANSI reset.
"
*values -min 0 -max -1
} [string map [list <choices> [dict keys $SGR_map]] {
code -type string -optional 1 -multiple 1 -choices {<choices>} -choiceprefix 0 -choicerestricted 0 -help\
"SGR code from the list below, or an integer corresponding to the code e.g 31 = red.
A leading capital letter indicates a codename applies to the background colour.
Other accepted codes are:
term-<int> Term-<int> foreground/background where int is 0-255 terminal color
term-<termcolour> Term-<termcolour> foreground/background
rgb-<r>-<g>-<b> Rgb-<r>-<g>-<b> foreground/background where <r> <g> <b> are the
0-255 int values for red, green and blue.
rgb#<hexcode> Rgb#<hexcode> where <hexcode> is a 6 char hex colour e.g rgb#C71585
web-<webcolour> Web-<webcolour>
The acceptable values for <termcolour> and <webcolour> can be queried using
punk::ansi::a? term
and
punk::ansi::a? web
Example to set foreground red and background cyan followed by a reset:
set str \"[a+ red Cyan]sample text[a]\"
"
}]]
#PUNKARGS doc performed below, after we create the proc
proc a+ {args} {
#*** !doctools
#[call [fun a+] [opt {ansicode...}]]
@ -2907,6 +2880,41 @@ Brightblack 100 Brightred 101 Brightgreen 102 Brightyellow 103 Brightblu
return $result
}
set SGR_samples [dict create]
foreach k [dict keys $SGR_map] {
dict set SGR_samples $k "[punk::ansi::a+ $k]sample\x1b\[m"
}
lappend PUNKARGS [list {
@id -id ::punk::ansi::a+
@cmd -name "punk::ansi::a+" -help\
"Returns an ANSI sgr escape sequence based on the list of supplied codes.
Unlike punk::ansi::a - it is not prefixed with an ANSI reset.
"
@values -min 0 -max -1
} [string map [list <choices> [dict keys $SGR_map] <choicelabels> $SGR_samples] {
code -type string -optional 1 -multiple 1 -choices {<choices>}\
-choicelabels {<choicelabels>}\
-choicecolumns 5 -choiceprefix 0 -choicerestricted 0 -help\
"SGR code from the list below, or an integer corresponding to the code e.g 31 = red.
A leading capital letter indicates a codename applies to the background colour.
Other accepted codes are:
term-<int> Term-<int> foreground/background where int is 0-255 terminal color
term-<termcolour> Term-<termcolour> foreground/background
rgb-<r>-<g>-<b> Rgb-<r>-<g>-<b> foreground/background where <r> <g> <b> are the
0-255 int values for red, green and blue.
rgb#<hexcode> Rgb#<hexcode> where <hexcode> is a 6 char hex colour e.g rgb#C71585
web-<webcolour> Web-<webcolour>
The acceptable values for <termcolour> and <webcolour> can be queried using
punk::ansi::a? term
and
punk::ansi::a? web
Example to set foreground red and background cyan followed by a reset:
set str \"[a+ red Cyan]sample text[a]\"
"
}]]
proc a {args} {
#*** !doctools
#[call [fun a] [opt {ansicode...}]]
@ -4281,6 +4289,7 @@ tcl::namespace::eval punk::ansi {
}
4 {
#REVIEW - merging extended (e.g 4:4) underline attributes suppresses all other SGR attributes on at least some terminals which don't support extended underlines
#e.g hyper on windows
if {[llength $paramsplit] == 1} {
tcl::dict::set codestate underline 4
} else {
@ -4634,6 +4643,8 @@ tcl::namespace::eval punk::ansi::ta {
#[list_begin definitions]
tcl::namespace::path ::punk::ansi
variable PUNKARGS
#handle both 7-bit and 8-bit csi
#review - does codepage affect this? e.g ebcdic has 8bit csi in different position
@ -4706,15 +4717,31 @@ tcl::namespace::eval punk::ansi::ta {
#variable re_ansi_split "${re_csi_code}|${re_esc_osc1}|${re_esc_osc2}|${re_esc_osc3}|${re_standalones}|${re_ST}|${re_g0_open}|${re_g0_close}"
set re_ansi_split $re_ansi_detect
lappend PUNKARGS [list -dynamic 0 {
@id -id ::punk::ansi::ta::detect
@cmd -name punk::ansi::ta::detect -help\
"Return a boolean indicating whether Ansi codes were detected in text.
Important caveat:
When text is a tcl list made from splitting (or lappending) some ansi string
- individual elements may be braced or have certain chars escaped.
(one example is if a list element contains an unbalanced brace)
This can cause square brackets that form part of the ansi to be backslash escaped
- and the function can fail to match it as an Ansi code.
"
@values -min 1
text -type string
} ]
#*** !doctools
#[call [fun detect] [arg text]]
#[para]Return a boolean indicating whether Ansi codes were detected in text
#[para]Important caveat:
#[para] When text is a tcl list made from splitting (or lappending) some ansi string - individual elements may be braced or have certain chars escaped. (one example is if a list element contains an unbalanced brace)
#[para] This can cause square brackets that form part of the ansi being backslash escaped - and the regexp can fail to match
#detect any ansi escapes
#review - only detect 'complete' codes - or just use the opening escapes for performance?
proc detect {text} [string map [list <re> [list $re_ansi_detect]] {
#*** !doctools
#[call [fun detect] [arg text]]
#[para]Return a boolean indicating whether Ansi codes were detected in text
#[para]Important caveat:
#[para] When text is a tcl list made from splitting (or lappending) some ansi string - individual elements may be braced or have certain chars escaped. (one example is if a list element contains an unbalanced brace)
#[para] This can cause square brackets that form part of the ansi being backslash escaped - and the regexp can fail to match
regexp <re> $text
}]
@ -7405,7 +7432,7 @@ if {![info exists ::punk::args::register::NAMESPACES]} {
set NAMESPACES [list]
}
}
lappend ::punk::args::register::NAMESPACES ::punk::ansi ::punk::ansi::class
lappend ::punk::args::register::NAMESPACES ::punk::ansi ::punk::ansi::class ::punk::ansi::ta
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
## Ready

1114
src/bootsupport/modules/punk/args-0.1.0.tm

File diff suppressed because it is too large Load Diff

15
src/bootsupport/modules/punk/cap/handlers/templates-0.1.0.tm

@ -254,8 +254,9 @@ namespace eval punk::cap::handlers::templates {
}
method folders {args} {
set argd [punk::args::get_dict {
@id -id "::punk::cap::handlers::templates::class::api folders"
-startdir -default ""
*values -max 0
@values -max 0
} $args]
set opts [dict get $argd opts]
@ -471,10 +472,11 @@ namespace eval punk::cap::handlers::templates {
}
method get_itemdict_projectlayouts {args} {
set argd [punk::args::get_dict {
*opts -anyopts 1
@id -id "::punk::cap::handlers::templates::class::api get_itemdict_projectlayouts"
@opts -anyopts 1
#peek -startdir while allowing all other opts/vals to be verified down-the-line instead of here
-startdir -default ""
*values -maxvalues -1
@values -maxvalues -1
} $args]
set opt_startdir [dict get $argd opts -startdir]
@ -648,14 +650,15 @@ namespace eval punk::cap::handlers::templates {
#and a name determining command -command_get_item_name
method _get_itemdict {args} {
set argd [punk::args::get_dict {
*proc -name _get_itemdict
*opts -anyopts 0
@id -id "::punk::cap::handlers::templates::class::api _get_itemdict"
@cmd -name _get_itemdict
@opts -anyopts 0
-startdir -default ""
-templatefolder_subdir -optional 0
-command_get_items_from_base -optional 0
-command_get_item_name -optional 0
-not -default "" -multiple 1
*values -maxvalues -1
@values -maxvalues -1
globsearches -default * -multiple 1
} $args]
set opts [dict get $argd opts]

12
src/bootsupport/modules/punk/config-0.1.tm

@ -362,10 +362,10 @@ tcl::namespace::eval punk::config {
proc configure {args} {
set argdef {
*id punk::config::configure
*proc -name punk::config::configure -help\
@id -id ::punk::config::configure
@cmd -name punk::config::configure -help\
"UNIMPLEMENTED"
*values -min 1 -max 1
@values -min 1 -max 1
whichconfig -type string -choices {startup running stop}
}
set argd [punk::args::get_dict $argdef $args]
@ -388,15 +388,15 @@ tcl::namespace::eval punk::config {
#This is to allow partial configs to be loaded to running, whereas a save of running to any target is always a complete configuration
proc copy {args} {
set argdef {
*id punk::config::copy
*proc -name punk::config::copy -help\
@id -id ::punk::config::copy
@cmd -name punk::config::copy -help\
"Copy a partial or full configuration from one config to another
If a target config has additional settings, then the source config can be considered to be partial with regards to the target.
"
-type -default "" -choices {replace merge} -help\
"Defaults to merge when target is running-config
Defaults to replace when source is running-config"
*values -min 2 -max 2
@values -min 2 -max 2
fromconfig -help\
"running or startup or file name (not fully implemented)"
toconfig -help\

8
src/bootsupport/modules/punk/console-0.1.1.tm

@ -875,7 +875,7 @@ namespace eval punk::console {
}
}
punk::args::set_alias punk::console::code_a+ punk::ansi::a+
punk::args::set_alias ::punk::console::code_a+ ::punk::ansi::a+
proc code_a+ {args} {
variable ansi_wanted
if {$ansi_wanted <= 0} {
@ -1187,14 +1187,14 @@ namespace eval punk::console {
#todo - change -inoutchannels to -terminalobject with prebuilt default
punk::args::definition {
*id punk::console::cell_size
@id -id ::punk::console::cell_size
-inoutchannels -default {stdin stdout} -type list
*values -min 0 -max 1
@values -min 0 -max 1
newsize -default "" -help\
"character cell pixel dimensions WxH"
}
proc cell_size {args} {
set argd [punk::args::get_by_id punk::console::cell_size $args]
set argd [punk::args::get_by_id ::punk::console::cell_size $args]
set inoutchannels [dict get $argd opts -inoutchannels]
set newsize [dict get $argd values newsize]

6
src/bootsupport/modules/punk/du-0.1.0.tm

@ -563,9 +563,10 @@ namespace eval punk::du {
variable win_reparse_tags_by_int
set argd [punk::args::get_dict {
@id -id ::punk::du::lib::Get_attributes_from_iteminfo
-debug -default 0 -help "set 1 for raw data on -debugchannel (default stderr)"
-debugchannel -default stderr -help "channel to write debug output, or none to append to output"
*values -min 1 -max 1
@values -min 1 -max 1
iteminfo -help "iteminfo dict as set by 'twapi::find_file_next <iterator> iteminfo'"
} $args]
set opts [dict get $argd opts]
@ -621,10 +622,11 @@ namespace eval punk::du {
proc attributes_twapi {args} {
set argd [punk::args::get_dict {
@id -id ::punk::du::lib::attributes_twapi
-debug -default 0 -help "set 1 for raw data on -debugchannel (default stderr)"
-debugchannel -default stderr -help "channel to write debug output, or none to append to output"
-detail -default basic -choices {basic full} -help "full returns also the altname/shortname field"
*values -min 1 -max 1
@values -min 1 -max 1
path -help "path to file or folder for which to retrieve attributes"
} $args]
set opts [dict get $argd opts]

8
src/bootsupport/modules/punk/fileline-0.1.0.tm

@ -1252,14 +1252,14 @@ namespace eval punk::fileline {
#[list_begin definitions]
punk::args::definition {
*id punk::fileline::get_textinfo
*proc -name punk::fileline::get_textinfo -help\
@id -id ::punk::fileline::get_textinfo
@cmd -name punk::fileline::get_textinfo -help\
"return: textinfo object instance"
-file -default {} -type existingfile
-translation -default iso8859-1
-encoding -default "\uFFFF"
-includebom -default 0
*values -min 0 -max 1
@values -min 0 -max 1
}
proc get_textinfo {args} {
#*** !doctools
@ -1276,7 +1276,7 @@ namespace eval punk::fileline {
#[para]Currently only utf-8, utf-16* and utf-32* are properly supported even though the other BOMs are detected, reported via get_bomid, and stripped from the data.
#[para]GB18030 falls back to cp936/gbk (unless a gb18030 encoding has been installed). Use -encoding iso8859-1 if this isn't suitable and you need to do your own processing of the bytes.
lassign [dict values [punk::args::get_by_id punk::fileline::get_textinfo $args]] opts values
lassign [dict values [punk::args::get_by_id ::punk::fileline::get_textinfo $args]] opts values
# -- --- --- ---
set opt_file [dict get $opts -file]
set opt_translation [dict get $opts -translation]

26
src/bootsupport/modules/punk/lib-0.1.1.tm

@ -1009,13 +1009,13 @@ namespace eval punk::lib {
set sep " [punk::ansi::a+ Green]=[punk::ansi::a] "
}
set argspec [string map [list %sep% $sep] {
*id punk::lib::pdict
*proc -name pdict -help\
@id -id ::punk::lib::pdict
@cmd -name pdict -help\
"Print dict keys,values to channel
The pdict function operates on variable names - passing the value to the showdict function which operates on values
(see also showdict)"
*opts -any 1
@opts -any 1
#default separator to provide similarity to tcl's parray function
-separator -default "%sep%"
@ -1023,7 +1023,7 @@ namespace eval punk::lib {
-substructure -default {}
-channel -default stdout -help "existing channel - or 'none' to return as string"
*values -min 1 -max -1
@values -min 1 -max -1
dictvar -type string -help "name of variable. Can be a dict, list or array"
@ -1095,14 +1095,16 @@ namespace eval punk::lib {
package require textblock
set argd [punk::args::get_dict [string map [list %sep% $sep %sep_mismatch% $sep_mismatch] {
*id punk::lib::showdict
*proc -name punk::lib::showdict -help "display dictionary keys and values"
@id -id ::punk::lib::showdict
@cmd -name punk::lib::showdict -help "display dictionary keys and values"
#todo - table tableobject
-return -default "tailtohead" -choices {tailtohead sidebyside}
-channel -default none
-trimright -default 1 -type boolean -help "Trim whitespace off rhs of each line.
This can help prevent a single long line that wraps in terminal from making every line wrap due to long rhs padding
"
-trimright -default 1 -type boolean -help\
"Trim whitespace off rhs of each line.
This can help prevent a single long line that wraps in terminal from making
every line wrap due to long rhs padding.
"
-separator -default {%sep%} -help "Separator column between keys and values"
-separator_mismatch -default {%sep_mismatch%} -help "Separator to use when patterns mismatch"
-roottype -default "dict" -help "list,dict,string"
@ -1114,7 +1116,7 @@ namespace eval punk::lib {
-keysortdirection -default increasing -choices {increasing decreasing}
-debug -default 0 -type boolean -help\
"When enabled, produces some rudimentary debug output on stderr"
*values -min 1 -max -1
@values -min 1 -max -1
dictvalue -type list -help "dict or list value"
patterns -default "*" -type string -multiple 1 -help "key or key glob pattern"
}] $args]
@ -2816,7 +2818,7 @@ namespace eval punk::lib {
#eat or own dogfood version - shows the implementation is simpler - but unfortunately not suitable for a simple function like this which should be as fast as possible?
lassign [tcl::dict::values [punk::args::get_dict {
-joinchar -default \n
*values -min 1 -max 1
@values -min 1 -max 1
} $args]] leaders opts values
puts "opts:$opts"
puts "values:$values"
@ -2857,7 +2859,7 @@ namespace eval punk::lib {
#we don't have to decide what is an opt vs a value
#even if the caller provides the argument -block without a value the next function's validation will report a reasonable error because there is now nothing in $values (consumed by -block)
lassign [tcl::dict::values [punk::args::get_dict {
*opts -any 1
@opts -any 1
-block -default {}
} $args]] leaderdict opts valuedict
tailcall linelist {*}$opts {*}[tcl::dict::values $valuedict]

3
src/bootsupport/modules/punk/mix/commandset/doc-0.1.0.tm

@ -168,9 +168,10 @@ namespace eval punk::mix::commandset::doc {
}
proc validate {args} {
set argd [punk::args::get_dict {
@id -id ::punk::mix::commandset::doc::validate
-- -type none -optional 1 -help "end of options marker --"
-individual -type boolean -default 1
*values -min 0 -max -1
@values -min 0 -max -1
patterns -default {*.man} -type any -multiple 1
} $args]
set opt_individual [tcl::dict::get $argd opts -individual]

6
src/bootsupport/modules/punk/mix/commandset/layout-0.1.0.tm

@ -34,7 +34,8 @@ namespace eval punk::mix::commandset::layout {
#per layout functions
proc files {{layout ""}} {
set argd [punk::args::get_dict {
*values -min 1 -max 1
@id -id ::punk::mix::commandset::layout::files
@values -min 1 -max 1
layout -type string -minsize 1
} [list $layout]]
@ -88,7 +89,8 @@ namespace eval punk::mix::commandset::layout {
proc _default {args} {
punk::args::get_dict [subst {
*proc -name ::punk::mix::commandset::layout::collection::_default
@id -id ::punk::mix::commandset::layout::collection::_default
@cmd -name ::punk::mix::commandset::layout::collection::_default
-startdir -type string
-not -type string -multiple 1
globsearches -default * -multiple 1

18
src/bootsupport/modules/punk/mix/commandset/loadedlib-0.1.0.tm

@ -27,20 +27,24 @@ namespace eval punk::mix::commandset::loadedlib {
namespace export *
#search automatically wrapped in * * - can contain inner * ? globs
punk::args::definition {
*id punk::mix::commandset::loadedlib::search
*proc -name "punk::mix::commandset::loadedlib search" -help "search all Tcl libraries available to your local interpreter"
@id -id ::punk::mix::commandset::loadedlib::search
@cmd -name "punk::mix::commandset::loadedlib search" -help "search all Tcl libraries available to your local interpreter"
-return -type string -default table -choices {table tableobject list lines}
-present -type integer -default 2 -choices {0 1 2} -choicelabels {absent present both} -help\
"(unimplemented) Display only those that are 0:absent 1:present 2:both"
-highlight -type boolean -default 1 -help "Highlight which version is present with ansi underline and colour"
"(unimplemented) Display only those that are 0:absent 1:present 2:either"
-highlight -type boolean -default 1 -help\
"Highlight which version is present with ansi underline and colour"
-refresh -default 0 -type boolean -help "Re-scan the tm and library folders"
searchstrings -default * -multiple 1 -help\
"Names to search for, may contain glob chars (* ?) e.g *lib*
If no glob chars are explicitly specified, the searchstring will be wrapped with star globs.
eg name -> *name*"
eg name -> *name*
To search for an exact name prefix it with =
e.g =name -> name
"
}
proc search {args} {
set argd [punk::args::get_by_id punk::mix::commandset::loadedlib::search $args]
set argd [punk::args::get_by_id ::punk::mix::commandset::loadedlib::search $args]
set searchstrings [dict get $argd values searchstrings]
set opts [dict get $argd opts]
set opt_return [dict get $opts -return]
@ -55,7 +59,7 @@ namespace eval punk::mix::commandset::loadedlib {
set packages [package names]
set matches [list]
foreach search $searchstrings {
if {[regexp {[?*]} $search]} {
if {[regexp {[?*\[]} $search]} {
#caller has specified specific glob pattern - use it
#todo - respect supplied case only if uppers present? require another flag?
lappend matches {*}[lsearch -all -inline -nocase $packages $search]

13
src/bootsupport/modules/punk/mix/commandset/module-0.1.0.tm

@ -123,10 +123,11 @@ namespace eval punk::mix::commandset::module {
#return all module templates with repeated ones suffixed with .2 .3 etc
proc templates_dict {args} {
set argspec {
*proc -name templates_dict -help "Templates from module and project paths"
@id -id ::punk::mix::commandset::module::templates_dict
@cmd -name templates_dict -help "Templates from module and project paths"
-startdir -default "" -help "Project folder used in addition to module paths"
-not -default "" -multiple 1
*values
@values
globsearches -default * -multiple 1
}
set argd [punk::args::get_dict $argspec $args]
@ -141,8 +142,8 @@ namespace eval punk::mix::commandset::module {
set moduletypes [punk::mix::cli::lib::module_types]
punk::args::definition [subst {
*id punk::mix::commandset::module::new
*proc -name "punk::mix::commandset::module::new" -help\
@id -id ::punk::mix::commandset::module::new
@cmd -name "punk::mix::commandset::module::new" -help\
"Create a new module file in the appropriate folder within src/modules.
If the name given in the module argument is namespaced,
the necessary subfolder(s) will be used or created."
@ -160,7 +161,7 @@ namespace eval punk::mix::commandset::module {
If false (default) an error will be raised if there is a conflict."
-quiet -default 0 -type boolean -help\
"Suppress information messages on stdout"
*values -min 1 -max 1
@values -min 1 -max 1
module -type string -help\
"Name of module, possibly including a namespace and/or version number
e.g mynamespace::mymodule-1.0"
@ -168,7 +169,7 @@ namespace eval punk::mix::commandset::module {
proc new {args} {
set year [clock format [clock seconds] -format %Y]
# use \uFFFD because unicode replacement char should consistently render as 1 wide
set argd [punk::args::get_by_id punk::mix::commandset::module::new $args]
set argd [punk::args::get_by_id ::punk::mix::commandset::module::new $args]
lassign [dict values $argd] leaders opts values received
set module [dict get $values module]

8
src/bootsupport/modules/punk/mix/commandset/scriptwrap-0.1.0.tm

@ -1262,15 +1262,15 @@ namespace eval punk::mix::commandset::scriptwrap {
# [list_begin arguments]
# [arg_def string args] name-value pairs -scriptpath <path>
# [list_end]
*id punk::mix::commandset::scriptwrap
*proc -name punk::mix::commandset::get_wrapper_folders
@id -id ::punk::mix::commandset::scriptwrap
@cmd -name punk::mix::commandset::get_wrapper_folders
*opts -anyopts 0
@opts -anyopts 0
-scriptpath -default "" -type directory\
-help ""
#todo -help folder within a punk.templates provided area???
*values -minvalues 0 -maxvalues 0
@values -minvalues 0 -maxvalues 0
} $args]
# -- --- --- --- --- --- --- --- ---

34
src/bootsupport/modules/punk/nav/fs-0.1.0.tm

@ -636,13 +636,14 @@ tcl::namespace::eval punk::nav::fs {
# c:/repo/jn/punk/../../blah
#dirfiles assumes we don't have glob chars in the filenames or paths - dirfiles_dict can be called directly with explicit -tailglob in the rare case that assumption doesn't hold
# dirfiles will test last segment (tail) of supplied searchspecs for fileness vs folderness (when no globchars present in tail) so that it can pass the appropriate flags downstream
punk::args::definition {
@id -id ::punk::nav::fs::dirfiles
-stripbase -default 1 -type boolean
-formatsizes -default 1 -type boolean -help "Format file size numbers for clarity"
@values -min 0 -max -1
}
proc dirfiles {args} {
set argspecs {
-stripbase -default 1 -type boolean
-formatsizes -default 1 -type boolean -help "Format file size numbers for clarity"
*values -min 0 -max -1
}
set argd [punk::args::get_dict $argspecs $args]
set argd [punk::args::get_by_id ::punk::nav::fs::dirfiles $args]
lassign [dict values $argd] leaders opts values_dict
set opt_stripbase [dict get $opts -stripbase]
@ -726,14 +727,14 @@ tcl::namespace::eval punk::nav::fs {
# -searchbase is always passed through - and is only used to construct a location path if a relative searchspec was supplied
proc dirfiles_dict {args} {
set argspecs {
*id punk::nav::fs::dirfiles_dict
*opts -any 0
@id -id ::punk::nav::fs::dirfiles_dict
@opts -any 0
-searchbase -default ""
-tailglob -default "\uFFFF"
#with_sizes & with_times must accept 0|1|f|d|l where f = files d = dirs l = links (punk::du)
-with_sizes -default "\uFFFF" -type string
-with_times -default "\uFFFF" -type string
*values -min 0 -max -1 -type string
@values -min 0 -max -1 -type string
}
set argd [punk::args::get_dict $argspecs $args]
lassign [dict values $argd] leaders opts vals
@ -991,16 +992,17 @@ tcl::namespace::eval punk::nav::fs {
return [dict merge $listing $updated]
}
punk::args::definition {
@id -id ::punk::nav::fs::dirfiles_dict_as_lines
-stripbase -default 0 -type boolean
-formatsizes -default 1 -type boolean
@values -min 1 -max -1 -type dict
}
#todo - color key via repl-telemetry? help command? documentation? or add tag columns as done in namespace listing?
proc dirfiles_dict_as_lines {args} {
package require overtype
set argspecs {
-stripbase -default 0 -type boolean
-formatsizes -default 1 -type boolean
*values -min 1 -max -1 -type dict
}
set argd [punk::args::get_dict $argspecs $args]
set argd [punk::args::get_by_id ::punk::nav::fs::dirfiles_dict_as_lines $args]
lassign [dict values $argd] leaders opts vals
set list_of_dicts [dict values $vals]

421
src/bootsupport/modules/punk/ns-0.1.0.tm

@ -1608,7 +1608,7 @@ tcl::namespace::eval punk::ns {
if {$word1 eq "punk::mix::base::_cli"} {
#special case for punk deck - REVIEW
#e.g punk::mix::base::_cli -extension ::punk::mix::cli
set fq [lindex $tgt end]
set fq [lindex $tgt end] ;#todo - explicitly get -extension argval in case _cli extended with other options
} else {
#todo - alias may have prefilled some leading args - so usage report should reflect that???
#(currying)
@ -1618,7 +1618,8 @@ tcl::namespace::eval punk::ns {
set fq [nsjoin $location $c]
}
if {$has_punkargs} {
set id [string trimleft $fq :]
#set id [string trimleft $fq :]
set id $fq
if {[::punk::args::id_exists $id]} {
lappend usageinfo $c
} else {
@ -1892,110 +1893,188 @@ tcl::namespace::eval punk::ns {
}
} |data@@ok/result> {lmap v $data {punk::ns::nstail $v}} |> lsort |> {join $data \n} <ns/0|
proc ensemble_subcommands {origin} {
set ensembleinfo [namespace ensemble configure $origin]
set prefixes [dict get $ensembleinfo -prefixes]
set map [dict get $ensembleinfo -map]
set ns [dict get $ensembleinfo -namespace]
#review - we can have a combination of commands from -map as well as those exported from -namespace
# if and only if -subcommands is specified
set subcommand_dict [dict create]
set commands [list]
set nscommands [list]
if {[llength [dict get $ensembleinfo -subcommands]]} {
#set exportspecs [namespace eval $ns {namespace export}]
#foreach pat $exportspecs {
# lappend nscommands {*}[info commands ${ns}::$pat]
#}
#when using -subcommands, even unexported commands are available
set nscommands [info commands ${ns}::*]
foreach sub [dict get $ensembleinfo -subcommands] {
if {[dict exists $map $sub]} {
#-map takes precence over same name exported from -namespace
dict set subcommand_dict $sub [dict get $map $sub]
} elseif {"${ns}::$sub" in $nscommands} {
dict set subcommand_dict $sub ${ns}::$sub
} else {
#subcommand probably supplied via -unknown handler?
dict set subcommand_dict $sub ""
}
}
} else {
if {[dict size $map]} {
set subcommand_dict $map
} else {
set exportspecs [namespace eval $ns {namespace export}]
foreach pat $exportspecs {
lappend nscommands {*}[info commands ${ns}::$pat]
}
foreach fqc $nscommands {
dict set subcommand_dict [namespace tail $fqc] $fqc
}
}
}
return $subcommand_dict
}
#todo - -cache or -refresh to configure whether we introspect ensembles/objects each time?
# - as this is interactive generally introspection should be ok at the top level
# but if we need to go down multiple levels of subcommands generating/testing prefixes - could be an issue ??
punk::args::definition {
*id punk::ns::arginfo
*proc -name punk::ns::arginfo -help\
"Show usage info for a command"
@id -id ::punk::ns::arginfo
@cmd -name punk::ns::arginfo -help\
"Show usage info for a command.
It supports the following:
1) Procedures or builtins for which a punk::args definition has
been loaded.
2) tepam procedures (returns string form only)
3) ensemble commands - auto-generated unless documented via punk::args
(subcommands will show with an indicator if they are
explicitly documented or are themselves ensembles)
4) tcl::oo objects - auto-gnerated unless documented via punk::args
5) dereferencing of aliases to find underlying command
(will not work with some renamed aliases)
Note that native commands commands not explicitly documented will
generally produce no useful info. For example sqlite3 dbcmd objects
could theoretically be documented - but as 'info cmdtype' just shows
'native' they can't (?) be identified as belonging to sqlite3 without
calling them. arginfo deliberately avoids calling commands to elicit
usage information as this is inherently risky. (could create a file,
exit the interp etc)
"
-return -type string -default table -choices {string table tableobject}
-- -type none -help\
"End of options marker
Use this if the command to view begins with a -"
*values -min 1
@values -min 1
commandpath -help\
"command (may be alias or ensemble)"
"command (may be alias, ensemble, tcl::oo object, tepam proc etc)"
subcommand -optional 1 -multiple 1 -default {} -help\
"subcommand if commandpath is an ensemble.
Multiple subcommands can be supplied if ensembles are further nested"
}
proc arginfo {args} {
lassign [dict values [punk::args::get_by_id punk::ns::arginfo $args]] leaders opts values received
set commandpath [dict get $values commandpath]
set commandargs [dict get $values subcommand]
lassign [dict values [punk::args::get_by_id ::punk::ns::arginfo $args]] leaders opts values received
set querycommand [dict get $values commandpath]
set queryargs [dict get $values subcommand]
punk::args::update_definitions ;#ensure any packages that register PUNKARGS have been loaded
#todo - similar to corp? review corp resolution process
#should handle lazy loaded commands (via ::auto_index) that are not yet present but may be documented
if {[string match ::* $commandpath]} {
set targetns [nsprefix $commandpath]
set name [nstail $commandpath]
#don't use 'info commands $commandpath' - or Tcl will use 'namespace path' resolution to find command in another ns or in global
if {[string match ::* $querycommand]} {
set targetns [nsprefix $querycommand]
set name [nstail $querycommand]
#don't use 'info commands $querycommand' - or Tcl will use 'namespace path' resolution to find command in another ns or in global
#when arginfo given a fully qualified path - we only want an answer for that exact command
set nscommands [info commands ${targetns}::*]
if {[lsearch -exact $nscommands $commandpath] >= 0} {
if {[lsearch -exact $nscommands $querycommand] >= 0} {
#use nseval_ifexists to avoid creating intermediate namespaces for bogus paths
if {[catch {
set origin [nseval_ifexists $targetns [list ::namespace origin $name]]
set resolved [nseval_ifexists $targetns [list ::namespace which $name]]
}]} {
set origin $commandpath
set resolved $commandpath
set origin $querycommand
set resolved $querycommand
}
} else {
#fully qualified command specified but doesn't exist
set origin $commandpath
set resolved $commandpath
set origin $querycommand
set resolved $querycommand
}
} else {
set thispath [uplevel 1 [list ::nsthis $commandpath]]
set targetns [nsprefix $thispath]
set name [nstail $thispath]
set targetparts [nsparts $targetns]
if {[lsearch $targetparts :*] >=0} {
#weird ns
set valid_ns [nsexists $targetns]
#relative comandpath
if {[string match (autodef)* $querycommand]} {
#pass through - should be found with id lookup
set origin $querycommand
set resolved $querycommand
} else {
set valid_ns [namespace exists $targetns]
}
if {$valid_ns} {
if {[catch {
set origin [nseval_ifexists $targetns [list ::namespace origin $name]]
set resolved [nseval_ifexists $targetns [list ::namespace which $name]]
}]} {
set thiscmd [nsjoin $targetns $name]
#relative commandpath specified - but Tcl didn't find a match in namespace path
#assume global (todo - look for namespace match in auto_index first ?)
set origin ::$name
set resolved ::$name
set thispath [uplevel 1 [list ::nsthis $querycommand]]
set targetns [nsprefix $thispath]
set name [nstail $thispath]
set targetparts [nsparts $targetns]
if {[lsearch $targetparts :*] >=0} {
#weird ns
set valid_ns [nsexists $targetns]
} else {
set valid_ns [namespace exists $targetns]
}
if {$valid_ns} {
if {[catch {
set origin [nseval_ifexists $targetns [list ::namespace origin $name]]
set resolved [nseval_ifexists $targetns [list ::namespace which $name]]
}]} {
set thiscmd [nsjoin $targetns $name]
#relative querycommand specified - but Tcl didn't find a match in namespace path
#assume global (todo - look for namespace match in auto_index first ?)
set origin ::$name
set resolved ::$name
}
} else {
#namespace as relative to current doesn't seem to exist
#Tcl would also attempt to resolve as global
set numvals [expr {[llength $queryargs]+1}]
#puts "THROWBACK: namespace eval :: [list punk::ns::arginfo {*}[lrange $args 0 end-$numvals] $querycommand {*}$queryargs]"
return [namespace eval :: [list punk::ns::arginfo {*}[lrange $args 0 end-$numvals] $querycommand {*}$queryargs]]
#set origin $querycommand
#set resolved $querycommand
}
} else {
#namespace doesn't seem to exist - but there still could be documentation for lazy loaded ns and command
set origin $commandpath
set resolved $commandpath
}
}
#set thiscmd [nsjoin $targetns $name]
#if {[info commands $thiscmd] eq ""} {
# set origin $thiscmd
# set resolved $thiscmd
#} else {
# set origin [nseval $targetns [list ::namespace origin $name]]
# set resolved [nseval $targetns [list ::namespace which $name]]
#}
}
}
#ns::cmdtype only detects alias type on 8.7+?
set initial_cmdtype [punk::ns::cmdtype $origin]
switch -- $initial_cmdtype {
na - alias {
#REVIEW - alias entry doesn't necessarily match command!
#considure using which_alias (wiki)
#consider using which_alias (wiki)
set tgt [interp alias "" $origin]
if {$tgt eq ""} {
set tgt [interp alias "" [string trimleft $origin :]]
}
#first word of tgt may be namespace relative or absolute
if {$tgt ne ""} {
set word1 [lindex $tgt 0]
if {$word1 eq "punk::mix::base::_cli"} {
#special case for punk deck - REVIEW
#e.g punk::mix::base::_cli -extension ::punk::mix::cli
set fq [lindex $tgt end]
set targetword [lindex $tgt end]
} else {
#todo - alias may have prefilled some leading args - so usage report should reflect that???
#(possible curried arguments)
#review - curried arguments could be for ensembles!
set fq $word1
set targetword $word1
set numvals [expr {[llength $queryargs]+1}]
#puts "ALIAS THROWBACK: namespace eval :: [list punk::ns::arginfo {*}[lrange $args 0 end-$numvals] $targetword {*}[lrange $tgt 1 end] {*}$queryargs]"
return [namespace eval :: [list punk::ns::arginfo {*}[lrange $args 0 end-$numvals] $targetword {*}[lrange $tgt 1 end] {*}$queryargs]]
}
set origin $fq
set origin $targetword
#retest cmdtype on modified origin
set cmdtype [punk::ns::cmdtype $origin]
} else {
@ -2013,6 +2092,83 @@ tcl::namespace::eval punk::ns {
}
}
set id $origin
if {[info commands ::punk::args::id_exists] ne ""} {
#cycle through longest first checking for id matching ::cmd ?subcmd..?
#REVIEW - this doesn't cater for prefix callable subcommands!
set argcopy $queryargs
while {[llength $argcopy]} {
if {[punk::args::id_exists [list $id {*}$argcopy]]} {
return [uplevel 1 [list punk::args::usage {*}$opts [list $id {*}$argcopy]]]
}
lpop argcopy
}
#didn't find any exact matches
#traverse from other direction taking prefixes into account
if {[punk::args::id_exists $id]} {
#cycle forward through leading values
set def [punk::args::get_def $id]
if {[llength $queryargs]} {
set nextqueryargs [list] ;#build a list of prefix-resolved queryargs
set queryargs_untested $queryargs
foreach q $queryargs {
if {[llength [dict get $def leader_names]]} {
set subitems [dict get $def leader_names]
if {[llength $subitems]} {
set next [lindex $subitems 0]
set arginfo [dict get $def arg_info $next]
set allchoices [list]
set choices [punk::args::system::Dict_getdef $arginfo -choices {}]
set choicegroups [punk::args::system::Dict_getdef $arginfo -choicegroups {}]
if {[dict exists $choicegroups ""]} {
dict lappend choicegroups "" {*}$choices
} else {
set choicegroups [dict merge [dict create "" $choices] $choicegroups]
}
dict for {groupname clist} $choicegroups {
lappend allchoices {*}$clist
}
set resolved_q [tcl::prefix::match -error "" $allchoices $q]
if {$resolved_q eq ""} {
break
}
lappend nextqueryargs $resolved_q
lpop queryargs_untested 0
if {$resolved_q ne $q} {
#we have our first difference - recurse with new query args
set numvals [expr {[llength $queryargs]+1}]
return [ punk::ns::arginfo {*}[lrange $args 0 end-$numvals] $querycommand {*}$nextqueryargs {*}$queryargs_untested]
}
#check if subcommands so far have a custom args def
set currentid [list $querycommand {*}$nextqueryargs]
if {[punk::args::id_exists $currentid]} {
set def [punk::args::get_def $currentid
} else {
#We can get no further with custom defs
break
}
}
} else {
#review
break
}
}
} else {
return [uplevel 1 [list punk::args::usage {*}$opts $id]]
}
}
}
if {[string match "(autodef)*" $origin]} {
#wasn't resolved by id - so take this as a request to generate it (probably there is an existing custom def - and this has been manually requested to get the default)
set origin [string range $origin [string length (autodef)] end]
set resolved $origin
}
switch -- $cmdtype {
object {
#class is also an object
@ -2025,19 +2181,19 @@ tcl::namespace::eval punk::ns {
#set class_methods [info class methods $class]
#set object_methods [info object methods $origin]
if {[llength $commandargs]} {
set c1 [lindex $commandargs 0]
if {[llength $queryargs]} {
set c1 [lindex $queryargs 0]
if {$c1 in $public_methods} {
switch -- $c1 {
new {
set constructorinfo [info class constructor $origin]
set arglist [lindex $constructorinfo 0]
set argspec [punk::lib::tstr -return string {
*id "${$origin} new"
*proc -name "${$origin} new" -help\
@id -id "(autodef)${$origin} new"
@cmd -name "${$origin} new" -help\
"create object with specified command name.
Arguments are passed to the constructor."
*values
@values
}]
set i 0
foreach a $arglist {
@ -2054,17 +2210,17 @@ tcl::namespace::eval punk::ns {
incr i
}
punk::args::definition $argspec
return [punk::args::usage {*}$opts "$origin new"]
return [punk::args::usage {*}$opts "(autodef)$origin new"]
}
create {
set constructorinfo [info class constructor $origin]
set arglist [lindex $constructorinfo 0]
set argspec [punk::lib::tstr -return string {
*id "${$origin} create"
*proc -name "${$origin} create" -help\
@id -id "(autodef)${$origin} create"
@cmd -name "${$origin} create" -help\
"create object with specified command name.
Arguments following objectName are passed to the constructor."
*values -min 1
@values -min 1
objectName -type string -help\
"possibly namespaced name for object instance command"
}]
@ -2083,20 +2239,20 @@ tcl::namespace::eval punk::ns {
incr i
}
punk::args::definition $argspec
return [punk::args::usage {*}$opts "$origin create"]
return [punk::args::usage {*}$opts "(autodef)$origin create"]
}
destroy {
#review - generally no doc
# but we may want notes about a specific destructor
set argspec [punk::lib::tstr -return string {
*id "${$origin} destroy"
*proc -name "destroy" -help\
@id -id "(audodef)${$origin} destroy"
@cmd -name "destroy" -help\
"delete object, calling destructor if any.
destroy accepts no arguments."
*values -min 0 -max 0
@values -min 0 -max 0
}]
punk::args::definition $argspec
return [punk::args::usage {*}$opts "$origin destroy"]
return [punk::args::usage {*}$opts "(autodef)$origin destroy"]
}
default {
#use info object call <obj> <method> to resolve callchain
@ -2111,20 +2267,24 @@ tcl::namespace::eval punk::ns {
lassign $impl generaltype mname location methodtype
switch -- $generaltype {
method - private {
#objects being dynamic systems - we should always reinspect.
#Don't use the cached (autodef) def
#If there is a custom def override - use it (should really be -dynamic - but we don't check)
if {$location eq "object"} {
set id "[string trimleft $origin :] $c1" ;# "<object> <method>"
set idcustom "$origin $c1"
#set id "[string trimleft $origin :] $c1" ;# "<object> <method>"
if {[info commands ::punk::args::id_exists] ne ""} {
if {[punk::args::id_exists $id]} {
return [uplevel 1 [list punk::args::usage {*}$opts $id]]
if {[punk::args::id_exists $idcustom]} {
return [uplevel 1 [list punk::args::usage {*}$opts $idcustom]]
}
}
set def [::info object definition $origin $c1]
} else {
set id "[string trimleft $location :] $c1" ;# "<class> <method>"
#set id "[string trimleft $location :] $c1" ;# "<class> <method>"
set idcustom "$location $c1"
if {[info commands ::punk::args::id_exists] ne ""} {
if {[punk::args::id_exists $id]} {
return [uplevel 1 [list punk::args::usage {*}$opts $id]]
if {[punk::args::id_exists $idcustom]} {
return [uplevel 1 [list punk::args::usage {*}$opts $idcustom]]
}
}
set def [::info class definition $location $c1]
@ -2138,12 +2298,15 @@ tcl::namespace::eval punk::ns {
}
}
if {$def ne ""} {
#assert - if we pre
set autoid "(autodef)$location $c1"
set arglist [lindex $def 0]
set argspec [punk::lib::tstr -return string {
*id "${$location} ${$c1}"
*proc -name "${$location} ${$c1}" -help\
"arglist:${$arglist}"
*values
@id -id "${$autoid}"
@cmd -name "${$location} ${$c1}" -help\
"(autogenerated)
arglist:${$arglist}"
@values
}]
set i 0
foreach a $arglist {
@ -2166,7 +2329,7 @@ tcl::namespace::eval punk::ns {
incr i
}
punk::args::definition $argspec
return [punk::args::usage {*}$opts "$location $c1"]
return [punk::args::usage {*}$opts $autoid]
} else {
return "unable to resolve $origin method $c1"
}
@ -2189,9 +2352,11 @@ tcl::namespace::eval punk::ns {
switch -- $generaltype {
method - private {
if {$location eq "object"} {
set id "[string trimleft $origin :] $cmd" ;# "<object> <method>"
#set id "[string trimleft $origin :] $cmd" ;# "<object> <method>"
set id "$origin $cmd"
} else {
set id "[string trimleft $location :] $cmd" ;# "<class> <method>"
#set id "[string trimleft $location :] $cmd" ;# "<class> <method>"
set id "$location $cmd"
}
if {[info commands ::punk::args::id_exists] ne ""} {
if {[punk::args::id_exists $id]} {
@ -2212,15 +2377,16 @@ tcl::namespace::eval punk::ns {
set vline [list method -choices $public_methods -choicelabels $choicelabeldict -choiceprefix 0] ;#methods must be specified in full always? - review
#puts stderr "--->$vline"
set idauto "(autodef)$origin"
set argspec [punk::lib::tstr -return string {
*id ${$origin}
*proc -name "Object: ${$origin}" -help\
"Instance of class: ${$class}"
*values -min 1
@id -id ${$idauto}
@cmd -name "Object: ${$origin}" -help\
"Instance of class: ${$class} (info autogenerated)"
@values -min 1
}]
append argspec \n $vline
punk::args::definition $argspec
return [punk::args::usage {*}$opts $origin]
return [punk::args::usage {*}$opts $idauto]
}
privateObject {
return "Command is a privateObject - no info currently available"
@ -2287,11 +2453,11 @@ tcl::namespace::eval punk::ns {
set subcommands [lsort [dict keys $subcommand_dict]]
if {[llength $commandargs]} {
set match [tcl::prefix::match $subcommands [lindex $commandargs 0]]
if {[llength $queryargs]} {
set match [tcl::prefix::match $subcommands [lindex $queryargs 0]]
if {$match in $subcommands} {
set subcmd [dict get $subcommand_dict $match]
return [arginfo {*}$subcmd {*}[lrange $commandargs 1 end]] ;#subcmd is sometimes multiple words (implemented as a further ensemble subcommand) (e.g huddle string -> "Type_string string")
return [arginfo {*}$subcmd {*}[lrange $queryargs 1 end]] ;#subcmd is sometimes multiple words (implemented as a further ensemble subcommand) (e.g huddle string -> "Type_string string")
}
}
@ -2307,9 +2473,9 @@ tcl::namespace::eval punk::ns {
set is_object [list]
foreach ns $namespaces {
set nsinfo [lindex [punk::ns::nslist_dict [nsjoin [nsprefix $ns] *]] 0]
lappend have_usageinfo {*}[dict get $nsinfo usageinfo]
lappend is_ensemble {*}[dict get $nsinfo ensembles]
lappend is_object {*}[dict get $nsinfo ooobjects]
lappend have_usageinfo {*}[dict get $nsinfo usageinfo]
lappend is_ensemble {*}[dict get $nsinfo ensembles]
lappend is_object {*}[dict get $nsinfo ooobjects]
}
set choicelabeldict [dict create]
@ -2324,14 +2490,17 @@ tcl::namespace::eval punk::ns {
}
set vline [list subcommand -choices $subcommands -choiceprefix $prefixes -choicelabels $choicelabeldict]
set autoid "(autodef)$origin"
set argspec [punk::lib::tstr -return string {
*id ${$origin}
*proc -help "ensemble: ${$origin}"
*values -min 1
@id -id ${$autoid}
@cmd -help\
"(autogenerated)
ensemble: ${$origin}"
@values -min 1
}]
append argspec \n $vline
punk::args::definition $argspec
return [punk::args::usage {*}$opts $origin]
return [punk::args::usage {*}$opts $autoid]
}
#check for tepam help
@ -2364,12 +2533,6 @@ tcl::namespace::eval punk::ns {
}
}
set id [string trimleft $origin :]
if {[info commands ::punk::args::id_exists] ne ""} {
if {[punk::args::id_exists $id]} {
return [uplevel 1 [list punk::args::usage {*}$opts $id]]
}
}
set origin_ns [nsprefix $origin]
set parts [nsparts $origin_ns]
set weird_ns 0
@ -2379,24 +2542,42 @@ tcl::namespace::eval punk::ns {
if {$weird_ns} {
set argl {}
set tail [nstail $origin]
foreach a [nseval_ifexists $origin_ns [list info args $tail]] {
if {[nseval_ifexists $origin_ns [list info default $tail $a def]]} {
lappend a $def
set cmdtype [nseval_ifexists $origin_ns [list punk::ns::cmdtype $tail]]
if {$cmdtype eq "proc"} {
foreach a [nseval_ifexists $origin_ns [list info args $tail]] {
if {[nseval_ifexists $origin_ns [list info default $tail $a def]]} {
lappend a $def
}
lappend argl $a
}
lappend argl $a
}
} else {
set argl {}
foreach a [info args $origin] {
if {[info default $origin $a def]} {
lappend a $def
set cmdtype [punk::ns::cmdtype $origin]
if {$cmdtype eq "proc"} {
set argl {}
set infoargs [info args $origin]
foreach a $infoargs {
if {[info default $origin $a def]} {
lappend a $def
}
lappend argl $a
}
lappend argl $a
}
}
set msg "No argument processor detected"
append msg \n "function signature: $resolved $argl"
if {[llength $queryargs]} {
#todo - something better
set msg "Undocumented or nonexistant subcommand $origin $queryargs"
append msg \n "$origin Type: $cmdtype"
} else {
if {$cmdtype eq "proc"} {
set msg "Undocumented proc $origin"
append msg \n "No argument processor detected"
append msg \n "function signature: $resolved $argl"
} else {
set msg "Undocumented command $origin. Type: $cmdtype"
}
}
return $msg
}
@ -2738,8 +2919,8 @@ tcl::namespace::eval punk::ns {
interp alias "" use "" punk::ns::pkguse
punk::args::definition {
*id punk::ns::nsimport_noclobber
*proc -name punk::ns::nsimport_noclobber -help\
@id -id ::punk::ns::nsimport_noclobber
@cmd -name punk::ns::nsimport_noclobber -help\
"Import exported commands from a namespace into either the current namespace,
or that specified in -targetnamespace.
Return list of imported commands, ignores failures due to name conflicts"
@ -2750,14 +2931,14 @@ tcl::namespace::eval punk::ns {
If not supplied, caller's namespace is used."
-prefix -optional 1 -help\
"string prefix for command names in target namespace"
*values -min 1 -max 1
@values -min 1 -max 1
sourcepattern -type string -optional 0 -help\
"Glob pattern for source namespace.
Globbing only active in the tail segment.
e.g ::mynamespace::*"
}
proc nsimport_noclobber {args} {
lassign [dict values [punk::args::get_by_id punk::ns::nsimport_noclobber $args]] leaders opts values received
lassign [dict values [punk::args::get_by_id ::punk::ns::nsimport_noclobber $args]] leaders opts values received
set sourcepattern [dict get $values sourcepattern]
set source_ns [tcl::namespace::qualifiers $sourcepattern]

6
src/bootsupport/modules/punk/path-0.1.0.tm

@ -645,14 +645,14 @@ namespace eval punk::path {
}
punk::args::definition {
*id punk::path::treefilenames
@id -id ::punk::path::treefilenames
-directory -type directory -help\
"folder in which to begin recursive scan for files."
-call-depth-internal -default 0 -type integer
-antiglob_paths -default {} -help\
"list of path patterns to exclude
may include * and ** path segments e.g /usr/**"
*values -min 0 -max -1 -optional 1 -type string
@values -min 0 -max -1 -optional 1 -type string
tailglobs -multiple 1 -help\
"Patterns to match against filename portion (last segment) of each file path
within the directory tree being searched."
@ -671,7 +671,7 @@ namespace eval punk::path {
#[para] list of path patterns to exclude - may include * and ** path segments e.g /usr/**
#[para]no natsorting - so order is dependent on filesystem
set argd [punk::args::get_by_id punk::path::treefilenames $args]
set argd [punk::args::get_by_id ::punk::path::treefilenames $args]
lassign [dict values $argd] leaders opts values received
set tailglobs [dict values $values]
# -- --- --- --- --- --- ---

84
src/bootsupport/modules/punk/repo-0.1.1.tm

@ -62,6 +62,73 @@ package require punk::mix::util ;#do_in_path
# -- --- --- --- --- --- --- --- --- --- ---
namespace eval punk::repo {
variable PUNKARGS
variable PUNKARGS_aliases
proc get_fossil_usage {} {
set allcmds [runout -n fossil help -a]
set mainhelp [runout -n fossil help]
set maincommands [list]
foreach ln [split $mainhelp \n] {
set ln [string trim $ln]
if {$ln eq "" || [regexp {^[A-Z]+} $ln]} {
continue
}
lappend maincommands {*}$ln
}
set othercmds [punk::lib::ldiff $allcmds $maincommands]
set result "@leaders -min 0\n"
append result [tstr -return string {
subcommand -type string -choicecolumns 8 -choicegroups {
"frequently used commands" {${$maincommands}}
"" {${$othercmds}}
}
}]
return $result
}
#lappend PUNKARGS [list -dynamic 1 {
# @id -id ::punk::repo::fossil_proxy
# @cmd -name fossil -help "fossil executable
# "
# @argdisplay -header "fossil help" -body {${[runout -n fossil help]}}
# } ""]
lappend PUNKARGS [list -dynamic 1 {
@id -id ::punk::repo::fossil_proxy
@cmd -name fossil -help "fossil executable"
${[punk::repo::get_fossil_usage]}
} ]
#experiment
lappend PUNKARGS [list -dynamic 1 {
@id -id "::punk::repo::fossil_proxy diff"
@cmd -name "fossil diff" -help "fossil diff
"
@argdisplay -header "fossil help diff" -body {${[runout -n fossil help diff]}}
} ""]
lappend PUNKARGS [list -dynamic 1 {
@id -id "::punk::repo::fossil_proxy add"
@cmd -name "fossil add" -help "fossil add
"
@argdisplay -header "fossil help add" -body {${[runout -n fossil help add]}}
} ""]
#TODO
#lappend PUNKARGS [list -dynamic 1 {
# @id -glob 1 -id "::punk::repo::fossil_proxy *" -aliases {fs}
# @cmd -name "fossil add" -help "fossil add
# "
# @argdisplay -header "fossil help add" -body {${[runout -n fossil help add]}}
# } ""]
lappend PUNKARGS_aliases {"::fossil" "::punk::repo::fossil_proxy"}
lappend PUNKARGS_aliases {"::fossil diff" "::punk::repo::fossil_proxy diff"}
#Todo - investigate proper way to install a client-side commit hook in the fossil project
#Then we may still use this proxy to check the hook - but the required checks will occur when another shell used
@ -137,7 +204,7 @@ namespace eval punk::repo {
puts stderr "fossil command not found. Please install fossil"
}
}
interp alias "" fossil "" punk::repo::fossil_proxy
# ---
# Calling auto_execok on an external tool can be too slow to do during package load (e.g could be 150ms)
@ -153,6 +220,7 @@ namespace eval punk::repo {
# ----------
#
#uppercase FOSSIL to bypass fossil as alias to fossil_proxy
proc establish_FOSSIL {args} {
if {![info exists ::auto_execs(FOSSIL)]} {
@ -161,7 +229,6 @@ namespace eval punk::repo {
interp alias "" FOSSIL "" ;#delete establishment alias
FOSSIL {*}$args
}
interp alias "" FOSSIL "" punk::repo::establish_FOSSIL
# ----------
proc askuser {question} {
@ -1577,6 +1644,8 @@ namespace eval punk::repo {
}
}
interp alias "" fossil "" punk::repo::fossil_proxy
interp alias "" FOSSIL "" punk::repo::establish_FOSSIL
interp alias {} is_fossil {} ::punk::repo::is_fossil
interp alias {} is_fossil_root {} ::punk::repo::is_fossil_root
@ -1609,6 +1678,17 @@ namespace eval punk::repo::lib {
}
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
if {![info exists ::punk::args::register::NAMESPACES]} {
namespace eval ::punk::args::register {
set ::punk::args::register::NAMESPACES [list] ;#use fully qualified so 8.6 doesn't find existing var in global namespace
}
}
lappend ::punk::args::register::NAMESPACES ::punk::repo
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
## Ready
package provide punk::repo [namespace eval punk::repo {

19
src/bootsupport/modules/punk/zip-0.1.1.tm

@ -180,10 +180,11 @@ tcl::namespace::eval punk::zip {
#}]
set argd [punk::args::get_dict {
*proc -name punk::zip::walk
@id -id ::punk::zip::walk
@cmd -name punk::zip::walk
-excludes -default "" -help "list of glob expressions to match against files and exclude"
-subpath -default ""
*values -min 1 -max -1
@values -min 1 -max -1
base
fileglobs -default {*} -multiple 1
} $args]
@ -373,11 +374,12 @@ tcl::namespace::eval punk::zip {
#[para] The return value is the central directory record that will need to be used when finalizing the zip archive.
set argd [punk::args::get_dict {
*proc -name punk::zip::Addentry -help "Add a single file at 'path' to open channel 'zipchan'
@id -id ::punk::zip::Addentry
@cmd -name punk::zip::Addentry -help "Add a single file at 'path' to open channel 'zipchan'
return a central directory file record"
*opts
@opts
-comment -default "" -help "An optional comment specific to the added file"
*values -min 3 -max 4
@values -min 3 -max 4
zipchan -help "open file descriptor with cursor at position appropriate for writing a local file header"
base -help "base path for entries"
path -type file -help "path of file to add"
@ -525,9 +527,10 @@ tcl::namespace::eval punk::zip {
#[para] Call 'punk::zip::mkzip' with no arguments for usage display.
set argd [punk::args::get_dict {
*proc -name punk::zip::mkzip\
@id -id ::punk::zip::mkzip
@cmd -name punk::zip::mkzip\
-help "Create a zip archive in 'filename'"
*opts
@opts
-offsettype -default "archive" -choices {archive file}\
-help "zip offsets stored relative to start of entire file or relative to start of zip-archive
Only relevant if the created file has a script/runtime prefix.
@ -557,7 +560,7 @@ tcl::namespace::eval punk::zip {
it must be a parent of -directory or the same path as -directory"
-exclude -default {CVS/* */CVS/* *~ ".#*" "*/.#*"}
*values -min 1 -max -1
@values -min 1 -max -1
filename -type file -default ""\
-help "name of zipfile to create"
globs -default {*} -multiple 1\

139
src/bootsupport/modules/textblock-0.1.2.tm

@ -123,12 +123,12 @@ tcl::namespace::eval textblock {
set choicemsg " (unavailable packages: $unavailable)"
}
set argd [punk::args::get_dict [tstr -return string {
*id textblock::use_hash
*proc -name "textblock::use_hash" -help\
@id -id ::textblock::use_hash
@cmd -name "textblock::use_hash" -help\
"Hashing algorithm to use for framecache lookup.
'none' may be slightly faster but less compact
when viewing textblock::framecache"
*values -min 0 -max 1
@values -min 0 -max 1
hash_algorithm -choices {${$choices}} -optional 1 -help\
"algorithm choice ${$choicemsg}"
}] $args]
@ -423,7 +423,6 @@ tcl::namespace::eval textblock {
}
}
}
my configure {*}$o_opts_table
#foreach {k v} $args {
# #todo - convert to literal switch using tcl::string::map so we don't have to define o_opts_table_defaults here.
@ -453,6 +452,7 @@ tcl::namespace::eval textblock {
-minheight 1\
-maxheight ""\
]
my configure {*}$o_opts_table
}
method width_algorithm {{alg ""}} {
@ -593,7 +593,7 @@ tcl::namespace::eval textblock {
tcl::dict::set o_opts_table_effective -framelimits_header $hlims
return [tcl::dict::create body $blims header $hlims]
}
method configure args {
method configure {args} {
#*** !doctools
#[call class::table [method configure] [arg args]]
#[para] get or set various table-level properties
@ -781,6 +781,14 @@ tcl::namespace::eval textblock {
}
}
}
-title {
set twidth [punk::ansi::printing_length $v]
if {[my width] < [expr {$twidth+2}]} {
set o_calculated_column_widths [list]
tcl::dict::set o_opts_table -minwidth [expr {$twidth+2}]
}
tcl::dict::set o_opts_table -title $v
}
default {
tcl::dict::set o_opts_table $k $v
}
@ -3943,14 +3951,13 @@ tcl::namespace::eval textblock {
if {$header_build eq "" && ![llength $body_blocks]} {
set header_build $nextcol_header
lappend body_blocks $nextcol_body
} else {
if {$headerheight > 0} {
set header_build [overtype::renderspace -startcolumn [expr {$padwidth + 1}] -expand_right 1 -transparent $TSUB $header_build[unset header_build] $nextcol_header[unset nextcol_header]]
}
lappend body_blocks $nextcol_body
#set body_build [textblock::join -- $body_build[unset body_build] $nextcol_body]
}
lappend body_blocks $nextcol_body
incr padwidth $bodywidth
incr colposn
}
@ -4096,8 +4103,8 @@ tcl::namespace::eval textblock {
}
punk::args::definition {
*id textblock::periodic
*proc -name textblock::periodic -help "A rudimentary periodic table
@id -id ::textblock::periodic
@cmd -name textblock::periodic -help "A rudimentary periodic table
This is primarily a test of textblock::class::table"
-return -default table\
@ -4109,13 +4116,13 @@ tcl::namespace::eval textblock {
-show_header -default "" -type boolean
-show_edge -default "" -type boolean
-forcecolour -default 0 -type boolean -help "If punk::colour is off - this enables the produced table to still be ansi coloured"
*values -min 0 -max 0
@values -min 0 -max 0
}
proc periodic {args} {
#For an impressive interactive terminal app (javascript)
# see: https://github.com/spirometaxas/periodic-table-cli
set opts [dict get [punk::args::get_by_id textblock::periodic $args] opts]
set opts [dict get [punk::args::get_by_id ::textblock::periodic $args] opts]
set opt_return [tcl::dict::get $opts -return]
if {[tcl::dict::get $opts -forcecolour]} {
set fc forcecolour
@ -4345,7 +4352,10 @@ tcl::namespace::eval textblock {
set FRAMETYPES [textblock::frametypes]
punk::args::definition [punk::lib::tstr -return string {
*id textblock::list_as_table
@id -id ::textblock::list_as_table
@cmd -name "textblock::list_as_table" -help\
"Display a list in a bordered table
"
-return -default table -choices {table tableobject}
-frametype -default "light" -type dict -choices {${$FRAMETYPES}} -choicerestricted 0\
@ -4376,13 +4386,13 @@ tcl::namespace::eval textblock {
-help "Number of table columns
Will default to 2 if not using an existing -table object"
*values -min 0 -max 1
@values -min 0 -max 1
datalist -default {} -type list -help "flat list of table cell values which will be wrapped based on -columns value"
}]
proc list_as_table {args} {
set FRAMETYPES [textblock::frametypes]
set argd [punk::args::get_by_id textblock::list_as_table $args]
set argd [punk::args::get_by_id ::textblock::list_as_table $args]
set opts [dict get $argd opts]
set datalist [dict get $argd values datalist]
@ -4894,7 +4904,7 @@ tcl::namespace::eval textblock {
#review!?
#-within_ansi means after a leading ansi code when doing left pad on all but last line
#-within_ansi means before a trailing ansi code when doing right pad on all but last line
set usage "pad ?-padchar <sp>|<character>? ?-which right|left|centre? ?-known_hasansi \"\"|<bool>? ?-known_blockwidth \"\"|<int>? ?-width auto|<int>? ?-within_ansi 1|0?"
set usage "pad block ?-padchar <sp>|<character>? ?-which right|left|centre? ?-known_hasansi \"\"|<bool>? ?-known_blockwidth \"\"|<int>? ?-width auto|<int>? ?-within_ansi 1|0?"
foreach {k v} $args {
switch -- $k {
-padchar - -which - -known_hasansi - -known_samewidth - -known_blockwidth - -width - -overflow - -within_ansi {
@ -5420,16 +5430,21 @@ tcl::namespace::eval textblock {
return [punk::lib::list_as_lines -- $outlines]
}
punk::args::definition {
@id -id ::textblock::join_basic
@cmd -name textblock::join_basic -help\
"Join blocks of text line by line but don't add padding on each line to enforce uniform width.
Already uniform blocks will join faster than textblock::join, and ragged blocks will join in a ragged manner
"
-- -type none -optional 0 -help "end of options marker -- is mandatory because joined blocks may easily conflict with flags"
-ansiresets -type any -default auto
blocks -type any -multiple 1
}
#join without regard to each line length in a block (no padding added to make each block uniform)
proc ::textblock::join_basic {args} {
#*proc -name textblock::join_basic -help "Join blocks line by line but don't add padding on each line to enforce uniform width.
# Already uniform blocks will join faster than textblock::join, and ragged blocks will join in a ragged manner
#"
set argd [punk::args::get_dict {
-- -type none -optional 0 -help "end of options marker -- is mandatory because joined blocks may easily conflict with flags"
-ansiresets -type any -default auto
blocks -type any -multiple 1
} $args]
set argd [punk::args::get_by_id ::textblock::join_basic $args]
set ansiresets [tcl::dict::get $argd opts -ansiresets]
set blocks [tcl::dict::get $argd values blocks]
@ -5466,7 +5481,7 @@ tcl::namespace::eval textblock {
return [::join $outlines \n]
}
proc ::textblock::join_basic2 {args} {
#*proc -name textblock::join_basic -help "Join blocks line by line but don't add padding on each line to enforce uniform width.
#@cmd -name textblock::join_basic -help "Join blocks line by line but don't add padding on each line to enforce uniform width.
# Already uniform blocks will join faster than textblock::join, and ragged blocks will join in a ragged manner
#"
set argd [punk::args::get_dict {
@ -6046,8 +6061,8 @@ tcl::namespace::eval textblock {
if {$bad_option || [llength $values] == 0} {
#no framedef supplied, or unrecognised opt seen
set spec [string map [list <ftlist> $::textblock::frametypes] {
*id textblock::framedef
*proc -name textblock::framedef\
@id -id ::textblock::framedef
@cmd -name textblock::framedef\
-help "Return a dict of the elements that make up a frame border.
May return a subset of available elements based on memberglob values."
@ -6058,7 +6073,7 @@ tcl::namespace::eval textblock {
-help "-boxonly true restricts results to the corner,vertical and horizontal box elements
It excludes the extra top and side join elements htlj,hlbj,vllj,vlrj."
*values -min 1
@values -min 1
frametype -choices "<ftlist>" -choiceprefix 0 -choicerestricted 0 -type dict\
-help "name from the predefined frametypes or an adhoc dictionary."
memberglob -type globstring -optional 1 -multiple 1 -choiceprefix 0 -choicerestricted 0 -choices {
@ -7438,17 +7453,17 @@ tcl::namespace::eval textblock {
set frame_cache [tcl::dict::create]
punk::args::definition {
*id textblock::frame_cache
*proc -name textblock::frame_cache -help\
@id -id ::textblock::frame_cache
@cmd -name textblock::frame_cache -help\
"Display or clear the frame cache."
-action -default {} -choices {clear} -help\
"Clear the textblock::frame_cache dictionary"
-pretty -default 1 -help\
"Use 'pdict textblock::frame_cache */*' for prettier output"
*values -min 0 -max 0
@values -min 0 -max 0
}
proc frame_cache {args} {
set argd [punk::args::get_by_id textblock::frame_cache $args]
set argd [punk::args::get_by_id ::textblock::frame_cache $args]
set action [dict get $argd opts -action]
if {$action ni [list clear ""]} {
@ -7490,13 +7505,40 @@ tcl::namespace::eval textblock {
}
variable FRAMETYPES
set FRAMETYPES [textblock::frametypes]
variable EG
set EG [a+ brightblack]
variable RST
set RST [a]
proc frame_samples {} {
set FRAMETYPELABELS [dict create]
if {[info commands ::textblock::frame] ne ""} {
foreach ft [frametypes] {
dict set FRAMETYPELABELS $ft [textblock::frame -checkargs 0 -type $ft " "]
}
}
set FRAMETYPELABELS [dict remove $FRAMETYPELABELS block2hack]
return $FRAMETYPELABELS
}
#proc EG {} "return {[a+ brightblack]}"
#make EG fetch from SGR cache so as to abide by colour off/on
proc EG {} {
a+ brightblack
}
#proc RST {} "return {\x1b\[m}"
proc RST {} {
return "\x1b\[m"
}
#catch 22 for -choicelabels - need some sort of lazy evaluation
# ${[textblock::frame_samples]}
#todo punk::args alias for centre center etc?
punk::args::definition [punk::lib::tstr -return string {
*id textblock::frame
*proc -name "textblock::frame"\
punk::args::definition -dynamic 1 {
@id -id ::textblock::frame
@cmd -name "textblock::frame"\
-help "Frame a block of text with a border."
-checkargs -default 1 -type boolean\
-help "If true do extra argument checks and
@ -7504,18 +7546,21 @@ tcl::namespace::eval textblock {
Set false for slight performance improvement."
-etabs -default 0\
-help "expanding tabs - experimental/unimplemented."
-type -default light -choices {${$FRAMETYPES}} -choicerestricted 0 -type dict\
-type -default light -choices {${[textblock::frametypes]}} -choicerestricted 0 -choicecolumns 8 -type dict\
-choicelabels {
${[textblock::frame_samples]}
}\
-help "Type of border for frame."
-boxlimits -default {hl vl tlc blc trc brc} -type list -help "Limit the border box to listed elements.
passing an empty string will result in no box, but title/subtitle will still appear if supplied.
${$EG}e.g: -frame -boxlimits {} -title things [a+ red White]my\\ncontent${$RST}"
${[textblock::EG]}e.g: -frame -boxlimits {} -title things [a+ red White]my\\ncontent${[textblock::RST]}"
-boxmap -default {} -type dict
-joins -default {} -type list
-title -default "" -type string -regexprefail {\n}\
-help "Frame title placed on topbar - no newlines.
May contain ANSI - no trailing reset required.
${$EG}e.g 1: frame -title My[a+ green]Green[a]Thing
e.g 2: frame -title [a+ red underline]MyThing${$RST}"
${[textblock::EG]}e.g 1: frame -title My[a+ green]Green[a]Thing
e.g 2: frame -title [a+ red underline]MyThing${[textblock::RST]}"
-subtitle -default "" -type string -regexprefail {\n}\
-help "Frame subtitle placed on bottombar - no newlines
May contain Ansi - no trailing reset required."
@ -7526,8 +7571,8 @@ tcl::namespace::eval textblock {
-help "Height of resulting frame including borders."
-ansiborder -default "" -type ansistring\
-help "Ansi escape sequence to set border attributes.
${$EG}e.g 1: frame -ansiborder [a+ web-red] contents
e.g 2: frame -ansiborder \"\\x1b\\\[31m\" contents${$RST}"
${[textblock::EG]}e.g 1: frame -ansiborder [a+ web-red] contents
e.g 2: frame -ansiborder \"\\x1b\\\[31m\" contents${[textblock::RST]}"
-ansibase -default "" -type ansistring\
-help "Default ANSI attributes within frame."
-blockalign -default centre -choices {left right centre}\
@ -7547,13 +7592,13 @@ tcl::namespace::eval textblock {
Frame width doesn't adapt and content may be truncated
so -width may need to be manually set to display more."
*values -min 0 -max 1
@values -min 0 -max 1
contents -default "" -type string\
-help "Frame contents - may be a block of text containing newlines and ANSI.
Text may be 'ragged' - ie unequal line-lengths.
No trailing ANSI reset required.
${$EG}e.g: frame \"[a+ blue White] \\nMy blue foreground text on\\nwhite background\\n\"${$RST}"
}]
${[textblock::EG]}e.g: frame \"[a+ blue White] \\nMy blue foreground text on\\nwhite background\\n\"${[textblock::RST]}"
}
#options before content argument - which is allowed to be absent
#frame performance (noticeable with complex tables even of modest size) is improved somewhat by frame_cache - but is still (2024) a fairly expensive operation.
@ -7638,7 +7683,7 @@ tcl::namespace::eval textblock {
#only use punk::args if check_args is true or our basic checks failed
#never need to checkargs if only one argument supplied even if it looks like an option - as it will be treated as data to frame
if {[llength $args] != 1 && (!$opts_ok || $check_args)} {
set argd [punk::args::get_by_id textblock::frame $args]
set argd [punk::args::get_by_id ::textblock::frame $args]
set opts [dict get $argd opts]
set contents [dict get $argd values contents]
}
@ -8346,18 +8391,18 @@ tcl::namespace::eval textblock {
}
}
punk::args::definition {
*id textblock::gcross
@id -id ::textblock::gcross
-max_cross_size -default 0 -type integer -help "Largest size cross to use to make up the block
Only cross sizes that divide the size of the overall block will be used.
e.g if the 'size' chosen is 19 (a prime number) - only 1 or the full size of 19 can be used as the crosses to make up the block.
Whereas for a block size of 24, -max_cross_size of 1,2,3,4,6,8,12 or 24 will work. (all divisors)
If a number chosen for -max_cross_size isn't a divisor, the largest divisor below the chosen value will be used.
"
*values -min 0 -max 1
@values -min 0 -max 1
size -default 1 -type integer
}
proc gcross {args} {
set argd [punk::args::get_by_id textblock::gcross $args]
set argd [punk::args::get_by_id ::textblock::gcross $args]
set size [dict get $argd values size]
set opts [dict get $argd opts]

46
src/modules/argparsingtest-999999.0a1.0.tm

@ -277,8 +277,9 @@ namespace eval argparsingtest {
#punk::args is slower than argp - but comparable, and argp doesn't support solo flags
proc test1_punkargs {args} {
set argd [punk::args::get_dict {
*proc -name argtest4 -help "test of punk::args::get_dict comparative performance"
*opts -anyopts 0
@id -id ::argparsingtest::test1_punkargs
@cmd -name argtest4 -help "test of punk::args::get_dict comparative performance"
@opts -anyopts 0
-return -default string -type string
-frametype -default \uFFEF -type string
-show_edge -default \uFFEF -type string
@ -290,15 +291,15 @@ namespace eval argparsingtest {
-1 -default 1 -type boolean
-2 -default 2 -type integer
-3 -default 3 -type integer
*values
@values
} $args]
return [tcl::dict::get $argd opts]
}
punk::args::definition {
*id argparsingtest::test1_punkargs2
*proc -name argtest4 -help "test of punk::args::get_dict comparative performance"
*opts -anyopts 0
@id -id ::test1_punkargs_by_id
@cmd -name argtest4 -help "test of punk::args::get_dict comparative performance"
@opts -anyopts 0
-return -default string -type string
-frametype -default \uFFEF -type string
-show_edge -default \uFFEF -type string
@ -310,18 +311,41 @@ namespace eval argparsingtest {
-1 -default 1 -type boolean
-2 -default 2 -type integer
-3 -default 3 -type integer
*values
@values
}
proc test1_punkargs_by_id {args} {
set argd [punk::args::get_by_id ::test1_punkargs_by_id $args]
return [tcl::dict::get $argd opts]
}
punk::args::definition {
@id -id ::argparsingtest::test1_punkargs2
@cmd -name argtest4 -help "test of punk::args::get_dict comparative performance"
@opts -anyopts 0
-return -default string -type string
-frametype -default \uFFEF -type string
-show_edge -default \uFFEF -type string
-show_seps -default \uFFEF -type string
-join -type none -multiple 1
-x -default "" -type string
-y -default b -type string
-z -default c -type string
-1 -default 1 -type boolean
-2 -default 2 -type integer
-3 -default 3 -type integer
@values
}
proc test1_punkargs2 {args} {
set argd [punk::args::get_by_id argparsingtest::test1_punkargs2 $args]
set argd [punk::args::get_by_id ::argparsingtest::test1_punkargs2 $args]
return [tcl::dict::get $argd opts]
}
proc test1_punkargs_validate_ansistripped {args} {
set argd [punk::args::get_dict {
*proc -name argtest4 -help "test of punk::args::get_dict comparative performance"
*opts -anyopts 0
@id -id ::argparsingtest::test1_punkargs_validate_ansistripped
@cmd -name argtest4 -help "test of punk::args::get_dict comparative performance"
@opts -anyopts 0
-return -default string -type string -choices {string object} -help "return type"
-frametype -default \uFFEF -type string
-show_edge -default \uFFEF -type string
@ -333,7 +357,7 @@ namespace eval argparsingtest {
-1 -default 1 -type boolean -validate_ansistripped true
-2 -default 2 -type integer -validate_ansistripped true
-3 -default 3 -type integer -validate_ansistripped true
*values
@values
} $args]
return [tcl::dict::get $argd opts]
}

15
src/modules/patternpunk-1.1.tm

@ -112,10 +112,10 @@ proc TCL {args} {
}
punk::args::definition {
*id ">punk . poses"
*proc -name ">punk . poses" -help "Show or list the poses for the Punk mascot"
-censored -default 1 -type boolean -help "Set true to include mild toilet humour poses"
-return -default table -choices {list table}
@id -id ">punk . poses"
@cmd -name ">punk . poses" -help "Show or list the poses for the Punk mascot"
-censored -default 1 -type boolean -help "Set true to include mild toilet humour poses"
-return -default table -choices {list table}
}
>punk .. Method poses {args} {
set argd [punk::args::get_by_id ">punk . poses" $args]
@ -344,7 +344,8 @@ v_ /|\/ /
package require punk::args
set standard_frame_types [textblock::frametypes]
set argd [punk::args::get_dict [tstr -return string {
*proc -name "deck" -help "Punk Deck mascot"
@id -id ">punk . deck"
@cmd -name "deck" -help "Punk Deck mascot"
-frame -default arc -choices "${$standard_frame_types}" -choicerestricted 0 -choiceprefix 1
-boxmap -default {} -type dict
-boxlimits -default {hl vl tlc blc trc brc} -help "Limit the border box to listed elements."
@ -353,7 +354,7 @@ v_ /|\/ /
}
-title -default "PATTERN" -type string
-subtitle -default "PUNK" -type string
*values -max 0
@values -max 0
}] $args]
set frame_type [dict get $argd opts -frame]
set box_map [dict get $argd opts -boxmap]
@ -367,7 +368,7 @@ v_ /|\/ /
#TODO - reuse textblock::gcross arguments - but reorder for error display
>punk .. Method gcross {{size 1} args} {
package require textblock
set argd [punk::args::get_by_id textblock::gcross [list {*}$args $size]]
set argd [punk::args::get_by_id ::textblock::gcross [list {*}$args $size]]
textblock::gcross {*}$args $size
}

20
src/modules/poshinfo-999999.0a1.0.tm

@ -199,19 +199,19 @@ tcl::namespace::eval poshinfo {
}
punk::args::definition {
*id poshinfo::themes
*proc -name poshinfo::themes
@id -id ::poshinfo::themes
@cmd -name poshinfo::themes
-format -default all -multiple 1 -choices {all yaml json}\
-help "File format of posh theme - based on file extension"
-type -default all -multiple 1\
-help "e.g omp"
-as -default "table" -choices {list showlist dict showdict table tableobject plaintext}\
-help "return type of result"
*values -min 0
globs -multiple 1 -default * -help ""
-help "File format of posh theme - based on file extension"
-type -default all -multiple 1\
-help "e.g omp"
-as -default "table" -choices {list showlist dict showdict table tableobject plaintext}\
-help "return type of result"
@values -min 0
globs -multiple 1 -default * -help ""
}
proc themes {args} {
set argd [punk::args::get_by_id poshinfo::themes $args]
set argd [punk::args::get_by_id ::poshinfo::themes $args]
set return_as [dict get $argd opts -as]
set formats [dict get $argd opts -format] ;#multiple
if {"yaml" in $formats} {

13
src/modules/punk-0.1.tm

@ -306,10 +306,11 @@ namespace eval punk {
#get last command result that was run through the repl
proc ::punk::get_runchunk {args} {
set argd [punk::args::get_dict {
*opts
@id -id ::punk::get_runchunk
@opts
-1 -optional 1 -type none
-2 -optional 1 -type none
*values -min 0 -max 0
@values -min 0 -max 0
} $args]
#todo - make this command run without truncating previous runchunks
set runchunks [tsv::array names repl runchunks-*]
@ -7152,8 +7153,8 @@ namespace eval punk {
}
punk::args::definition {
*id punk::inspect
*proc -name punk::inspect -help\
@id -id ::punk::inspect
@cmd -name punk::inspect -help\
"Function to display values - used pimarily in a punk pipeline.
The raw value arguments (not options) are always returned to pass
forward in the pipeline.
@ -7229,7 +7230,7 @@ namespace eval punk {
"End of options marker.
It is advisable to use this, as data in a pipeline may often begin with -"
*values -min 0 -max -1
@values -min 0 -max -1
arg -type string -optional 1 -multiple 1 -help\
"value to display"
}
@ -7261,7 +7262,7 @@ namespace eval punk {
foreach {k v} $flags {
if {$k ni [dict keys $defaults]} {
#error "inspect: unknown option $k. Known options: [dict keys $defaults]. If data contains flaglike elements, consider calling with end-of-opts marker. e.g inspect --"
punk::args::get_by_id punk::inspect $args
punk::args::get_by_id ::punk::inspect $args
}
}
set opts [dict merge $defaults $flags]

145
src/modules/punk/ansi-999999.0a1.0.tm

@ -134,27 +134,27 @@ tcl::namespace::eval punk::ansi::class {
}
lappend ::punk::ansi::class::PUNKARGS [list {
*id "punk::ansi::class::class_ansi render_to_input_line"
*proc -name "punk::ansi::class::class_ansi render_to_input_line" -help\
@id -id "::punk::ansi::class::class_ansi render_to_input_line"
@cmd -name "punk::ansi::class::class_ansi render_to_input_line" -help\
"render string from line 0 to line
(experimental/debug)"
-dimensions -type string -help\
"WxH where W is integer width >= 1 and H is integer heigth >= 1"
-minus -type integer -help\
"number of chars to exclude from end"
*values -min 1 -max 1
@values -min 1 -max 1
line -type indexexpression
}]
method render_to_input_line {args} {
if {[llength $args] < 1} {
puts stderr "render_to_input_line usage: ?-dimensions WxH? ?-minus charcount? x"
punk::args::get_by_id "punk::ansi::class::class_ansi render_to_input_line" $args
punk::args::get_by_id "::punk::ansi::class::class_ansi render_to_input_line" $args
}
set x [lindex $args end]
set arglist [lrange $args 0 end-1]
if {[llength $arglist] %2 != 0} {
puts stderr "render_to_input_line usage: ?-dimensions WxH? ?-minus charcount? x"
punk::args::get_by_id "punk::ansi::class::class_ansi render_to_input_line" $args
punk::args::get_by_id "::punk::ansi::class::class_ansi render_to_input_line" $args
}
set opts [tcl::dict::create\
-dimensions 80x24\
@ -167,7 +167,7 @@ tcl::namespace::eval punk::ansi::class {
}
default {
puts stderr "render_to_input_line unexpected argument '$k' usage: ?-dimensions WxH? ?-minus charcount? x"
punk::args::get_by_id "punk::ansi::class::class_ansi render_to_input_line" $args
punk::args::get_by_id "::punk::ansi::class::class_ansi render_to_input_line" $args
}
}
}
@ -588,20 +588,20 @@ tcl::namespace::eval punk::ansi {
}
lappend PUNKARGS [list -dynamic 1 {
*id punk::ansi::example
*proc -name punk::ansi::example -help "Display .ans image files in a grid that will fit in console
@id -id ::punk::ansi::example
@cmd -name punk::ansi::example -help "Display .ans image files in a grid that will fit in console
"
-colwidth -default 82 -help "Width of each column - default of 82 will fit a standard 80wide ansi image (when framed)
You can specify a narrower width to truncate images on the right side"
-folder -default "${[punk::ansi::Get_ansifolder]}" -help "Base folder for files if relative paths are used.
Defaults to <projectbase>/src/testansi - where projectbase is determined from current directory.
"
*values -min 0 -max -1
@values -min 0 -max -1
files -default {belinda.ans bot.ans flower.ans fish.ans} -multiple true -help "List of filenames - leave empty to display 4 defaults"
} ""]
proc example {args} {
set argd [punk::args::get_by_id punk::ansi::example $args]
set argd [punk::args::get_by_id ::punk::ansi::example $args]
set colwidth [dict get $argd opts -colwidth]
set ansifolder [file normalize [dict get $argd opts -folder]]
set fnames [dict get $argd values files]
@ -2355,21 +2355,21 @@ Brightblack 100 Brightred 101 Brightgreen 102 Brightyellow 103 Brightblu
#sgr_cache clear called by punk::console::ansi when set to off
#punk::args depends on punk::ansi - REVIEW
lappend PUNKARGS [list {
@id -id ::punk::ansi::sgr_cache
@cmd -name punk::ansi::sgr_cache -help\
"Convenience function to view and optionally clear the ansi character attribute cache (ansi SGR codes)
"
-action -default "" -choices "clear" -help\
"-action clear will unset the keys in the punk::ansi::sgr_cache dict
This is called automatically when setting 'colour false' in the console"
-pretty -default 1 -type boolean -help\
"use 'pdict punk::ansi::sgr_cache */%str,%ansiview' output"
@values -min 0 -max 0
}]
proc sgr_cache {args} {
set argdef {
*id punk::ansi::sgr_cache
*proc -name punk::ansi::sgr_cache -help\
"Convenience function to view and optionally clear the ansi character attribute cache (ansi SGR codes)
"
-action -default "" -choices "clear" -help\
"-action clear will unset the keys in the punk::ansi::sgr_cache dict
This is called automatically when setting 'colour false' in the console"
-pretty -default 1 -type boolean -help\
"use 'pdict punk::ansi::sgr_cache */%str,%ansiview' output"
*values -min 0 -max 0
}
set argd [punk::args::get_dict $argdef $args]
set argd [punk::args::get_by_id ::punk::ansi::sgr_cache $args]
set action [dict get $argd opts -action]
set pretty [dict get $argd opts -pretty]
@ -2412,34 +2412,7 @@ Brightblack 100 Brightred 101 Brightgreen 102 Brightyellow 103 Brightblu
return [join $lines \n]
}
lappend PUNKARGS [list {
*id punk::ansi::a+
*proc -name "punk::ansi::a+" -help\
"Returns an ANSI sgr escape sequence based on the list of supplied codes.
Unlike punk::ansi::a - it is not prefixed with an ANSI reset.
"
*values -min 0 -max -1
} [string map [list <choices> [dict keys $SGR_map]] {
code -type string -optional 1 -multiple 1 -choices {<choices>} -choiceprefix 0 -choicerestricted 0 -help\
"SGR code from the list below, or an integer corresponding to the code e.g 31 = red.
A leading capital letter indicates a codename applies to the background colour.
Other accepted codes are:
term-<int> Term-<int> foreground/background where int is 0-255 terminal color
term-<termcolour> Term-<termcolour> foreground/background
rgb-<r>-<g>-<b> Rgb-<r>-<g>-<b> foreground/background where <r> <g> <b> are the
0-255 int values for red, green and blue.
rgb#<hexcode> Rgb#<hexcode> where <hexcode> is a 6 char hex colour e.g rgb#C71585
web-<webcolour> Web-<webcolour>
The acceptable values for <termcolour> and <webcolour> can be queried using
punk::ansi::a? term
and
punk::ansi::a? web
Example to set foreground red and background cyan followed by a reset:
set str \"[a+ red Cyan]sample text[a]\"
"
}]]
#PUNKARGS doc performed below, after we create the proc
proc a+ {args} {
#*** !doctools
#[call [fun a+] [opt {ansicode...}]]
@ -2907,6 +2880,41 @@ Brightblack 100 Brightred 101 Brightgreen 102 Brightyellow 103 Brightblu
return $result
}
set SGR_samples [dict create]
foreach k [dict keys $SGR_map] {
dict set SGR_samples $k "[punk::ansi::a+ $k]sample\x1b\[m"
}
lappend PUNKARGS [list {
@id -id ::punk::ansi::a+
@cmd -name "punk::ansi::a+" -help\
"Returns an ANSI sgr escape sequence based on the list of supplied codes.
Unlike punk::ansi::a - it is not prefixed with an ANSI reset.
"
@values -min 0 -max -1
} [string map [list <choices> [dict keys $SGR_map] <choicelabels> $SGR_samples] {
code -type string -optional 1 -multiple 1 -choices {<choices>}\
-choicelabels {<choicelabels>}\
-choicecolumns 5 -choiceprefix 0 -choicerestricted 0 -help\
"SGR code from the list below, or an integer corresponding to the code e.g 31 = red.
A leading capital letter indicates a codename applies to the background colour.
Other accepted codes are:
term-<int> Term-<int> foreground/background where int is 0-255 terminal color
term-<termcolour> Term-<termcolour> foreground/background
rgb-<r>-<g>-<b> Rgb-<r>-<g>-<b> foreground/background where <r> <g> <b> are the
0-255 int values for red, green and blue.
rgb#<hexcode> Rgb#<hexcode> where <hexcode> is a 6 char hex colour e.g rgb#C71585
web-<webcolour> Web-<webcolour>
The acceptable values for <termcolour> and <webcolour> can be queried using
punk::ansi::a? term
and
punk::ansi::a? web
Example to set foreground red and background cyan followed by a reset:
set str \"[a+ red Cyan]sample text[a]\"
"
}]]
proc a {args} {
#*** !doctools
#[call [fun a] [opt {ansicode...}]]
@ -4281,6 +4289,7 @@ tcl::namespace::eval punk::ansi {
}
4 {
#REVIEW - merging extended (e.g 4:4) underline attributes suppresses all other SGR attributes on at least some terminals which don't support extended underlines
#e.g hyper on windows
if {[llength $paramsplit] == 1} {
tcl::dict::set codestate underline 4
} else {
@ -4634,6 +4643,8 @@ tcl::namespace::eval punk::ansi::ta {
#[list_begin definitions]
tcl::namespace::path ::punk::ansi
variable PUNKARGS
#handle both 7-bit and 8-bit csi
#review - does codepage affect this? e.g ebcdic has 8bit csi in different position
@ -4706,15 +4717,31 @@ tcl::namespace::eval punk::ansi::ta {
#variable re_ansi_split "${re_csi_code}|${re_esc_osc1}|${re_esc_osc2}|${re_esc_osc3}|${re_standalones}|${re_ST}|${re_g0_open}|${re_g0_close}"
set re_ansi_split $re_ansi_detect
lappend PUNKARGS [list -dynamic 0 {
@id -id ::punk::ansi::ta::detect
@cmd -name punk::ansi::ta::detect -help\
"Return a boolean indicating whether Ansi codes were detected in text.
Important caveat:
When text is a tcl list made from splitting (or lappending) some ansi string
- individual elements may be braced or have certain chars escaped.
(one example is if a list element contains an unbalanced brace)
This can cause square brackets that form part of the ansi to be backslash escaped
- and the function can fail to match it as an Ansi code.
"
@values -min 1
text -type string
} ]
#*** !doctools
#[call [fun detect] [arg text]]
#[para]Return a boolean indicating whether Ansi codes were detected in text
#[para]Important caveat:
#[para] When text is a tcl list made from splitting (or lappending) some ansi string - individual elements may be braced or have certain chars escaped. (one example is if a list element contains an unbalanced brace)
#[para] This can cause square brackets that form part of the ansi being backslash escaped - and the regexp can fail to match
#detect any ansi escapes
#review - only detect 'complete' codes - or just use the opening escapes for performance?
proc detect {text} [string map [list <re> [list $re_ansi_detect]] {
#*** !doctools
#[call [fun detect] [arg text]]
#[para]Return a boolean indicating whether Ansi codes were detected in text
#[para]Important caveat:
#[para] When text is a tcl list made from splitting (or lappending) some ansi string - individual elements may be braced or have certain chars escaped. (one example is if a list element contains an unbalanced brace)
#[para] This can cause square brackets that form part of the ansi being backslash escaped - and the regexp can fail to match
regexp <re> $text
}]
@ -7405,7 +7432,7 @@ if {![info exists ::punk::args::register::NAMESPACES]} {
set NAMESPACES [list]
}
}
lappend ::punk::args::register::NAMESPACES ::punk::ansi ::punk::ansi::class
lappend ::punk::args::register::NAMESPACES ::punk::ansi ::punk::ansi::class ::punk::ansi::ta
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
## Ready

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

File diff suppressed because it is too large Load Diff

494
src/modules/punk/args/tclcore-999999.0a1.0.tm

@ -141,29 +141,219 @@ tcl::namespace::eval punk::args::tclcore {
variable PUNKARGS
# -- --- --- --- ---
#non colour SGR codes
# we can use these directly via ${$I} etc without marking a definition with -dynamic
#This is because they don't need to change when colour switched on and off.
set I [a+ italic]
set NI [a+ noitalic]
set B [a+ bold]
set N [a+ normal]
# -- --- --- --- ---
# -- --- --- --- --- --- --- --- --- --- --- --- --- ---
# library commands loaded via auto_index
# -- --- --- --- --- --- --- --- --- --- --- --- --- ---
lappend PUNKARGS [list {
*id parray
*proc -name "Builtin: parray" -help\
@id -id ::parray
@cmd -name "Builtin: parray" -help\
"Prints on standard output the names and values of all the elements in the
array arrayName, or just the names that match pattern (using the matching
rules of string_match) and their values if pattern is given.
ArrayName must be an array accessible to the caller of parray. It may either
be local or global. The result of this command is the empty string.
(loaded via auto_index)"
*values -min 1 -max 2
@values -min 1 -max 2
arrayName -type string -help\
"variable name of an array"
pattern -type string -optional 1 -help\
"Match pattern possibly containing glob characters"
} "*doc -name Manpage: -url [manpage_tcl library]" ]
} "@doc -name Manpage: -url [manpage_tcl library]" ]
# -- --- --- --- --- --- --- --- --- --- --- --- --- ---
#categorise array subcommands based on currently known groupings.
#we do this dynamically because Tcl ensembles (even some core ones) can have subcommands added at runtime.
proc array_subcommands {} {
package require punk::ns
set subdict [punk::ns::ensemble_subcommands array]
set expected_searchcmds {startsearch anymore nextelement donesearch}
set searchcmds [list]
foreach sc $expected_searchcmds {
if {$sc in [dict keys $subdict]} {
lappend searchcmds $sc
}
}
set argdef ""
append argdef "subcommand -choicegroups \{" \n
append argdef " \"\" \{" \n
append argdef " [dict keys [dict remove $subdict {*}$searchcmds]]" \n
append argdef " \}" \n
append argdef " \"search\" \{" \n
append argdef " $searchcmds" \n
append argdef " \}" \n
append argdef " \} -choicecolumns 4 " \n
return $argdef
}
lappend PUNKARGS [list -dynamic 1 {
@id -id ::array
@cmd -name "Builtin: array" -help\
"Manipulate array variables"
@values
${[punk::args::tclcore::array_subcommands]}
} "@doc -name Manpage: -url [manpage_tcl array]" ]
#todo - make generic - take command and known_groups_dict
proc info_subcommands {} {
package require punk::ns
set subdict [punk::ns::ensemble_subcommands info]
set allsubs [dict keys $subdict]
dict set groups "system" {hostname library nameofexecutable patchlevel script sharedlibextension tclversion}
dict set groups "{proc introspection}" {args body default}
dict set groups "variables" {constant consts exists globals locals vars}
dict set groups "{oo object introspection}" {class object}
set allgrouped [list]
dict for {g members} $groups {
lappend allgrouped {*}$members
}
set others [list]
foreach sc $allsubs {
if {$sc ni $allgrouped} {
lappend others $sc
}
}
set argdef ""
append argdef "subcommand -choicegroups \{" \n
append argdef " \"\" \{$others\}" \n
dict for {g members} $groups {
append argdef " $g \{$members\}" \n
}
append argdef " \}" \n
return $argdef
}
lappend PUNKARGS [list -dynamic 1 {
@id -id ::info
@cmd -name "Builtin: info" -help\
"Information about the state of the Tcl interpreter"
@values
${[punk::args::tclcore::info_subcommands]}
} "@doc -name Manpage: -url [manpage_tcl array]" ]
#An idiom for sharing common features - incomplete - todo work out what happens with (default)::id that has leaders,opts,values
#todo @cmd -help+ text (append to existing help that came from a default?)
lappend PUNKARGS [list {
@id -id "(default)::tcl::binary::*::base64"
@cmd -help\
"The base64 binary encoding is commonly used in mail messages and XML documents,
and uses mostly upper and lower case letters and digits. It has the distinction
of being able to be rewrapped arbitrarily without losing information.
"
} "@doc -name Manpage: -url [manpage_tcl binary]" ]
lappend PUNKARGS [list {
@id -id "::tcl::binary::encode::base64"
@default -id (default)::tcl::binary::*::base64
@cmd -name "binary encode base64"
-maxlen -type integer -help\
"Indicates that the output should be split into lines of no more than length
characters. By default, lines are not split."
-wrapchar -type character -default \n -help\
"Indicates that, when lines are split because of the -maxlen option, character
should be used to separate lines. By default, this is a newline character, \"\\n\"."
@values -min 1 -max 1
data -type string
} ]
lappend PUNKARGS [list {
@id -id "::tcl::binary::decode::base64"
@cmd -name "binary decode base64"
-strict -type none -help\
"Instructs the decoder to throw an error if it encounters any characters that
are not strictly part of the encoding itself. Otherwise it ignores them.
RFC 2045 calls for base64 decoders to be non-strict."
@values -min 1 -max 1
data -type string
} ]
lappend PUNKARGS [list {
@id -id "(default)::tcl::binary::*::hex"
@cmd -help\
"The hex binary encoding converts each byte to a pair of hexadecimal digits
that represent the byte value as a hexadecimal integer. When encoding, lower
characters are used. When decoding, upper and lower characters are accepted."
} "@doc -name Manpage: -url [manpage_tcl binary]" ]
lappend PUNKARGS [list {
@id -id "::tcl::binary::encode::hex"
@default -id (default)::tcl::binary::*::hex
@cmd -name "binary encode hex"
@values -min 1 -max 1
data -type string
} ]
lappend PUNKARGS [list {
@id -id "::tcl::binary::decode::hex"
@default -id (default)::tcl::binary::*::hex
@cmd -name "binary encode hex"
-strict -type none -help\
"Instructs the decoder to throw an error if it encounters whitespace
characters. Otherwise it ignores them."
@values -min 1 -max 1
data -type string
} "@doc -name Manpage: -url [manpage_tcl binary]" ]
lappend PUNKARGS [list {
@id -id "(default)::tcl::binary::*::uuencode"
@cmd -help\
"The uuencode binary encoding used to be common for transfer of data between Unix
systems and on USENT, but is less common these days, having been largely
superseded by the base64 binary encoding.
Note that neither the encoder nor the decoder handle the header and footer of the
uuencode format."
} "@doc -name Manpage: -url [manpage_tcl binary]" ]
lappend PUNKARGS [list {
@id -id "::tcl::binary::encode::uuencode"
@default -id (default)::tcl::binary::*::uuencode
#todo @cmd -help+ "Changing the options may produce files that other implementations of decoders cannot process"
@cmd -name "binary encode uuencode"
-maxlen -type integer -default 61 -range {5 85} -help\
"Indicates the maximum number of characters to produce for each encoded line.
The valid range is 5 to 85. Line lengths outside that range cannot be
accommodated by the encoding format."
-wrapchar -type string -default \n -help\
"Indicates the character(s) to use to mark the end of each encoded line.
Acceptable values are a sequence of zero or more character from the set
{ \\x09 (TAB), \\x0B (VT), \\x0C (FF), \\x0D (CR) } followed by zero or
one newline \\x0A (LF). Any other values are rejected because they would
generate encoded text that could not be decoded. The default value is a
single newline.
"
@values -min 1 -max 1
data -type string
} ]
lappend PUNKARGS [list {
@id -id "::tcl::binary::decode::uuencode"
@default -id (default)::tcl::binary::*::uuencode
@cmd -name "binary decode uuencode"
-strict -type none -help\
"Instructs the decoder to throw an error if it encounters anything outside
of the standard encoding format. Without this option, the decoder tolerates
some deviations, mostly to forgive reflows of lines between the encoder and
decoder."
@values -min 1 -max 1
data -type string
} ]
lappend PUNKARGS [list {
*id time
*proc -name "Builtin: time" -help\
@id -id ::time
@cmd -name "Builtin: time" -help\
"Calls the Tcl interpreter count times to evaluate script
(or once if count is not specified). It will then return
a string of the form
@ -172,46 +362,129 @@ tcl::namespace::eval punk::args::tclcore {
iteration, in microseconds. Time is measured in elapsed
time, not CPU time.
(see also: timerate)"
*values -min 1 -max 2
@values -min 1 -max 2
script -type script
count -type integer -default 1 -optional 1
} "*doc -name Manpage: -url [manpage_tcl time]" ]
} "@doc -name Manpage: -url [manpage_tcl time]" ]
lappend PUNKARGS [list {
@id -id ::tcl::chan::tell
@cmd -name "Builtin: tcl::chan::tell" -help\
"Returns a number giving the current access position within the underlying
data stream for the channel named channel. This value returned is a byte
offset that can be passed to ${[a+ bold]}chan seek${[a normal]} in order
to set the channel to a particular position. Note that this value is in
terms of bytes, not characters like ${[a+ bold]}chan read${[a+ normal]}. The
value returned is -1 for channels that do not support seeking."
@values
channel -help \
""
} "@doc -name Manpage: -url [manpage_tcl chan]" ]
lappend PUNKARGS [list {
@id -id ::tcl::info::cmdtype
@cmd -name "Builtin: tcl::info::cmdtype" -help\
"Returns the type of the command named ${$I}commandName${$NI}.
Built-in types are:
${$B}alias${$N}
${$I}commandName${$NI} was created by 'interp alias'. In a safe interpreter an
alias is only visible if both the alias and the target are visible.
${$B}coroutine${$N}
${$I}commandName${$NI} was created by 'coroutine'.
${$B}ensemble${$N}
${$I}commandName${$NI} was created by 'namespace ensemble'.
${$B}import${$N}
${$I}commandName${$NI} was created by 'namespace import'.
${$B}native${$N}
${$I}commandName${$NI} was created by the 'Tcl_CreateObjCommand' interface
directly without further registration of the type of command.
${$B}object${$N}
${$I}commandName${$NI} is the public comand that represents an instance
of oo::object or one of its subclasses.
${$B}privateObject${$N}
${$I}commandName${$NI} is the private command, my by default,
that represents an instance of oo::object or one of its subclasses.
${$B}proc${$N}
${$I}commandName${$NI} was created by 'proc'.
${$B}interp${$N}
${$I}commandName${$NI} was created by 'interp create'.
${$B}zlibStream${$N}
${$I}commandName${$NI} was created by 'zlib stream'.
"
@values -min 1 -max 1
commandName -type string
} "@doc -name Manpage: -url [manpage_tcl info]" ]
lappend PUNKARGS [list {
@id -id ::tcl::namespace::origin
@cmd -name "Builtin: tcl::namespace::origin" -help\
"Returns the fully-qualified name of the original command to which the
imported command command refers. When a command is imported into a
namespace, a new command is created in that namespace that points to the
actual command in the exporting namespace. If a command is imported into
a sequence of namespaces a,b,...,n where each successive namespace just
imports the command from the previous namespace, this command returns
the fully-qualified name of the original command in the first namespace, a.
If command does not refer to an imported command, the command's own
fully-qualified name is returned
"
@values
command
} "@doc -name Manpage: -url [manpage_tcl namespace]" ]
lappend PUNKARGS [list {
*id tcl::namespace::path
*proc -name "Builtin: tcl::namespace::path" -help\
@id -id ::tcl::namespace::path
@cmd -name "Builtin: tcl::namespace::path" -help\
"Returns the command resolution path of the current namespace.
If namespaceList is specified as a list of named namespaces, the current
namespace's command resolution path is set to those namespaces and returns
the empty list. The default command resolution path is always empty.
See the section NAME_RESOLUTION in the manpage for an explanation of the
rules regarding name resolution."
*values -min 0 -max 1
@values -min 0 -max 1
namespaceList -type list -optional 1 -help\
"List of existing namespaces"
} "*doc -name Manpage: -url [manpage_tcl namespace]" ]
} "@doc -name Manpage: -url [manpage_tcl namespace]" ]
lappend PUNKARGS [list {
*id tcl::namespace::unknown
*proc -name "Builtin: tcl::namespace::unknown" -help\
@id -id ::tcl::namespace::unknown
@cmd -name "Builtin: tcl::namespace::unknown" -help\
"Sets or returns the unknown command handler for the current namespace.
The handler is invoked when a command called from within the namespace cannot
be found in the current namespace, the namespace's path nor in the global
namespace.
When the handler is invoiked, the full invocation line will be appended to
the script and the result evaluated in the context of the namespace.
The default handler for all namespaces is [a+ italic]::unknown[a].
The default handler for all namespaces is ${[a+ italic]}::unknown${[a+ noitalic]}.
If no argument is given, it returns the handler for the current namespace."
*values -min 0 -max 1
@values -min 0 -max 1
script -type script -optional 1 -help\
"A well formed list representing a command name and optional arguments."
} "*doc -name Manpage: -url [manpage_tcl namespace]" ]
} "@doc -name Manpage: -url [manpage_tcl namespace]" ]
lappend PUNKARGS [list {
@id -id ::tcl::namespace::which
@cmd -name "Builtin: tcl::namespace::which" -help\
"Looks up name as either a command or variable and returns its fully-qulified name.
For example, if name does not exist in the current namespace but does exist in the
global namespace, this command returns a fully-qualified name in the global namespace.
If the command or variable does not exist, this command returns an empty string. If
the variable has been created but not defined, such as with the variable command or
through a trace on the variable, this command will return the fully-qualified name
of the variable. If no flag is given, name is treated as a command name.
See the section NAME RESOLUTION in the manpage for an explanation of the rules
regarding name resolution.
"
@opts
-command
-variable
@values -min 1 -max 1
name
} "@doc -name Manpage: -url [manpage_tcl namespace]" ]
set I [a+ italic]
set NI [a+ noitalic]
lappend PUNKARGS [list {
*id tcl::process::status
*proc -name "Builtin: tcl::process::status" -help\
@id -id ::tcl::process::status
@cmd -name "Builtin: tcl::process::status" -help\
"Returns a dictionary mapping subprocess PIDs to their respective status.
if ${$I}pids${$NI} is specified as a list of PIDs then the command
only returns the status of the matching subprocesses if they exist, and
@ -243,43 +516,43 @@ tcl::namespace::eval punk::args::tclcore {
-- -type none -optional 1 -help\
"Marks the end of switches. The argument following this one will be
treated as the first arg even if it starts with a -."
*values -min 0 -max 1
@values -min 0 -max 1
pids -type list -optional 1 -help\
"A list of PIDs"
} "*doc -name Manpage: -url [manpage_tcl namespace]" ]
} "@doc -name Manpage: -url [manpage_tcl namespace]" ]
lappend PUNKARGS [list {
*id lappend
*proc -name "builtin: lappend" -help\
@id -id ::lappend
@cmd -name "builtin: lappend" -help\
"Append list elements onto a variable.
"
*values -min 1 -max -1
@values -min 1 -max -1
varName -type string -help\
"variable name"
value -type any -optional 1 -multiple 1
} "*doc -name Manpage: -url [manpage_tcl lappend]"]
} "@doc -name Manpage: -url [manpage_tcl lappend]"]
punk::args::definition {
*id ledit
*proc -name "builtin: ledit" -help\
@id -id ::ledit
@cmd -name "builtin: ledit" -help\
"Replace elements of a list stored in variable
"
*values -min 3 -max -1
@values -min 3 -max -1
listVar -type string -help\
"Existing list variable name"
first -type indexexpression
last -type indexexpression
value -type any -optional 1 -multiple 1
} "*doc -name Manpage: -url [manpage_tcl ledit]"
} "@doc -name Manpage: -url [manpage_tcl ledit]"
punk::args::definition {
*id lpop
*proc -name "builtin: lpop" -help\
@id -id ::lpop
@cmd -name "builtin: lpop" -help\
"Get and remove an element in a list
"
*values -min 1 -max -1
@values -min 1 -max -1
varName -type string -help\
"Existing list variable name"
index -type indexexpression -default end -optional 1 -multiple 1 -help\
@ -292,11 +565,11 @@ tcl::namespace::eval punk::args::tclcore {
in turn to address an element within a sublist designated by the
previous indexing operation, allowing the script to remove elements
in sublists, similar to lindex and lset."
} "*doc -name Manpage: -url [manpage_tcl lpop]"
} "@doc -name Manpage: -url [manpage_tcl lpop]"
punk::args::definition {
*id lrange
*proc -name "builtin: lrange" -help\
@id -id ::lrange
@cmd -name "builtin: lrange" -help\
"return one or more adjacent elements from a list.
The new list returned consists of elements first through last, inclusive.
The index values first and last are interpreted the same as index values
@ -304,20 +577,20 @@ tcl::namespace::eval punk::args::tclcore {
indices relative to the end of the list.
e.g lrange {a b c} 0 end-1
"
*values -min 3 -max 3
@values -min 3 -max 3
list -type list -help\
"tcl list as a value"
first -help\
"index expression for first element"
last -help\
"index expression for last element"
} "*doc -name Manpage: -url [manpage_tcl lrange]"
} "@doc -name Manpage: -url [manpage_tcl lrange]"
punk::args::definition {
*id tcl::string::cat
@id -id ::tcl::string::cat
*proc -name "builtin: tcl::string::cat" -help\
@cmd -name "builtin: tcl::string::cat" -help\
"Concatente the given strings just like placing them directly next to each other and
return the resulting compound string. If no strings are present, the result is an
empty string.
@ -326,14 +599,14 @@ tcl::namespace::eval punk::args::tclcore {
to return -level 0, and is more efficient than building a list of arguments and using
join with an empty join string."
*values -min 0 -max -1
@values -min 0 -max -1
string -type string -optional 1 -multiple 1
} "*doc -name Manpage: -url [manpage_tcl string]"
} "@doc -name Manpage: -url [manpage_tcl string]"
punk::args::definition {
*id tcl::string::compare
@id -id ::tcl::string::compare
*proc -name "builtin: tcl::string::compare" -help\
@cmd -name "builtin: tcl::string::compare" -help\
"Perform a character-by-character comparison of strings string1 and string2.
Returns -1, 0, or 1, dpending on whether string1 is lexicographically
lessthan, equal to, or greater than string2"
@ -345,15 +618,15 @@ tcl::namespace::eval punk::args::tclcore {
"If -length is specified, then only the first length characters are used in the comparison.
If -length is negative, it is ignored."
*values -min 2 -max 2
@values -min 2 -max 2
string1 -type string
string2 -type string
} "*doc -name Manpage: -url [manpage_tcl string]"
} "@doc -name Manpage: -url [manpage_tcl string]"
punk::args::definition {
*id tcl::string::equal
@id -id ::tcl::string::equal
*proc -name "builtin: tcl::string::equal" -help\
@cmd -name "builtin: tcl::string::equal" -help\
"Perform a character-by-character comparison of strings string1 and string2.
Returns 1 if string1 and string2 are identical, or 0 when not."
@ -364,30 +637,30 @@ tcl::namespace::eval punk::args::tclcore {
"If -length is specified, then only the first length characters are used in the comparison.
If -length is negative, it is ignored."
*values -min 2 -max 2
@values -min 2 -max 2
string1 -type string
string2 -type string
} "*doc -name Manpage: -url [manpage_tcl string]"
} "@doc -name Manpage: -url [manpage_tcl string]"
punk::args::definition {
*id tcl::string::first
*proc -name "builtin: tcl::string::first" -help\
@id -id ::tcl::string::first
@cmd -name "builtin: tcl::string::first" -help\
"Search haystackString for a sequence of characters that exactly match the characters
in needleString. If found, return the index of the first character in the first such
match within haystackString. If there is no match, then return -1. If startIndex is
specified (in any of the forms described in STRING_INDICES), then the search is
constrained to start with the character in haystackString specified by the index.
"
*values -min 2 -max 3
@values -min 2 -max 3
needleString -type string
haystackString -type string
startIndex -type indexexpression -optional 1 -help\
"integer or simple expression."
} "*doc -name Manpage: -url [manpage_tcl string]"
} "@doc -name Manpage: -url [manpage_tcl string]"
punk::args::definition {
*id tcl::string::insert
*proc -name "builtin: tcl::string::insert" -help\
@id -id ::tcl::string::insert
@cmd -name "builtin: tcl::string::insert" -help\
"Returns a copy of string with insertString inserted at the index'th character.
If index is start-relative, the first character inserted in the returned string will be
at the specified index.
@ -398,43 +671,43 @@ tcl::namespace::eval punk::args::tclcore {
If index is at or after the end of the string (e.g., index is end), insertString is
appended to string."
*values -min 3 -max 3
@values -min 3 -max 3
string -type string
index -type indexexpression -help\
"The index may be specified as described in the STRING_INDICES section"
insertString -type string
} "*doc -name Manpage: -url [manpage_tcl string]"
} "@doc -name Manpage: -url [manpage_tcl string]"
punk::args::definition {
*id tcl::string::last
*proc -name "builtin: tcl::string::last" -help\
@id -id ::tcl::string::last
@cmd -name "builtin: tcl::string::last" -help\
"Search haystackString for a sequence of characters that exactly match the characters
in needleString. If found, return the index of the first character in the last such
match within haystackString. If there is no match, then return -1. If lastIndex is
specified (in any of the forms described in STRING_INDICES), then only the characters
in haystackString at or before the specified lastIndex will be considered by the search
"
*values -min 2 -max 3
@values -min 2 -max 3
needleString -type string
haystackString -type string
lastIndex -type indexexpression -optional 1 -help\
"integer or simple expression."
} "*doc -name Manpage: -url [manpage_tcl string]"
} "@doc -name Manpage: -url [manpage_tcl string]"
punk::args::definition {
*id tcl::string::repeat
*proc -name "builtin: tcl::string::repeat" -help\
@id -id ::tcl::string::repeat
@cmd -name "builtin: tcl::string::repeat" -help\
"Returns a string consisting of string concatenated with itself count times."
*values -min 2 -max 2
@values -min 2 -max 2
string -type string
count -type int -help\
"If count is 0, the empty string will be returned."
} "*doc -name Manpage: -url [manpage_tcl string]"
} "@doc -name Manpage: -url [manpage_tcl string]"
punk::args::definition {
*id tcl::string::replace
*proc -name "builtin: tcl::string::replace" -help\
@id -id ::tcl::string::replace
@cmd -name "builtin: tcl::string::replace" -help\
"Removes a range of consecutive characters from string, starting with the character whose
index is first and ending with the character whose index is last
(Using the forms described in STRING_INDICES). An index of 0 refers to the first
@ -444,68 +717,68 @@ tcl::namespace::eval punk::args::tclcore {
end. The initial string is returned untouched, if first is greater than last, or if
first is equal to or greater than the length of the inital string, or last is less
than 0."
*values -min 3 -max 3
@values -min 3 -max 3
string -type string
first -type indexexpression
last -type indexexpression
newstring -type string -optional 1 -help\
"If newstring is specified, then it is placed in the removed character range."
} "*doc -name Manpage: -url [manpage_tcl string]"
} "@doc -name Manpage: -url [manpage_tcl string]"
punk::args::definition {
*id tcl::string::totitle
*proc -name "builtin: tcl::string::totitle" -help\
@id -id ::tcl::string::totitle
@cmd -name "builtin: tcl::string::totitle" -help\
"Returns a value equal to string except that the first character in string is converted to
it's Unicode title case variant (or upper case if there is no title case variant) and the
rest of the string is converted to lower case."
*values -min 1 -max 1
@values -min 1 -max 1
string -type string
first -type indexexpression -optional 1 -help\
"If first is specified, it refers to the first char index in the string to start modifying."
last -type indexexpression -optional 1 -help\
"If last is specified, it refers to the char index in the string to stop at (inclusive)."
} "*doc -name Manpage: -url [manpage_tcl string]"
} "@doc -name Manpage: -url [manpage_tcl string]"
punk::args::definition {
*id tcl::string::wordend
*proc -name "builtin: tcl::string::wordend" -help\
@id -id ::tcl::string::wordend
@cmd -name "builtin: tcl::string::wordend" -help\
"Returns the index of the character just after the last one in the word containing
character charIndex of string.
A word is considered to be any contiguous range of alphanumeric (Unicode letters or decimal digits)
or underscore (Unicode connector punctuation) characters, or any single character other than these."
*values -min 2 -max 2
@values -min 2 -max 2
string -type string
charIndex -type indexexpression -help\
"integer or simple expresssion.
e.g end
e.g end-1
e.g M+N"
} "*doc -name Manpage: -url [manpage_tcl string]"
} "@doc -name Manpage: -url [manpage_tcl string]"
punk::args::definition {
*id tcl::string::wordstart
*proc -name "builtin: tcl::string::wordstart" -help\
@id -id ::tcl::string::wordstart
@cmd -name "builtin: tcl::string::wordstart" -help\
"Returns the index of the first character in the word containing
character charIndex of string.
A word is considered to be any contiguous range of alphanumeric (Unicode letters or decimal digits)
or underscore (Unicode connector punctuation) characters, or any single character other than these.
"
*values -min 2 -max 2
@values -min 2 -max 2
string -type string
charIndex -type indexexpression -help\
"integer or simple expresssion.
e.g end
e.g end-1
e.g M+N"
} "*doc -name Manpage: -url [manpage_tcl string]"
} "@doc -name Manpage: -url [manpage_tcl string]"
punk::args::definition [punk::lib::tstr -return string {
*id tcl::string::is
*proc -name "builtin: tcl::string::is" -help\
@id -id ::tcl::string::is
@cmd -name "builtin: tcl::string::is" -help\
"Returns 1 if string is a valid member of the specified character class, otherwise returns 0.
"
*leaders -min 1 -max 1
@leaders -min 1 -max 1
class -type string\
-choices {
alnum
@ -649,15 +922,56 @@ tcl::namespace::eval punk::args::tclcore {
varname will always be set to 0, due to the varied nature of a valid boolean value"
-strict -type none -help\
"If -strictis specified, then an empty string returns 0,
"If -strict is specified, then an empty string returns 0,
otherwise an empty string will return 1 on any class"
-failindex -type variablename -help\
"If -failindex is specified, then if the function returns 0,
the index in the string where the class was no longer valid will be stored
in the variable named."
*values -min 1 -max 1
@values -min 1 -max 1
string -type string -optional 0
}] "*doc -name Manpage: -url [manpage_tcl string]"
}] "@doc -name Manpage: -url [manpage_tcl string]"
punk::args::definition {
@id -id ::zlib
@cmd -name "builtin: ::zlib" -help\
"zlib - compression and decompression operations
"
@leaders -min 1 -max 1
subcommand -type string\
-choicecolumns 2\
-choicegroups {
compression {compress decompress deflate gunzip gzip inflate}
channel {push}
streaming {stream}
checksumming {adler32 crc32}
}\
-choicelabels {
compress "zlib compress string ?level?"
decompress "zlib decompress string ?buffersize?"
deflate "zlib deflate string ?level?"
gunzip "zlib gunzip string ?-headerVar varName?"
gzip "zlib gzip string ?-level level? ?-header dict?"
inflate "zlib inflate string ?bufferSize?"
push "zlib push mode channel ?options ...?"
stream "zlib stream mode ?options?"
adler32 "zlib adler32 string ?initValue?"
crc32 "zlib crc32 string ?initValue?"
}
} "@doc -name Manpage: -url [manpage_tcl zlib]"
punk::args::definition {
@id -id "::zlib adler32"
@cmd -name "builtin: ::zlib adler32" -help\
"Compute a checksum of binary string ${$I}string${$NI} using the Adler32
algorithm. If given, ${$I}initValue${$NI} is used to initialize the checksum engine.
"
@values -min 1 -max 2
string -type string
initValue -type string -optional 1
} "@doc -name Manpage: -url [manpage_tcl zlib]"
#*** !doctools
#[subsection {Namespace punk::args::tclcore}]

18
src/modules/punk/blockletter-999999.0a1.0.tm

@ -120,17 +120,17 @@ tcl::namespace::eval punk::blockletter {
set logo_letter_colours [list Red Green Blue Purple Yellow]
punk::args::definition [tstr -return string {
*id punk::blockletter::logo
@id -id ::punk::blockletter::logo
-frametype -default {${$default_frametype}}
-outlinecolour -default "web-white"
-backgroundcolour -default {} -help "e.g Web-white
This argument is the name as accepted by punk::ansi::a+"
*values -min 0 -max 0
@values -min 0 -max 0
}]
proc logo {args} {
variable logo_letter_colours
variable default_frametype
set argd [punk::args::get_by_id punk::blockletter::logo $args]
set argd [punk::args::get_by_id ::punk::blockletter::logo $args]
set f [dict get $argd opts -frametype]
set bd [dict get $argd opts -outlinecolour]
set bgansi [dict get $argd opts -backgroundcolour] ;#we use ta::detect to see if already ansi and apply as necessary
@ -219,17 +219,17 @@ tcl::namespace::eval punk::blockletter {
}
punk::args::definition [tstr -return string {
*id punk::blockletter::text
@id -id ::punk::blockletter::text
-bgcolour -default "Web-red"
-bordercolour -default "web-white"
-frametype -default {${$default_frametype}}
*values -min 1 -max 1
@values -min 1 -max 1
str -help "Text to convert to blockletters
Requires terminal font to support relevant block characters"
"
}]
proc text {args} {
set argd [punk::args::get_by_id punk::blockletter::text $args]
set argd [punk::args::get_by_id ::punk::blockletter::text $args]
set opts [dict get $argd opts]
set str [dict get $argd values str]
set str [string map {\r\n \n} $str]
@ -281,17 +281,17 @@ tcl::namespace::eval punk::blockletter::lib {
punk::args::definition [tstr -return string {
*id punk::blockletter::block
@id -id ::punk::blockletter::block
-height -default 2
-width -default 4
-frametype -default {${$::punk::blockletter::default_frametype}}
-bgcolour -default "Web-red"
-bordercolour -default "web-white"
*values -min 0 -max 0
@values -min 0 -max 0
}]
proc block {args} {
upvar ::punk::blockletter::default_frametype ft
set argd [punk::args::get_by_id punk::blockletter::block $args]
set argd [punk::args::get_by_id ::punk::blockletter::block $args]
set bg [dict get $argd opts -bgcolour]
set bd [dict get $argd opts -bordercolour]
set h [dict get $argd opts -height]

15
src/modules/punk/cap/handlers/templates-999999.0a1.0.tm

@ -254,8 +254,9 @@ namespace eval punk::cap::handlers::templates {
}
method folders {args} {
set argd [punk::args::get_dict {
@id -id "::punk::cap::handlers::templates::class::api folders"
-startdir -default ""
*values -max 0
@values -max 0
} $args]
set opts [dict get $argd opts]
@ -471,10 +472,11 @@ namespace eval punk::cap::handlers::templates {
}
method get_itemdict_projectlayouts {args} {
set argd [punk::args::get_dict {
*opts -anyopts 1
@id -id "::punk::cap::handlers::templates::class::api get_itemdict_projectlayouts"
@opts -anyopts 1
#peek -startdir while allowing all other opts/vals to be verified down-the-line instead of here
-startdir -default ""
*values -maxvalues -1
@values -maxvalues -1
} $args]
set opt_startdir [dict get $argd opts -startdir]
@ -648,14 +650,15 @@ namespace eval punk::cap::handlers::templates {
#and a name determining command -command_get_item_name
method _get_itemdict {args} {
set argd [punk::args::get_dict {
*proc -name _get_itemdict
*opts -anyopts 0
@id -id "::punk::cap::handlers::templates::class::api _get_itemdict"
@cmd -name _get_itemdict
@opts -anyopts 0
-startdir -default ""
-templatefolder_subdir -optional 0
-command_get_items_from_base -optional 0
-command_get_item_name -optional 0
-not -default "" -multiple 1
*values -maxvalues -1
@values -maxvalues -1
globsearches -default * -multiple 1
} $args]
set opts [dict get $argd opts]

12
src/modules/punk/config-0.1.tm

@ -362,10 +362,10 @@ tcl::namespace::eval punk::config {
proc configure {args} {
set argdef {
*id punk::config::configure
*proc -name punk::config::configure -help\
@id -id ::punk::config::configure
@cmd -name punk::config::configure -help\
"UNIMPLEMENTED"
*values -min 1 -max 1
@values -min 1 -max 1
whichconfig -type string -choices {startup running stop}
}
set argd [punk::args::get_dict $argdef $args]
@ -388,15 +388,15 @@ tcl::namespace::eval punk::config {
#This is to allow partial configs to be loaded to running, whereas a save of running to any target is always a complete configuration
proc copy {args} {
set argdef {
*id punk::config::copy
*proc -name punk::config::copy -help\
@id -id ::punk::config::copy
@cmd -name punk::config::copy -help\
"Copy a partial or full configuration from one config to another
If a target config has additional settings, then the source config can be considered to be partial with regards to the target.
"
-type -default "" -choices {replace merge} -help\
"Defaults to merge when target is running-config
Defaults to replace when source is running-config"
*values -min 2 -max 2
@values -min 2 -max 2
fromconfig -help\
"running or startup or file name (not fully implemented)"
toconfig -help\

8
src/modules/punk/console-999999.0a1.0.tm

@ -875,7 +875,7 @@ namespace eval punk::console {
}
}
punk::args::set_alias punk::console::code_a+ punk::ansi::a+
punk::args::set_alias ::punk::console::code_a+ ::punk::ansi::a+
proc code_a+ {args} {
variable ansi_wanted
if {$ansi_wanted <= 0} {
@ -1187,14 +1187,14 @@ namespace eval punk::console {
#todo - change -inoutchannels to -terminalobject with prebuilt default
punk::args::definition {
*id punk::console::cell_size
@id -id ::punk::console::cell_size
-inoutchannels -default {stdin stdout} -type list
*values -min 0 -max 1
@values -min 0 -max 1
newsize -default "" -help\
"character cell pixel dimensions WxH"
}
proc cell_size {args} {
set argd [punk::args::get_by_id punk::console::cell_size $args]
set argd [punk::args::get_by_id ::punk::console::cell_size $args]
set inoutchannels [dict get $argd opts -inoutchannels]
set newsize [dict get $argd values newsize]

6
src/modules/punk/du-999999.0a1.0.tm

@ -563,9 +563,10 @@ namespace eval punk::du {
variable win_reparse_tags_by_int
set argd [punk::args::get_dict {
@id -id ::punk::du::lib::Get_attributes_from_iteminfo
-debug -default 0 -help "set 1 for raw data on -debugchannel (default stderr)"
-debugchannel -default stderr -help "channel to write debug output, or none to append to output"
*values -min 1 -max 1
@values -min 1 -max 1
iteminfo -help "iteminfo dict as set by 'twapi::find_file_next <iterator> iteminfo'"
} $args]
set opts [dict get $argd opts]
@ -621,10 +622,11 @@ namespace eval punk::du {
proc attributes_twapi {args} {
set argd [punk::args::get_dict {
@id -id ::punk::du::lib::attributes_twapi
-debug -default 0 -help "set 1 for raw data on -debugchannel (default stderr)"
-debugchannel -default stderr -help "channel to write debug output, or none to append to output"
-detail -default basic -choices {basic full} -help "full returns also the altname/shortname field"
*values -min 1 -max 1
@values -min 1 -max 1
path -help "path to file or folder for which to retrieve attributes"
} $args]
set opts [dict get $argd opts]

8
src/modules/punk/fileline-999999.0a1.0.tm

@ -1252,14 +1252,14 @@ namespace eval punk::fileline {
#[list_begin definitions]
punk::args::definition {
*id punk::fileline::get_textinfo
*proc -name punk::fileline::get_textinfo -help\
@id -id ::punk::fileline::get_textinfo
@cmd -name punk::fileline::get_textinfo -help\
"return: textinfo object instance"
-file -default {} -type existingfile
-translation -default iso8859-1
-encoding -default "\uFFFF"
-includebom -default 0
*values -min 0 -max 1
@values -min 0 -max 1
}
proc get_textinfo {args} {
#*** !doctools
@ -1276,7 +1276,7 @@ namespace eval punk::fileline {
#[para]Currently only utf-8, utf-16* and utf-32* are properly supported even though the other BOMs are detected, reported via get_bomid, and stripped from the data.
#[para]GB18030 falls back to cp936/gbk (unless a gb18030 encoding has been installed). Use -encoding iso8859-1 if this isn't suitable and you need to do your own processing of the bytes.
lassign [dict values [punk::args::get_by_id punk::fileline::get_textinfo $args]] opts values
lassign [dict values [punk::args::get_by_id ::punk::fileline::get_textinfo $args]] opts values
# -- --- --- ---
set opt_file [dict get $opts -file]
set opt_translation [dict get $opts -translation]

26
src/modules/punk/lib-999999.0a1.0.tm

@ -1009,13 +1009,13 @@ namespace eval punk::lib {
set sep " [punk::ansi::a+ Green]=[punk::ansi::a] "
}
set argspec [string map [list %sep% $sep] {
*id punk::lib::pdict
*proc -name pdict -help\
@id -id ::punk::lib::pdict
@cmd -name pdict -help\
"Print dict keys,values to channel
The pdict function operates on variable names - passing the value to the showdict function which operates on values
(see also showdict)"
*opts -any 1
@opts -any 1
#default separator to provide similarity to tcl's parray function
-separator -default "%sep%"
@ -1023,7 +1023,7 @@ namespace eval punk::lib {
-substructure -default {}
-channel -default stdout -help "existing channel - or 'none' to return as string"
*values -min 1 -max -1
@values -min 1 -max -1
dictvar -type string -help "name of variable. Can be a dict, list or array"
@ -1095,14 +1095,16 @@ namespace eval punk::lib {
package require textblock
set argd [punk::args::get_dict [string map [list %sep% $sep %sep_mismatch% $sep_mismatch] {
*id punk::lib::showdict
*proc -name punk::lib::showdict -help "display dictionary keys and values"
@id -id ::punk::lib::showdict
@cmd -name punk::lib::showdict -help "display dictionary keys and values"
#todo - table tableobject
-return -default "tailtohead" -choices {tailtohead sidebyside}
-channel -default none
-trimright -default 1 -type boolean -help "Trim whitespace off rhs of each line.
This can help prevent a single long line that wraps in terminal from making every line wrap due to long rhs padding
"
-trimright -default 1 -type boolean -help\
"Trim whitespace off rhs of each line.
This can help prevent a single long line that wraps in terminal from making
every line wrap due to long rhs padding.
"
-separator -default {%sep%} -help "Separator column between keys and values"
-separator_mismatch -default {%sep_mismatch%} -help "Separator to use when patterns mismatch"
-roottype -default "dict" -help "list,dict,string"
@ -1114,7 +1116,7 @@ namespace eval punk::lib {
-keysortdirection -default increasing -choices {increasing decreasing}
-debug -default 0 -type boolean -help\
"When enabled, produces some rudimentary debug output on stderr"
*values -min 1 -max -1
@values -min 1 -max -1
dictvalue -type list -help "dict or list value"
patterns -default "*" -type string -multiple 1 -help "key or key glob pattern"
}] $args]
@ -2816,7 +2818,7 @@ namespace eval punk::lib {
#eat or own dogfood version - shows the implementation is simpler - but unfortunately not suitable for a simple function like this which should be as fast as possible?
lassign [tcl::dict::values [punk::args::get_dict {
-joinchar -default \n
*values -min 1 -max 1
@values -min 1 -max 1
} $args]] leaders opts values
puts "opts:$opts"
puts "values:$values"
@ -2857,7 +2859,7 @@ namespace eval punk::lib {
#we don't have to decide what is an opt vs a value
#even if the caller provides the argument -block without a value the next function's validation will report a reasonable error because there is now nothing in $values (consumed by -block)
lassign [tcl::dict::values [punk::args::get_dict {
*opts -any 1
@opts -any 1
-block -default {}
} $args]] leaderdict opts valuedict
tailcall linelist {*}$opts {*}[tcl::dict::values $valuedict]

3
src/modules/punk/mix/commandset/doc-999999.0a1.0.tm

@ -168,9 +168,10 @@ namespace eval punk::mix::commandset::doc {
}
proc validate {args} {
set argd [punk::args::get_dict {
@id -id ::punk::mix::commandset::doc::validate
-- -type none -optional 1 -help "end of options marker --"
-individual -type boolean -default 1
*values -min 0 -max -1
@values -min 0 -max -1
patterns -default {*.man} -type any -multiple 1
} $args]
set opt_individual [tcl::dict::get $argd opts -individual]

6
src/modules/punk/mix/commandset/layout-999999.0a1.0.tm

@ -34,7 +34,8 @@ namespace eval punk::mix::commandset::layout {
#per layout functions
proc files {{layout ""}} {
set argd [punk::args::get_dict {
*values -min 1 -max 1
@id -id ::punk::mix::commandset::layout::files
@values -min 1 -max 1
layout -type string -minsize 1
} [list $layout]]
@ -88,7 +89,8 @@ namespace eval punk::mix::commandset::layout {
proc _default {args} {
punk::args::get_dict [subst {
*proc -name ::punk::mix::commandset::layout::collection::_default
@id -id ::punk::mix::commandset::layout::collection::_default
@cmd -name ::punk::mix::commandset::layout::collection::_default
-startdir -type string
-not -type string -multiple 1
globsearches -default * -multiple 1

13
src/modules/punk/mix/commandset/loadedlib-999999.0a1.0.tm

@ -27,8 +27,8 @@ namespace eval punk::mix::commandset::loadedlib {
namespace export *
#search automatically wrapped in * * - can contain inner * ? globs
punk::args::definition {
*id punk::mix::commandset::loadedlib::search
*proc -name "punk::mix::commandset::loadedlib search" -help "search all Tcl libraries available to your local interpreter"
@id -id ::punk::mix::commandset::loadedlib::search
@cmd -name "punk::mix::commandset::loadedlib search" -help "search all Tcl libraries available to your local interpreter"
-return -type string -default table -choices {table tableobject list lines}
-present -type integer -default 2 -choices {0 1 2} -choicelabels {absent present both} -help\
"(unimplemented) Display only those that are 0:absent 1:present 2:either"
@ -38,10 +38,13 @@ namespace eval punk::mix::commandset::loadedlib {
searchstrings -default * -multiple 1 -help\
"Names to search for, may contain glob chars (* ?) e.g *lib*
If no glob chars are explicitly specified, the searchstring will be wrapped with star globs.
eg name -> *name*"
eg name -> *name*
To search for an exact name prefix it with =
e.g =name -> name
"
}
proc search {args} {
set argd [punk::args::get_by_id punk::mix::commandset::loadedlib::search $args]
set argd [punk::args::get_by_id ::punk::mix::commandset::loadedlib::search $args]
set searchstrings [dict get $argd values searchstrings]
set opts [dict get $argd opts]
set opt_return [dict get $opts -return]
@ -56,7 +59,7 @@ namespace eval punk::mix::commandset::loadedlib {
set packages [package names]
set matches [list]
foreach search $searchstrings {
if {[regexp {[?*]} $search]} {
if {[regexp {[?*\[]} $search]} {
#caller has specified specific glob pattern - use it
#todo - respect supplied case only if uppers present? require another flag?
lappend matches {*}[lsearch -all -inline -nocase $packages $search]

13
src/modules/punk/mix/commandset/module-999999.0a1.0.tm

@ -123,10 +123,11 @@ namespace eval punk::mix::commandset::module {
#return all module templates with repeated ones suffixed with .2 .3 etc
proc templates_dict {args} {
set argspec {
*proc -name templates_dict -help "Templates from module and project paths"
@id -id ::punk::mix::commandset::module::templates_dict
@cmd -name templates_dict -help "Templates from module and project paths"
-startdir -default "" -help "Project folder used in addition to module paths"
-not -default "" -multiple 1
*values
@values
globsearches -default * -multiple 1
}
set argd [punk::args::get_dict $argspec $args]
@ -141,8 +142,8 @@ namespace eval punk::mix::commandset::module {
set moduletypes [punk::mix::cli::lib::module_types]
punk::args::definition [subst {
*id punk::mix::commandset::module::new
*proc -name "punk::mix::commandset::module::new" -help\
@id -id ::punk::mix::commandset::module::new
@cmd -name "punk::mix::commandset::module::new" -help\
"Create a new module file in the appropriate folder within src/modules.
If the name given in the module argument is namespaced,
the necessary subfolder(s) will be used or created."
@ -160,7 +161,7 @@ namespace eval punk::mix::commandset::module {
If false (default) an error will be raised if there is a conflict."
-quiet -default 0 -type boolean -help\
"Suppress information messages on stdout"
*values -min 1 -max 1
@values -min 1 -max 1
module -type string -help\
"Name of module, possibly including a namespace and/or version number
e.g mynamespace::mymodule-1.0"
@ -168,7 +169,7 @@ namespace eval punk::mix::commandset::module {
proc new {args} {
set year [clock format [clock seconds] -format %Y]
# use \uFFFD because unicode replacement char should consistently render as 1 wide
set argd [punk::args::get_by_id punk::mix::commandset::module::new $args]
set argd [punk::args::get_by_id ::punk::mix::commandset::module::new $args]
lassign [dict values $argd] leaders opts values received
set module [dict get $values module]

8
src/modules/punk/mix/commandset/scriptwrap-999999.0a1.0.tm

@ -1262,15 +1262,15 @@ namespace eval punk::mix::commandset::scriptwrap {
# [list_begin arguments]
# [arg_def string args] name-value pairs -scriptpath <path>
# [list_end]
*id punk::mix::commandset::scriptwrap
*proc -name punk::mix::commandset::get_wrapper_folders
@id -id ::punk::mix::commandset::scriptwrap
@cmd -name punk::mix::commandset::get_wrapper_folders
*opts -anyopts 0
@opts -anyopts 0
-scriptpath -default "" -type directory\
-help ""
#todo -help folder within a punk.templates provided area???
*values -minvalues 0 -maxvalues 0
@values -minvalues 0 -maxvalues 0
} $args]
# -- --- --- --- --- --- --- --- ---

34
src/modules/punk/nav/fs-999999.0a1.0.tm

@ -636,13 +636,14 @@ tcl::namespace::eval punk::nav::fs {
# c:/repo/jn/punk/../../blah
#dirfiles assumes we don't have glob chars in the filenames or paths - dirfiles_dict can be called directly with explicit -tailglob in the rare case that assumption doesn't hold
# dirfiles will test last segment (tail) of supplied searchspecs for fileness vs folderness (when no globchars present in tail) so that it can pass the appropriate flags downstream
punk::args::definition {
@id -id ::punk::nav::fs::dirfiles
-stripbase -default 1 -type boolean
-formatsizes -default 1 -type boolean -help "Format file size numbers for clarity"
@values -min 0 -max -1
}
proc dirfiles {args} {
set argspecs {
-stripbase -default 1 -type boolean
-formatsizes -default 1 -type boolean -help "Format file size numbers for clarity"
*values -min 0 -max -1
}
set argd [punk::args::get_dict $argspecs $args]
set argd [punk::args::get_by_id ::punk::nav::fs::dirfiles $args]
lassign [dict values $argd] leaders opts values_dict
set opt_stripbase [dict get $opts -stripbase]
@ -726,14 +727,14 @@ tcl::namespace::eval punk::nav::fs {
# -searchbase is always passed through - and is only used to construct a location path if a relative searchspec was supplied
proc dirfiles_dict {args} {
set argspecs {
*id punk::nav::fs::dirfiles_dict
*opts -any 0
@id -id ::punk::nav::fs::dirfiles_dict
@opts -any 0
-searchbase -default ""
-tailglob -default "\uFFFF"
#with_sizes & with_times must accept 0|1|f|d|l where f = files d = dirs l = links (punk::du)
-with_sizes -default "\uFFFF" -type string
-with_times -default "\uFFFF" -type string
*values -min 0 -max -1 -type string
@values -min 0 -max -1 -type string
}
set argd [punk::args::get_dict $argspecs $args]
lassign [dict values $argd] leaders opts vals
@ -991,16 +992,17 @@ tcl::namespace::eval punk::nav::fs {
return [dict merge $listing $updated]
}
punk::args::definition {
@id -id ::punk::nav::fs::dirfiles_dict_as_lines
-stripbase -default 0 -type boolean
-formatsizes -default 1 -type boolean
@values -min 1 -max -1 -type dict
}
#todo - color key via repl-telemetry? help command? documentation? or add tag columns as done in namespace listing?
proc dirfiles_dict_as_lines {args} {
package require overtype
set argspecs {
-stripbase -default 0 -type boolean
-formatsizes -default 1 -type boolean
*values -min 1 -max -1 -type dict
}
set argd [punk::args::get_dict $argspecs $args]
set argd [punk::args::get_by_id ::punk::nav::fs::dirfiles_dict_as_lines $args]
lassign [dict values $argd] leaders opts vals
set list_of_dicts [dict values $vals]

421
src/modules/punk/ns-999999.0a1.0.tm

@ -1608,7 +1608,7 @@ tcl::namespace::eval punk::ns {
if {$word1 eq "punk::mix::base::_cli"} {
#special case for punk deck - REVIEW
#e.g punk::mix::base::_cli -extension ::punk::mix::cli
set fq [lindex $tgt end]
set fq [lindex $tgt end] ;#todo - explicitly get -extension argval in case _cli extended with other options
} else {
#todo - alias may have prefilled some leading args - so usage report should reflect that???
#(currying)
@ -1618,7 +1618,8 @@ tcl::namespace::eval punk::ns {
set fq [nsjoin $location $c]
}
if {$has_punkargs} {
set id [string trimleft $fq :]
#set id [string trimleft $fq :]
set id $fq
if {[::punk::args::id_exists $id]} {
lappend usageinfo $c
} else {
@ -1892,110 +1893,188 @@ tcl::namespace::eval punk::ns {
}
} |data@@ok/result> {lmap v $data {punk::ns::nstail $v}} |> lsort |> {join $data \n} <ns/0|
proc ensemble_subcommands {origin} {
set ensembleinfo [namespace ensemble configure $origin]
set prefixes [dict get $ensembleinfo -prefixes]
set map [dict get $ensembleinfo -map]
set ns [dict get $ensembleinfo -namespace]
#review - we can have a combination of commands from -map as well as those exported from -namespace
# if and only if -subcommands is specified
set subcommand_dict [dict create]
set commands [list]
set nscommands [list]
if {[llength [dict get $ensembleinfo -subcommands]]} {
#set exportspecs [namespace eval $ns {namespace export}]
#foreach pat $exportspecs {
# lappend nscommands {*}[info commands ${ns}::$pat]
#}
#when using -subcommands, even unexported commands are available
set nscommands [info commands ${ns}::*]
foreach sub [dict get $ensembleinfo -subcommands] {
if {[dict exists $map $sub]} {
#-map takes precence over same name exported from -namespace
dict set subcommand_dict $sub [dict get $map $sub]
} elseif {"${ns}::$sub" in $nscommands} {
dict set subcommand_dict $sub ${ns}::$sub
} else {
#subcommand probably supplied via -unknown handler?
dict set subcommand_dict $sub ""
}
}
} else {
if {[dict size $map]} {
set subcommand_dict $map
} else {
set exportspecs [namespace eval $ns {namespace export}]
foreach pat $exportspecs {
lappend nscommands {*}[info commands ${ns}::$pat]
}
foreach fqc $nscommands {
dict set subcommand_dict [namespace tail $fqc] $fqc
}
}
}
return $subcommand_dict
}
#todo - -cache or -refresh to configure whether we introspect ensembles/objects each time?
# - as this is interactive generally introspection should be ok at the top level
# but if we need to go down multiple levels of subcommands generating/testing prefixes - could be an issue ??
punk::args::definition {
*id punk::ns::arginfo
*proc -name punk::ns::arginfo -help\
"Show usage info for a command"
@id -id ::punk::ns::arginfo
@cmd -name punk::ns::arginfo -help\
"Show usage info for a command.
It supports the following:
1) Procedures or builtins for which a punk::args definition has
been loaded.
2) tepam procedures (returns string form only)
3) ensemble commands - auto-generated unless documented via punk::args
(subcommands will show with an indicator if they are
explicitly documented or are themselves ensembles)
4) tcl::oo objects - auto-gnerated unless documented via punk::args
5) dereferencing of aliases to find underlying command
(will not work with some renamed aliases)
Note that native commands commands not explicitly documented will
generally produce no useful info. For example sqlite3 dbcmd objects
could theoretically be documented - but as 'info cmdtype' just shows
'native' they can't (?) be identified as belonging to sqlite3 without
calling them. arginfo deliberately avoids calling commands to elicit
usage information as this is inherently risky. (could create a file,
exit the interp etc)
"
-return -type string -default table -choices {string table tableobject}
-- -type none -help\
"End of options marker
Use this if the command to view begins with a -"
*values -min 1
@values -min 1
commandpath -help\
"command (may be alias or ensemble)"
"command (may be alias, ensemble, tcl::oo object, tepam proc etc)"
subcommand -optional 1 -multiple 1 -default {} -help\
"subcommand if commandpath is an ensemble.
Multiple subcommands can be supplied if ensembles are further nested"
}
proc arginfo {args} {
lassign [dict values [punk::args::get_by_id punk::ns::arginfo $args]] leaders opts values received
set commandpath [dict get $values commandpath]
set commandargs [dict get $values subcommand]
lassign [dict values [punk::args::get_by_id ::punk::ns::arginfo $args]] leaders opts values received
set querycommand [dict get $values commandpath]
set queryargs [dict get $values subcommand]
punk::args::update_definitions ;#ensure any packages that register PUNKARGS have been loaded
#todo - similar to corp? review corp resolution process
#should handle lazy loaded commands (via ::auto_index) that are not yet present but may be documented
if {[string match ::* $commandpath]} {
set targetns [nsprefix $commandpath]
set name [nstail $commandpath]
#don't use 'info commands $commandpath' - or Tcl will use 'namespace path' resolution to find command in another ns or in global
if {[string match ::* $querycommand]} {
set targetns [nsprefix $querycommand]
set name [nstail $querycommand]
#don't use 'info commands $querycommand' - or Tcl will use 'namespace path' resolution to find command in another ns or in global
#when arginfo given a fully qualified path - we only want an answer for that exact command
set nscommands [info commands ${targetns}::*]
if {[lsearch -exact $nscommands $commandpath] >= 0} {
if {[lsearch -exact $nscommands $querycommand] >= 0} {
#use nseval_ifexists to avoid creating intermediate namespaces for bogus paths
if {[catch {
set origin [nseval_ifexists $targetns [list ::namespace origin $name]]
set resolved [nseval_ifexists $targetns [list ::namespace which $name]]
}]} {
set origin $commandpath
set resolved $commandpath
set origin $querycommand
set resolved $querycommand
}
} else {
#fully qualified command specified but doesn't exist
set origin $commandpath
set resolved $commandpath
set origin $querycommand
set resolved $querycommand
}
} else {
set thispath [uplevel 1 [list ::nsthis $commandpath]]
set targetns [nsprefix $thispath]
set name [nstail $thispath]
set targetparts [nsparts $targetns]
if {[lsearch $targetparts :*] >=0} {
#weird ns
set valid_ns [nsexists $targetns]
#relative comandpath
if {[string match (autodef)* $querycommand]} {
#pass through - should be found with id lookup
set origin $querycommand
set resolved $querycommand
} else {
set valid_ns [namespace exists $targetns]
}
if {$valid_ns} {
if {[catch {
set origin [nseval_ifexists $targetns [list ::namespace origin $name]]
set resolved [nseval_ifexists $targetns [list ::namespace which $name]]
}]} {
set thiscmd [nsjoin $targetns $name]
#relative commandpath specified - but Tcl didn't find a match in namespace path
#assume global (todo - look for namespace match in auto_index first ?)
set origin ::$name
set resolved ::$name
set thispath [uplevel 1 [list ::nsthis $querycommand]]
set targetns [nsprefix $thispath]
set name [nstail $thispath]
set targetparts [nsparts $targetns]
if {[lsearch $targetparts :*] >=0} {
#weird ns
set valid_ns [nsexists $targetns]
} else {
set valid_ns [namespace exists $targetns]
}
if {$valid_ns} {
if {[catch {
set origin [nseval_ifexists $targetns [list ::namespace origin $name]]
set resolved [nseval_ifexists $targetns [list ::namespace which $name]]
}]} {
set thiscmd [nsjoin $targetns $name]
#relative querycommand specified - but Tcl didn't find a match in namespace path
#assume global (todo - look for namespace match in auto_index first ?)
set origin ::$name
set resolved ::$name
}
} else {
#namespace as relative to current doesn't seem to exist
#Tcl would also attempt to resolve as global
set numvals [expr {[llength $queryargs]+1}]
#puts "THROWBACK: namespace eval :: [list punk::ns::arginfo {*}[lrange $args 0 end-$numvals] $querycommand {*}$queryargs]"
return [namespace eval :: [list punk::ns::arginfo {*}[lrange $args 0 end-$numvals] $querycommand {*}$queryargs]]
#set origin $querycommand
#set resolved $querycommand
}
} else {
#namespace doesn't seem to exist - but there still could be documentation for lazy loaded ns and command
set origin $commandpath
set resolved $commandpath
}
}
#set thiscmd [nsjoin $targetns $name]
#if {[info commands $thiscmd] eq ""} {
# set origin $thiscmd
# set resolved $thiscmd
#} else {
# set origin [nseval $targetns [list ::namespace origin $name]]
# set resolved [nseval $targetns [list ::namespace which $name]]
#}
}
}
#ns::cmdtype only detects alias type on 8.7+?
set initial_cmdtype [punk::ns::cmdtype $origin]
switch -- $initial_cmdtype {
na - alias {
#REVIEW - alias entry doesn't necessarily match command!
#considure using which_alias (wiki)
#consider using which_alias (wiki)
set tgt [interp alias "" $origin]
if {$tgt eq ""} {
set tgt [interp alias "" [string trimleft $origin :]]
}
#first word of tgt may be namespace relative or absolute
if {$tgt ne ""} {
set word1 [lindex $tgt 0]
if {$word1 eq "punk::mix::base::_cli"} {
#special case for punk deck - REVIEW
#e.g punk::mix::base::_cli -extension ::punk::mix::cli
set fq [lindex $tgt end]
set targetword [lindex $tgt end]
} else {
#todo - alias may have prefilled some leading args - so usage report should reflect that???
#(possible curried arguments)
#review - curried arguments could be for ensembles!
set fq $word1
set targetword $word1
set numvals [expr {[llength $queryargs]+1}]
#puts "ALIAS THROWBACK: namespace eval :: [list punk::ns::arginfo {*}[lrange $args 0 end-$numvals] $targetword {*}[lrange $tgt 1 end] {*}$queryargs]"
return [namespace eval :: [list punk::ns::arginfo {*}[lrange $args 0 end-$numvals] $targetword {*}[lrange $tgt 1 end] {*}$queryargs]]
}
set origin $fq
set origin $targetword
#retest cmdtype on modified origin
set cmdtype [punk::ns::cmdtype $origin]
} else {
@ -2013,6 +2092,83 @@ tcl::namespace::eval punk::ns {
}
}
set id $origin
if {[info commands ::punk::args::id_exists] ne ""} {
#cycle through longest first checking for id matching ::cmd ?subcmd..?
#REVIEW - this doesn't cater for prefix callable subcommands!
set argcopy $queryargs
while {[llength $argcopy]} {
if {[punk::args::id_exists [list $id {*}$argcopy]]} {
return [uplevel 1 [list punk::args::usage {*}$opts [list $id {*}$argcopy]]]
}
lpop argcopy
}
#didn't find any exact matches
#traverse from other direction taking prefixes into account
if {[punk::args::id_exists $id]} {
#cycle forward through leading values
set def [punk::args::get_def $id]
if {[llength $queryargs]} {
set nextqueryargs [list] ;#build a list of prefix-resolved queryargs
set queryargs_untested $queryargs
foreach q $queryargs {
if {[llength [dict get $def leader_names]]} {
set subitems [dict get $def leader_names]
if {[llength $subitems]} {
set next [lindex $subitems 0]
set arginfo [dict get $def arg_info $next]
set allchoices [list]
set choices [punk::args::system::Dict_getdef $arginfo -choices {}]
set choicegroups [punk::args::system::Dict_getdef $arginfo -choicegroups {}]
if {[dict exists $choicegroups ""]} {
dict lappend choicegroups "" {*}$choices
} else {
set choicegroups [dict merge [dict create "" $choices] $choicegroups]
}
dict for {groupname clist} $choicegroups {
lappend allchoices {*}$clist
}
set resolved_q [tcl::prefix::match -error "" $allchoices $q]
if {$resolved_q eq ""} {
break
}
lappend nextqueryargs $resolved_q
lpop queryargs_untested 0
if {$resolved_q ne $q} {
#we have our first difference - recurse with new query args
set numvals [expr {[llength $queryargs]+1}]
return [ punk::ns::arginfo {*}[lrange $args 0 end-$numvals] $querycommand {*}$nextqueryargs {*}$queryargs_untested]
}
#check if subcommands so far have a custom args def
set currentid [list $querycommand {*}$nextqueryargs]
if {[punk::args::id_exists $currentid]} {
set def [punk::args::get_def $currentid
} else {
#We can get no further with custom defs
break
}
}
} else {
#review
break
}
}
} else {
return [uplevel 1 [list punk::args::usage {*}$opts $id]]
}
}
}
if {[string match "(autodef)*" $origin]} {
#wasn't resolved by id - so take this as a request to generate it (probably there is an existing custom def - and this has been manually requested to get the default)
set origin [string range $origin [string length (autodef)] end]
set resolved $origin
}
switch -- $cmdtype {
object {
#class is also an object
@ -2025,19 +2181,19 @@ tcl::namespace::eval punk::ns {
#set class_methods [info class methods $class]
#set object_methods [info object methods $origin]
if {[llength $commandargs]} {
set c1 [lindex $commandargs 0]
if {[llength $queryargs]} {
set c1 [lindex $queryargs 0]
if {$c1 in $public_methods} {
switch -- $c1 {
new {
set constructorinfo [info class constructor $origin]
set arglist [lindex $constructorinfo 0]
set argspec [punk::lib::tstr -return string {
*id "${$origin} new"
*proc -name "${$origin} new" -help\
@id -id "(autodef)${$origin} new"
@cmd -name "${$origin} new" -help\
"create object with specified command name.
Arguments are passed to the constructor."
*values
@values
}]
set i 0
foreach a $arglist {
@ -2054,17 +2210,17 @@ tcl::namespace::eval punk::ns {
incr i
}
punk::args::definition $argspec
return [punk::args::usage {*}$opts "$origin new"]
return [punk::args::usage {*}$opts "(autodef)$origin new"]
}
create {
set constructorinfo [info class constructor $origin]
set arglist [lindex $constructorinfo 0]
set argspec [punk::lib::tstr -return string {
*id "${$origin} create"
*proc -name "${$origin} create" -help\
@id -id "(autodef)${$origin} create"
@cmd -name "${$origin} create" -help\
"create object with specified command name.
Arguments following objectName are passed to the constructor."
*values -min 1
@values -min 1
objectName -type string -help\
"possibly namespaced name for object instance command"
}]
@ -2083,20 +2239,20 @@ tcl::namespace::eval punk::ns {
incr i
}
punk::args::definition $argspec
return [punk::args::usage {*}$opts "$origin create"]
return [punk::args::usage {*}$opts "(autodef)$origin create"]
}
destroy {
#review - generally no doc
# but we may want notes about a specific destructor
set argspec [punk::lib::tstr -return string {
*id "${$origin} destroy"
*proc -name "destroy" -help\
@id -id "(audodef)${$origin} destroy"
@cmd -name "destroy" -help\
"delete object, calling destructor if any.
destroy accepts no arguments."
*values -min 0 -max 0
@values -min 0 -max 0
}]
punk::args::definition $argspec
return [punk::args::usage {*}$opts "$origin destroy"]
return [punk::args::usage {*}$opts "(autodef)$origin destroy"]
}
default {
#use info object call <obj> <method> to resolve callchain
@ -2111,20 +2267,24 @@ tcl::namespace::eval punk::ns {
lassign $impl generaltype mname location methodtype
switch -- $generaltype {
method - private {
#objects being dynamic systems - we should always reinspect.
#Don't use the cached (autodef) def
#If there is a custom def override - use it (should really be -dynamic - but we don't check)
if {$location eq "object"} {
set id "[string trimleft $origin :] $c1" ;# "<object> <method>"
set idcustom "$origin $c1"
#set id "[string trimleft $origin :] $c1" ;# "<object> <method>"
if {[info commands ::punk::args::id_exists] ne ""} {
if {[punk::args::id_exists $id]} {
return [uplevel 1 [list punk::args::usage {*}$opts $id]]
if {[punk::args::id_exists $idcustom]} {
return [uplevel 1 [list punk::args::usage {*}$opts $idcustom]]
}
}
set def [::info object definition $origin $c1]
} else {
set id "[string trimleft $location :] $c1" ;# "<class> <method>"
#set id "[string trimleft $location :] $c1" ;# "<class> <method>"
set idcustom "$location $c1"
if {[info commands ::punk::args::id_exists] ne ""} {
if {[punk::args::id_exists $id]} {
return [uplevel 1 [list punk::args::usage {*}$opts $id]]
if {[punk::args::id_exists $idcustom]} {
return [uplevel 1 [list punk::args::usage {*}$opts $idcustom]]
}
}
set def [::info class definition $location $c1]
@ -2138,12 +2298,15 @@ tcl::namespace::eval punk::ns {
}
}
if {$def ne ""} {
#assert - if we pre
set autoid "(autodef)$location $c1"
set arglist [lindex $def 0]
set argspec [punk::lib::tstr -return string {
*id "${$location} ${$c1}"
*proc -name "${$location} ${$c1}" -help\
"arglist:${$arglist}"
*values
@id -id "${$autoid}"
@cmd -name "${$location} ${$c1}" -help\
"(autogenerated)
arglist:${$arglist}"
@values
}]
set i 0
foreach a $arglist {
@ -2166,7 +2329,7 @@ tcl::namespace::eval punk::ns {
incr i
}
punk::args::definition $argspec
return [punk::args::usage {*}$opts "$location $c1"]
return [punk::args::usage {*}$opts $autoid]
} else {
return "unable to resolve $origin method $c1"
}
@ -2189,9 +2352,11 @@ tcl::namespace::eval punk::ns {
switch -- $generaltype {
method - private {
if {$location eq "object"} {
set id "[string trimleft $origin :] $cmd" ;# "<object> <method>"
#set id "[string trimleft $origin :] $cmd" ;# "<object> <method>"
set id "$origin $cmd"
} else {
set id "[string trimleft $location :] $cmd" ;# "<class> <method>"
#set id "[string trimleft $location :] $cmd" ;# "<class> <method>"
set id "$location $cmd"
}
if {[info commands ::punk::args::id_exists] ne ""} {
if {[punk::args::id_exists $id]} {
@ -2212,15 +2377,16 @@ tcl::namespace::eval punk::ns {
set vline [list method -choices $public_methods -choicelabels $choicelabeldict -choiceprefix 0] ;#methods must be specified in full always? - review
#puts stderr "--->$vline"
set idauto "(autodef)$origin"
set argspec [punk::lib::tstr -return string {
*id ${$origin}
*proc -name "Object: ${$origin}" -help\
"Instance of class: ${$class}"
*values -min 1
@id -id ${$idauto}
@cmd -name "Object: ${$origin}" -help\
"Instance of class: ${$class} (info autogenerated)"
@values -min 1
}]
append argspec \n $vline
punk::args::definition $argspec
return [punk::args::usage {*}$opts $origin]
return [punk::args::usage {*}$opts $idauto]
}
privateObject {
return "Command is a privateObject - no info currently available"
@ -2287,11 +2453,11 @@ tcl::namespace::eval punk::ns {
set subcommands [lsort [dict keys $subcommand_dict]]
if {[llength $commandargs]} {
set match [tcl::prefix::match $subcommands [lindex $commandargs 0]]
if {[llength $queryargs]} {
set match [tcl::prefix::match $subcommands [lindex $queryargs 0]]
if {$match in $subcommands} {
set subcmd [dict get $subcommand_dict $match]
return [arginfo {*}$subcmd {*}[lrange $commandargs 1 end]] ;#subcmd is sometimes multiple words (implemented as a further ensemble subcommand) (e.g huddle string -> "Type_string string")
return [arginfo {*}$subcmd {*}[lrange $queryargs 1 end]] ;#subcmd is sometimes multiple words (implemented as a further ensemble subcommand) (e.g huddle string -> "Type_string string")
}
}
@ -2307,9 +2473,9 @@ tcl::namespace::eval punk::ns {
set is_object [list]
foreach ns $namespaces {
set nsinfo [lindex [punk::ns::nslist_dict [nsjoin [nsprefix $ns] *]] 0]
lappend have_usageinfo {*}[dict get $nsinfo usageinfo]
lappend is_ensemble {*}[dict get $nsinfo ensembles]
lappend is_object {*}[dict get $nsinfo ooobjects]
lappend have_usageinfo {*}[dict get $nsinfo usageinfo]
lappend is_ensemble {*}[dict get $nsinfo ensembles]
lappend is_object {*}[dict get $nsinfo ooobjects]
}
set choicelabeldict [dict create]
@ -2324,14 +2490,17 @@ tcl::namespace::eval punk::ns {
}
set vline [list subcommand -choices $subcommands -choiceprefix $prefixes -choicelabels $choicelabeldict]
set autoid "(autodef)$origin"
set argspec [punk::lib::tstr -return string {
*id ${$origin}
*proc -help "ensemble: ${$origin}"
*values -min 1
@id -id ${$autoid}
@cmd -help\
"(autogenerated)
ensemble: ${$origin}"
@values -min 1
}]
append argspec \n $vline
punk::args::definition $argspec
return [punk::args::usage {*}$opts $origin]
return [punk::args::usage {*}$opts $autoid]
}
#check for tepam help
@ -2364,12 +2533,6 @@ tcl::namespace::eval punk::ns {
}
}
set id [string trimleft $origin :]
if {[info commands ::punk::args::id_exists] ne ""} {
if {[punk::args::id_exists $id]} {
return [uplevel 1 [list punk::args::usage {*}$opts $id]]
}
}
set origin_ns [nsprefix $origin]
set parts [nsparts $origin_ns]
set weird_ns 0
@ -2379,24 +2542,42 @@ tcl::namespace::eval punk::ns {
if {$weird_ns} {
set argl {}
set tail [nstail $origin]
foreach a [nseval_ifexists $origin_ns [list info args $tail]] {
if {[nseval_ifexists $origin_ns [list info default $tail $a def]]} {
lappend a $def
set cmdtype [nseval_ifexists $origin_ns [list punk::ns::cmdtype $tail]]
if {$cmdtype eq "proc"} {
foreach a [nseval_ifexists $origin_ns [list info args $tail]] {
if {[nseval_ifexists $origin_ns [list info default $tail $a def]]} {
lappend a $def
}
lappend argl $a
}
lappend argl $a
}
} else {
set argl {}
foreach a [info args $origin] {
if {[info default $origin $a def]} {
lappend a $def
set cmdtype [punk::ns::cmdtype $origin]
if {$cmdtype eq "proc"} {
set argl {}
set infoargs [info args $origin]
foreach a $infoargs {
if {[info default $origin $a def]} {
lappend a $def
}
lappend argl $a
}
lappend argl $a
}
}
set msg "No argument processor detected"
append msg \n "function signature: $resolved $argl"
if {[llength $queryargs]} {
#todo - something better
set msg "Undocumented or nonexistant subcommand $origin $queryargs"
append msg \n "$origin Type: $cmdtype"
} else {
if {$cmdtype eq "proc"} {
set msg "Undocumented proc $origin"
append msg \n "No argument processor detected"
append msg \n "function signature: $resolved $argl"
} else {
set msg "Undocumented command $origin. Type: $cmdtype"
}
}
return $msg
}
@ -2738,8 +2919,8 @@ tcl::namespace::eval punk::ns {
interp alias "" use "" punk::ns::pkguse
punk::args::definition {
*id punk::ns::nsimport_noclobber
*proc -name punk::ns::nsimport_noclobber -help\
@id -id ::punk::ns::nsimport_noclobber
@cmd -name punk::ns::nsimport_noclobber -help\
"Import exported commands from a namespace into either the current namespace,
or that specified in -targetnamespace.
Return list of imported commands, ignores failures due to name conflicts"
@ -2750,14 +2931,14 @@ tcl::namespace::eval punk::ns {
If not supplied, caller's namespace is used."
-prefix -optional 1 -help\
"string prefix for command names in target namespace"
*values -min 1 -max 1
@values -min 1 -max 1
sourcepattern -type string -optional 0 -help\
"Glob pattern for source namespace.
Globbing only active in the tail segment.
e.g ::mynamespace::*"
}
proc nsimport_noclobber {args} {
lassign [dict values [punk::args::get_by_id punk::ns::nsimport_noclobber $args]] leaders opts values received
lassign [dict values [punk::args::get_by_id ::punk::ns::nsimport_noclobber $args]] leaders opts values received
set sourcepattern [dict get $values sourcepattern]
set source_ns [tcl::namespace::qualifiers $sourcepattern]

6
src/modules/punk/path-999999.0a1.0.tm

@ -645,14 +645,14 @@ namespace eval punk::path {
}
punk::args::definition {
*id punk::path::treefilenames
@id -id ::punk::path::treefilenames
-directory -type directory -help\
"folder in which to begin recursive scan for files."
-call-depth-internal -default 0 -type integer
-antiglob_paths -default {} -help\
"list of path patterns to exclude
may include * and ** path segments e.g /usr/**"
*values -min 0 -max -1 -optional 1 -type string
@values -min 0 -max -1 -optional 1 -type string
tailglobs -multiple 1 -help\
"Patterns to match against filename portion (last segment) of each file path
within the directory tree being searched."
@ -671,7 +671,7 @@ namespace eval punk::path {
#[para] list of path patterns to exclude - may include * and ** path segments e.g /usr/**
#[para]no natsorting - so order is dependent on filesystem
set argd [punk::args::get_by_id punk::path::treefilenames $args]
set argd [punk::args::get_by_id ::punk::path::treefilenames $args]
lassign [dict values $argd] leaders opts values received
set tailglobs [dict values $values]
# -- --- --- --- --- --- ---

84
src/modules/punk/repo-999999.0a1.0.tm

@ -62,6 +62,73 @@ package require punk::mix::util ;#do_in_path
# -- --- --- --- --- --- --- --- --- --- ---
namespace eval punk::repo {
variable PUNKARGS
variable PUNKARGS_aliases
proc get_fossil_usage {} {
set allcmds [runout -n fossil help -a]
set mainhelp [runout -n fossil help]
set maincommands [list]
foreach ln [split $mainhelp \n] {
set ln [string trim $ln]
if {$ln eq "" || [regexp {^[A-Z]+} $ln]} {
continue
}
lappend maincommands {*}$ln
}
set othercmds [punk::lib::ldiff $allcmds $maincommands]
set result "@leaders -min 0\n"
append result [tstr -return string {
subcommand -type string -choicecolumns 8 -choicegroups {
"frequently used commands" {${$maincommands}}
"" {${$othercmds}}
}
}]
return $result
}
#lappend PUNKARGS [list -dynamic 1 {
# @id -id ::punk::repo::fossil_proxy
# @cmd -name fossil -help "fossil executable
# "
# @argdisplay -header "fossil help" -body {${[runout -n fossil help]}}
# } ""]
lappend PUNKARGS [list -dynamic 1 {
@id -id ::punk::repo::fossil_proxy
@cmd -name fossil -help "fossil executable"
${[punk::repo::get_fossil_usage]}
} ]
#experiment
lappend PUNKARGS [list -dynamic 1 {
@id -id "::punk::repo::fossil_proxy diff"
@cmd -name "fossil diff" -help "fossil diff
"
@argdisplay -header "fossil help diff" -body {${[runout -n fossil help diff]}}
} ""]
lappend PUNKARGS [list -dynamic 1 {
@id -id "::punk::repo::fossil_proxy add"
@cmd -name "fossil add" -help "fossil add
"
@argdisplay -header "fossil help add" -body {${[runout -n fossil help add]}}
} ""]
#TODO
#lappend PUNKARGS [list -dynamic 1 {
# @id -glob 1 -id "::punk::repo::fossil_proxy *" -aliases {fs}
# @cmd -name "fossil add" -help "fossil add
# "
# @argdisplay -header "fossil help add" -body {${[runout -n fossil help add]}}
# } ""]
lappend PUNKARGS_aliases {"::fossil" "::punk::repo::fossil_proxy"}
lappend PUNKARGS_aliases {"::fossil diff" "::punk::repo::fossil_proxy diff"}
#Todo - investigate proper way to install a client-side commit hook in the fossil project
#Then we may still use this proxy to check the hook - but the required checks will occur when another shell used
@ -137,7 +204,7 @@ namespace eval punk::repo {
puts stderr "fossil command not found. Please install fossil"
}
}
interp alias "" fossil "" punk::repo::fossil_proxy
# ---
# Calling auto_execok on an external tool can be too slow to do during package load (e.g could be 150ms)
@ -153,6 +220,7 @@ namespace eval punk::repo {
# ----------
#
#uppercase FOSSIL to bypass fossil as alias to fossil_proxy
proc establish_FOSSIL {args} {
if {![info exists ::auto_execs(FOSSIL)]} {
@ -161,7 +229,6 @@ namespace eval punk::repo {
interp alias "" FOSSIL "" ;#delete establishment alias
FOSSIL {*}$args
}
interp alias "" FOSSIL "" punk::repo::establish_FOSSIL
# ----------
proc askuser {question} {
@ -1577,6 +1644,8 @@ namespace eval punk::repo {
}
}
interp alias "" fossil "" punk::repo::fossil_proxy
interp alias "" FOSSIL "" punk::repo::establish_FOSSIL
interp alias {} is_fossil {} ::punk::repo::is_fossil
interp alias {} is_fossil_root {} ::punk::repo::is_fossil_root
@ -1609,6 +1678,17 @@ namespace eval punk::repo::lib {
}
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
if {![info exists ::punk::args::register::NAMESPACES]} {
namespace eval ::punk::args::register {
set ::punk::args::register::NAMESPACES [list] ;#use fully qualified so 8.6 doesn't find existing var in global namespace
}
}
lappend ::punk::args::register::NAMESPACES ::punk::repo
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
## Ready
package provide punk::repo [namespace eval punk::repo {

28
src/modules/punk/safe-999999.0a1.0.tm

@ -366,7 +366,7 @@ tcl::namespace::eval punk::safe {
#REVIEW
set autoPath {}
}
set argd [punk::args::get_by_id punk::safe::interpCreate $args]
set argd [punk::args::get_by_id ::punk::safe::interpCreate $args]
set child [dict get $argd leaders child]
set autoPath [dict get $argd opts -autoPath]
punk::safe::lib::RejectExcessColons $child
@ -387,7 +387,7 @@ tcl::namespace::eval punk::safe {
if {$AutoPathSync} {
set autoPath {}
}
set argd [punk::args::get_by_id punk::safe::interpIC $args]
set argd [punk::args::get_by_id ::punk::safe::interpIC $args]
set child [dict get $argd leaders child]
set autoPath [dict get $argd opts -autoPath]
if {![::interp exists $child]} {
@ -437,7 +437,7 @@ tcl::namespace::eval punk::safe {
# we know that "child" is our given argument because it also
# checks for the "-help" option.
#TODO!
set argd [punk::args::get_by_id punk::safe::interpIC $args]
set argd [punk::args::get_by_id ::punk::safe::interpIC $args]
set child [dict get $argd leaders child]
CheckInterp $child
@ -501,7 +501,7 @@ tcl::namespace::eval punk::safe {
}
default {
#return -code error "unknown flag $name. Known options: $opt_names"
punk::args::get_by_id punk::safe::interpIC [list $child $arg]
punk::args::get_by_id ::punk::safe::interpIC [list $child $arg]
}
}
}
@ -509,7 +509,7 @@ tcl::namespace::eval punk::safe {
# Otherwise we want to parse the arguments like init and create did
#set Args [::tcl::OptKeyParse ::safe::interpIC $args]
set argd [punk::args::get_by_id punk::safe::interpIC $args]
set argd [punk::args::get_by_id ::punk::safe::interpIC $args]
set child [dict get $argd leaders child]
CheckInterp $child
namespace upvar ::punk::safe::system [VarName $child] state
@ -742,8 +742,8 @@ tcl::namespace::eval punk::safe::system {
variable AutoPathSync
set OPTS {
*id punk::safe::OPTS
*opts -optional 1
@id -id ::punk::safe::OPTS
@opts -optional 1
-accessPath -type list -default {} -help\
"access path for the child"
-noStatics -type none -default 0 -help\
@ -765,27 +765,27 @@ tcl::namespace::eval punk::safe::system {
set optlines [punk::args::get_spec punk::safe::OPTS -*]
set INTERPCREATE {
*id punk::safe::interpCreate
*proc -name punk::safe::interpCreate -help\
@id -id ::punk::safe::interpCreate
@cmd -name punk::safe::interpCreate -help\
"Create a safe interpreter with punk::safe specific aliases
Returns the interpreter name"
*leaders
@leaders
child -type string -default "" -regexprefail "^-" -regexprefailmsg "" -optional 1 -help\
"name of the child (optional)"
}
append INTERPCREATE \n $optlines
append INTERPCREATE \n {*values -max 0}
append INTERPCREATE \n {@values -max 0}
punk::args::definition $INTERPCREATE
set INTERPIC {
*id punk::safe::interpIC
*leaders
@id -id ::punk::safe::interpIC
@leaders
child -type string -optional 0 -regexprefail "^-" -regexprefailmsg "" -help\
"name of the child"
}
append INTERPIC \n $optlines
append INTERPIC \n {*values -max 0}
append INTERPIC \n {@values -max 0}
punk::args::definition $INTERPIC

8
src/modules/punk/sixel-999999.0a1.0.tm

@ -142,21 +142,21 @@ tcl::namespace::eval punk::sixel {
#we will for now consume all to final ST
#TODO - sixel row/col info is dependent on terminal - pass in -terminalobject or -inoutchannels (for use with punk::console::cell_size)
punk::args::definition {
*id punk::sixel::get_info
*proc -name punk::sixel::get_info -help\
@id -id ::punk::sixel::get_info
@cmd -name punk::sixel::get_info -help\
"return a dict of information about the supplied sixelstring"
-cache -default 1 -type boolean -help\
"Cached result based on sha1 hash."
-cell_size -default "" -help\
"override terminal cell_size.
If left empty, attempt to use value from querying terminal."
*values -min 1 -max 1
@values -min 1 -max 1
sixelstring -type string -help "A single sixel image - currently only 7-bit supported"
}
variable sixelinfo_cache
set sixelinfo_cache [dict create]
proc get_info {args} {
set argd [punk::args::get_by_id punk::sixel::get_info $args]
set argd [punk::args::get_by_id ::punk::sixel::get_info $args]
set sixelstring [dict get $argd values sixelstring]
set do_cache [dict get $argd opts -cache]
set cell_size_override [dict get $argd opts -cell_size]

19
src/modules/punk/zip-999999.0a1.0.tm

@ -180,10 +180,11 @@ tcl::namespace::eval punk::zip {
#}]
set argd [punk::args::get_dict {
*proc -name punk::zip::walk
@id -id ::punk::zip::walk
@cmd -name punk::zip::walk
-excludes -default "" -help "list of glob expressions to match against files and exclude"
-subpath -default ""
*values -min 1 -max -1
@values -min 1 -max -1
base
fileglobs -default {*} -multiple 1
} $args]
@ -373,11 +374,12 @@ tcl::namespace::eval punk::zip {
#[para] The return value is the central directory record that will need to be used when finalizing the zip archive.
set argd [punk::args::get_dict {
*proc -name punk::zip::Addentry -help "Add a single file at 'path' to open channel 'zipchan'
@id -id ::punk::zip::Addentry
@cmd -name punk::zip::Addentry -help "Add a single file at 'path' to open channel 'zipchan'
return a central directory file record"
*opts
@opts
-comment -default "" -help "An optional comment specific to the added file"
*values -min 3 -max 4
@values -min 3 -max 4
zipchan -help "open file descriptor with cursor at position appropriate for writing a local file header"
base -help "base path for entries"
path -type file -help "path of file to add"
@ -525,9 +527,10 @@ tcl::namespace::eval punk::zip {
#[para] Call 'punk::zip::mkzip' with no arguments for usage display.
set argd [punk::args::get_dict {
*proc -name punk::zip::mkzip\
@id -id ::punk::zip::mkzip
@cmd -name punk::zip::mkzip\
-help "Create a zip archive in 'filename'"
*opts
@opts
-offsettype -default "archive" -choices {archive file}\
-help "zip offsets stored relative to start of entire file or relative to start of zip-archive
Only relevant if the created file has a script/runtime prefix.
@ -557,7 +560,7 @@ tcl::namespace::eval punk::zip {
it must be a parent of -directory or the same path as -directory"
-exclude -default {CVS/* */CVS/* *~ ".#*" "*/.#*"}
*values -min 1 -max -1
@values -min 1 -max -1
filename -type file -default ""\
-help "name of zipfile to create"
globs -default {*} -multiple 1\

139
src/modules/textblock-999999.0a1.0.tm

@ -123,12 +123,12 @@ tcl::namespace::eval textblock {
set choicemsg " (unavailable packages: $unavailable)"
}
set argd [punk::args::get_dict [tstr -return string {
*id textblock::use_hash
*proc -name "textblock::use_hash" -help\
@id -id ::textblock::use_hash
@cmd -name "textblock::use_hash" -help\
"Hashing algorithm to use for framecache lookup.
'none' may be slightly faster but less compact
when viewing textblock::framecache"
*values -min 0 -max 1
@values -min 0 -max 1
hash_algorithm -choices {${$choices}} -optional 1 -help\
"algorithm choice ${$choicemsg}"
}] $args]
@ -423,7 +423,6 @@ tcl::namespace::eval textblock {
}
}
}
my configure {*}$o_opts_table
#foreach {k v} $args {
# #todo - convert to literal switch using tcl::string::map so we don't have to define o_opts_table_defaults here.
@ -453,6 +452,7 @@ tcl::namespace::eval textblock {
-minheight 1\
-maxheight ""\
]
my configure {*}$o_opts_table
}
method width_algorithm {{alg ""}} {
@ -593,7 +593,7 @@ tcl::namespace::eval textblock {
tcl::dict::set o_opts_table_effective -framelimits_header $hlims
return [tcl::dict::create body $blims header $hlims]
}
method configure args {
method configure {args} {
#*** !doctools
#[call class::table [method configure] [arg args]]
#[para] get or set various table-level properties
@ -781,6 +781,14 @@ tcl::namespace::eval textblock {
}
}
}
-title {
set twidth [punk::ansi::printing_length $v]
if {[my width] < [expr {$twidth+2}]} {
set o_calculated_column_widths [list]
tcl::dict::set o_opts_table -minwidth [expr {$twidth+2}]
}
tcl::dict::set o_opts_table -title $v
}
default {
tcl::dict::set o_opts_table $k $v
}
@ -3943,14 +3951,13 @@ tcl::namespace::eval textblock {
if {$header_build eq "" && ![llength $body_blocks]} {
set header_build $nextcol_header
lappend body_blocks $nextcol_body
} else {
if {$headerheight > 0} {
set header_build [overtype::renderspace -startcolumn [expr {$padwidth + 1}] -expand_right 1 -transparent $TSUB $header_build[unset header_build] $nextcol_header[unset nextcol_header]]
}
lappend body_blocks $nextcol_body
#set body_build [textblock::join -- $body_build[unset body_build] $nextcol_body]
}
lappend body_blocks $nextcol_body
incr padwidth $bodywidth
incr colposn
}
@ -4096,8 +4103,8 @@ tcl::namespace::eval textblock {
}
punk::args::definition {
*id textblock::periodic
*proc -name textblock::periodic -help "A rudimentary periodic table
@id -id ::textblock::periodic
@cmd -name textblock::periodic -help "A rudimentary periodic table
This is primarily a test of textblock::class::table"
-return -default table\
@ -4109,13 +4116,13 @@ tcl::namespace::eval textblock {
-show_header -default "" -type boolean
-show_edge -default "" -type boolean
-forcecolour -default 0 -type boolean -help "If punk::colour is off - this enables the produced table to still be ansi coloured"
*values -min 0 -max 0
@values -min 0 -max 0
}
proc periodic {args} {
#For an impressive interactive terminal app (javascript)
# see: https://github.com/spirometaxas/periodic-table-cli
set opts [dict get [punk::args::get_by_id textblock::periodic $args] opts]
set opts [dict get [punk::args::get_by_id ::textblock::periodic $args] opts]
set opt_return [tcl::dict::get $opts -return]
if {[tcl::dict::get $opts -forcecolour]} {
set fc forcecolour
@ -4345,7 +4352,10 @@ tcl::namespace::eval textblock {
set FRAMETYPES [textblock::frametypes]
punk::args::definition [punk::lib::tstr -return string {
*id textblock::list_as_table
@id -id ::textblock::list_as_table
@cmd -name "textblock::list_as_table" -help\
"Display a list in a bordered table
"
-return -default table -choices {table tableobject}
-frametype -default "light" -type dict -choices {${$FRAMETYPES}} -choicerestricted 0\
@ -4376,13 +4386,13 @@ tcl::namespace::eval textblock {
-help "Number of table columns
Will default to 2 if not using an existing -table object"
*values -min 0 -max 1
@values -min 0 -max 1
datalist -default {} -type list -help "flat list of table cell values which will be wrapped based on -columns value"
}]
proc list_as_table {args} {
set FRAMETYPES [textblock::frametypes]
set argd [punk::args::get_by_id textblock::list_as_table $args]
set argd [punk::args::get_by_id ::textblock::list_as_table $args]
set opts [dict get $argd opts]
set datalist [dict get $argd values datalist]
@ -4894,7 +4904,7 @@ tcl::namespace::eval textblock {
#review!?
#-within_ansi means after a leading ansi code when doing left pad on all but last line
#-within_ansi means before a trailing ansi code when doing right pad on all but last line
set usage "pad ?-padchar <sp>|<character>? ?-which right|left|centre? ?-known_hasansi \"\"|<bool>? ?-known_blockwidth \"\"|<int>? ?-width auto|<int>? ?-within_ansi 1|0?"
set usage "pad block ?-padchar <sp>|<character>? ?-which right|left|centre? ?-known_hasansi \"\"|<bool>? ?-known_blockwidth \"\"|<int>? ?-width auto|<int>? ?-within_ansi 1|0?"
foreach {k v} $args {
switch -- $k {
-padchar - -which - -known_hasansi - -known_samewidth - -known_blockwidth - -width - -overflow - -within_ansi {
@ -5420,16 +5430,21 @@ tcl::namespace::eval textblock {
return [punk::lib::list_as_lines -- $outlines]
}
punk::args::definition {
@id -id ::textblock::join_basic
@cmd -name textblock::join_basic -help\
"Join blocks of text line by line but don't add padding on each line to enforce uniform width.
Already uniform blocks will join faster than textblock::join, and ragged blocks will join in a ragged manner
"
-- -type none -optional 0 -help "end of options marker -- is mandatory because joined blocks may easily conflict with flags"
-ansiresets -type any -default auto
blocks -type any -multiple 1
}
#join without regard to each line length in a block (no padding added to make each block uniform)
proc ::textblock::join_basic {args} {
#*proc -name textblock::join_basic -help "Join blocks line by line but don't add padding on each line to enforce uniform width.
# Already uniform blocks will join faster than textblock::join, and ragged blocks will join in a ragged manner
#"
set argd [punk::args::get_dict {
-- -type none -optional 0 -help "end of options marker -- is mandatory because joined blocks may easily conflict with flags"
-ansiresets -type any -default auto
blocks -type any -multiple 1
} $args]
set argd [punk::args::get_by_id ::textblock::join_basic $args]
set ansiresets [tcl::dict::get $argd opts -ansiresets]
set blocks [tcl::dict::get $argd values blocks]
@ -5466,7 +5481,7 @@ tcl::namespace::eval textblock {
return [::join $outlines \n]
}
proc ::textblock::join_basic2 {args} {
#*proc -name textblock::join_basic -help "Join blocks line by line but don't add padding on each line to enforce uniform width.
#@cmd -name textblock::join_basic -help "Join blocks line by line but don't add padding on each line to enforce uniform width.
# Already uniform blocks will join faster than textblock::join, and ragged blocks will join in a ragged manner
#"
set argd [punk::args::get_dict {
@ -6046,8 +6061,8 @@ tcl::namespace::eval textblock {
if {$bad_option || [llength $values] == 0} {
#no framedef supplied, or unrecognised opt seen
set spec [string map [list <ftlist> $::textblock::frametypes] {
*id textblock::framedef
*proc -name textblock::framedef\
@id -id ::textblock::framedef
@cmd -name textblock::framedef\
-help "Return a dict of the elements that make up a frame border.
May return a subset of available elements based on memberglob values."
@ -6058,7 +6073,7 @@ tcl::namespace::eval textblock {
-help "-boxonly true restricts results to the corner,vertical and horizontal box elements
It excludes the extra top and side join elements htlj,hlbj,vllj,vlrj."
*values -min 1
@values -min 1
frametype -choices "<ftlist>" -choiceprefix 0 -choicerestricted 0 -type dict\
-help "name from the predefined frametypes or an adhoc dictionary."
memberglob -type globstring -optional 1 -multiple 1 -choiceprefix 0 -choicerestricted 0 -choices {
@ -7438,17 +7453,17 @@ tcl::namespace::eval textblock {
set frame_cache [tcl::dict::create]
punk::args::definition {
*id textblock::frame_cache
*proc -name textblock::frame_cache -help\
@id -id ::textblock::frame_cache
@cmd -name textblock::frame_cache -help\
"Display or clear the frame cache."
-action -default {} -choices {clear} -help\
"Clear the textblock::frame_cache dictionary"
-pretty -default 1 -help\
"Use 'pdict textblock::frame_cache */*' for prettier output"
*values -min 0 -max 0
@values -min 0 -max 0
}
proc frame_cache {args} {
set argd [punk::args::get_by_id textblock::frame_cache $args]
set argd [punk::args::get_by_id ::textblock::frame_cache $args]
set action [dict get $argd opts -action]
if {$action ni [list clear ""]} {
@ -7490,13 +7505,40 @@ tcl::namespace::eval textblock {
}
variable FRAMETYPES
set FRAMETYPES [textblock::frametypes]
variable EG
set EG [a+ brightblack]
variable RST
set RST [a]
proc frame_samples {} {
set FRAMETYPELABELS [dict create]
if {[info commands ::textblock::frame] ne ""} {
foreach ft [frametypes] {
dict set FRAMETYPELABELS $ft [textblock::frame -checkargs 0 -type $ft " "]
}
}
set FRAMETYPELABELS [dict remove $FRAMETYPELABELS block2hack]
return $FRAMETYPELABELS
}
#proc EG {} "return {[a+ brightblack]}"
#make EG fetch from SGR cache so as to abide by colour off/on
proc EG {} {
a+ brightblack
}
#proc RST {} "return {\x1b\[m}"
proc RST {} {
return "\x1b\[m"
}
#catch 22 for -choicelabels - need some sort of lazy evaluation
# ${[textblock::frame_samples]}
#todo punk::args alias for centre center etc?
punk::args::definition [punk::lib::tstr -return string {
*id textblock::frame
*proc -name "textblock::frame"\
punk::args::definition -dynamic 1 {
@id -id ::textblock::frame
@cmd -name "textblock::frame"\
-help "Frame a block of text with a border."
-checkargs -default 1 -type boolean\
-help "If true do extra argument checks and
@ -7504,18 +7546,21 @@ tcl::namespace::eval textblock {
Set false for slight performance improvement."
-etabs -default 0\
-help "expanding tabs - experimental/unimplemented."
-type -default light -choices {${$FRAMETYPES}} -choicerestricted 0 -type dict\
-type -default light -choices {${[textblock::frametypes]}} -choicerestricted 0 -choicecolumns 8 -type dict\
-choicelabels {
${[textblock::frame_samples]}
}\
-help "Type of border for frame."
-boxlimits -default {hl vl tlc blc trc brc} -type list -help "Limit the border box to listed elements.
passing an empty string will result in no box, but title/subtitle will still appear if supplied.
${$EG}e.g: -frame -boxlimits {} -title things [a+ red White]my\\ncontent${$RST}"
${[textblock::EG]}e.g: -frame -boxlimits {} -title things [a+ red White]my\\ncontent${[textblock::RST]}"
-boxmap -default {} -type dict
-joins -default {} -type list
-title -default "" -type string -regexprefail {\n}\
-help "Frame title placed on topbar - no newlines.
May contain ANSI - no trailing reset required.
${$EG}e.g 1: frame -title My[a+ green]Green[a]Thing
e.g 2: frame -title [a+ red underline]MyThing${$RST}"
${[textblock::EG]}e.g 1: frame -title My[a+ green]Green[a]Thing
e.g 2: frame -title [a+ red underline]MyThing${[textblock::RST]}"
-subtitle -default "" -type string -regexprefail {\n}\
-help "Frame subtitle placed on bottombar - no newlines
May contain Ansi - no trailing reset required."
@ -7526,8 +7571,8 @@ tcl::namespace::eval textblock {
-help "Height of resulting frame including borders."
-ansiborder -default "" -type ansistring\
-help "Ansi escape sequence to set border attributes.
${$EG}e.g 1: frame -ansiborder [a+ web-red] contents
e.g 2: frame -ansiborder \"\\x1b\\\[31m\" contents${$RST}"
${[textblock::EG]}e.g 1: frame -ansiborder [a+ web-red] contents
e.g 2: frame -ansiborder \"\\x1b\\\[31m\" contents${[textblock::RST]}"
-ansibase -default "" -type ansistring\
-help "Default ANSI attributes within frame."
-blockalign -default centre -choices {left right centre}\
@ -7547,13 +7592,13 @@ tcl::namespace::eval textblock {
Frame width doesn't adapt and content may be truncated
so -width may need to be manually set to display more."
*values -min 0 -max 1
@values -min 0 -max 1
contents -default "" -type string\
-help "Frame contents - may be a block of text containing newlines and ANSI.
Text may be 'ragged' - ie unequal line-lengths.
No trailing ANSI reset required.
${$EG}e.g: frame \"[a+ blue White] \\nMy blue foreground text on\\nwhite background\\n\"${$RST}"
}]
${[textblock::EG]}e.g: frame \"[a+ blue White] \\nMy blue foreground text on\\nwhite background\\n\"${[textblock::RST]}"
}
#options before content argument - which is allowed to be absent
#frame performance (noticeable with complex tables even of modest size) is improved somewhat by frame_cache - but is still (2024) a fairly expensive operation.
@ -7638,7 +7683,7 @@ tcl::namespace::eval textblock {
#only use punk::args if check_args is true or our basic checks failed
#never need to checkargs if only one argument supplied even if it looks like an option - as it will be treated as data to frame
if {[llength $args] != 1 && (!$opts_ok || $check_args)} {
set argd [punk::args::get_by_id textblock::frame $args]
set argd [punk::args::get_by_id ::textblock::frame $args]
set opts [dict get $argd opts]
set contents [dict get $argd values contents]
}
@ -8346,18 +8391,18 @@ tcl::namespace::eval textblock {
}
}
punk::args::definition {
*id textblock::gcross
@id -id ::textblock::gcross
-max_cross_size -default 0 -type integer -help "Largest size cross to use to make up the block
Only cross sizes that divide the size of the overall block will be used.
e.g if the 'size' chosen is 19 (a prime number) - only 1 or the full size of 19 can be used as the crosses to make up the block.
Whereas for a block size of 24, -max_cross_size of 1,2,3,4,6,8,12 or 24 will work. (all divisors)
If a number chosen for -max_cross_size isn't a divisor, the largest divisor below the chosen value will be used.
"
*values -min 0 -max 1
@values -min 0 -max 1
size -default 1 -type integer
}
proc gcross {args} {
set argd [punk::args::get_by_id textblock::gcross $args]
set argd [punk::args::get_by_id ::textblock::gcross $args]
set size [dict get $argd values size]
set opts [dict get $argd opts]

27
src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/overtype-1.6.5.tm

@ -402,7 +402,10 @@ tcl::namespace::eval overtype {
set looplimit [expr {[tcl::string::length $overblock] + 10}]
}
set scheme 3
#overblock height/width isn't useful in the presence of an ansi input overlay with movements. The number of lines may bear little relationship to the output height
#lassign [blocksize $overblock] _w overblock_width _h overblock_height
set scheme 4
switch -- $scheme {
0 {
#one big chunk
@ -443,11 +446,18 @@ tcl::namespace::eval overtype {
set inputchunks [lindex [list $lflines [unset lflines]] 0]
}
4 {
set inputchunks [list]
foreach ln [split $overblock \n] {
lappend inputchunks [string cat $ln \n]
}
if {[llength $inputchunks]} {
lset inputchunks end [tcl::string::range [lindex $inputchunks end] 0 end-1]
}
}
}
#overblock height/width isn't useful in the presence of an ansi input overlay with movements. The number of lines may bear little relationship to the output height
#lassign [blocksize $overblock] _w overblock_width _h overblock_height
set replay_codes_underlay [tcl::dict::create 1 ""]
@ -495,7 +505,7 @@ tcl::namespace::eval overtype {
}
#review insert_mode. As an 'overtype' function whose main function is not interactive keystrokes - insert is secondary -
#but even if we didn't want it as an option to the function call - to process ansi adequately we need to support IRM (insertion-replacement mode) ESC [ 4 h|l
set renderargs [list -experimental $opt_experimental\
set renderopts [list -experimental $opt_experimental\
-cp437 $opt_cp437\
-info 1\
-crm_mode [tcl::dict::get $vtstate crm_mode]\
@ -510,11 +520,8 @@ tcl::namespace::eval overtype {
-expand_right $opt_expand_right\
-cursor_column $col\
-cursor_row $row\
$undertext\
$overtext\
]
set LASTCALL $renderargs
set rinfo [renderline {*}$renderargs]
set rinfo [renderline {*}$renderopts $undertext $overtext]
set instruction [tcl::dict::get $rinfo instruction]
tcl::dict::set vtstate crm_mode [tcl::dict::get $rinfo crm_mode]
@ -1237,8 +1244,8 @@ tcl::namespace::eval overtype {
append debugmsg "looplimit $looplimit reached\n"
append debugmsg "data_mode:$data_mode\n"
append debugmsg "opt_appendlines:$opt_appendlines\n"
append debugmsg "prev_row :[tcl::dict::get $LASTCALL -cursor_row]\n"
append debugmsg "prev_col :[tcl::dict::get $LASTCALL -cursor_column]\n"
append debugmsg "prev_row :[tcl::dict::get $renderopts -cursor_row]\n"
append debugmsg "prev_col :[tcl::dict::get $renderopts -cursor_column]\n"
tcl::dict::for {k v} $rinfo {
append debugmsg "${Y}$k [ansistring VIEW -lf 1 -vt 1 $v]$RST" \n
}

15
src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk-0.1.tm

@ -306,10 +306,11 @@ namespace eval punk {
#get last command result that was run through the repl
proc ::punk::get_runchunk {args} {
set argd [punk::args::get_dict {
*opts
@id -id ::punk::get_runchunk
@opts
-1 -optional 1 -type none
-2 -optional 1 -type none
*values -min 0 -max 0
@values -min 0 -max 0
} $args]
#todo - make this command run without truncating previous runchunks
set runchunks [tsv::array names repl runchunks-*]
@ -7152,8 +7153,8 @@ namespace eval punk {
}
punk::args::definition {
*id punk::inspect
*proc -name punk::inspect -help\
@id -id ::punk::inspect
@cmd -name punk::inspect -help\
"Function to display values - used pimarily in a punk pipeline.
The raw value arguments (not options) are always returned to pass
forward in the pipeline.
@ -7227,9 +7228,9 @@ namespace eval punk {
Does not affect return value."
-- -type none -help\
"End of options marker.
It is advisable to use this, as data in a pipeline may often being with -"
It is advisable to use this, as data in a pipeline may often begin with -"
*values -min 0 -max -1
@values -min 0 -max -1
arg -type string -optional 1 -multiple 1 -help\
"value to display"
}
@ -7261,7 +7262,7 @@ namespace eval punk {
foreach {k v} $flags {
if {$k ni [dict keys $defaults]} {
#error "inspect: unknown option $k. Known options: [dict keys $defaults]. If data contains flaglike elements, consider calling with end-of-opts marker. e.g inspect --"
punk::args::get_by_id punk::inspect $args
punk::args::get_by_id ::punk::inspect $args
}
}
set opts [dict merge $defaults $flags]

145
src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/ansi-0.1.1.tm

@ -134,27 +134,27 @@ tcl::namespace::eval punk::ansi::class {
}
lappend ::punk::ansi::class::PUNKARGS [list {
*id "punk::ansi::class::class_ansi render_to_input_line"
*proc -name "punk::ansi::class::class_ansi render_to_input_line" -help\
@id -id "::punk::ansi::class::class_ansi render_to_input_line"
@cmd -name "punk::ansi::class::class_ansi render_to_input_line" -help\
"render string from line 0 to line
(experimental/debug)"
-dimensions -type string -help\
"WxH where W is integer width >= 1 and H is integer heigth >= 1"
-minus -type integer -help\
"number of chars to exclude from end"
*values -min 1 -max 1
@values -min 1 -max 1
line -type indexexpression
}]
method render_to_input_line {args} {
if {[llength $args] < 1} {
puts stderr "render_to_input_line usage: ?-dimensions WxH? ?-minus charcount? x"
punk::args::get_by_id "punk::ansi::class::class_ansi render_to_input_line" $args
punk::args::get_by_id "::punk::ansi::class::class_ansi render_to_input_line" $args
}
set x [lindex $args end]
set arglist [lrange $args 0 end-1]
if {[llength $arglist] %2 != 0} {
puts stderr "render_to_input_line usage: ?-dimensions WxH? ?-minus charcount? x"
punk::args::get_by_id "punk::ansi::class::class_ansi render_to_input_line" $args
punk::args::get_by_id "::punk::ansi::class::class_ansi render_to_input_line" $args
}
set opts [tcl::dict::create\
-dimensions 80x24\
@ -167,7 +167,7 @@ tcl::namespace::eval punk::ansi::class {
}
default {
puts stderr "render_to_input_line unexpected argument '$k' usage: ?-dimensions WxH? ?-minus charcount? x"
punk::args::get_by_id "punk::ansi::class::class_ansi render_to_input_line" $args
punk::args::get_by_id "::punk::ansi::class::class_ansi render_to_input_line" $args
}
}
}
@ -588,20 +588,20 @@ tcl::namespace::eval punk::ansi {
}
lappend PUNKARGS [list -dynamic 1 {
*id punk::ansi::example
*proc -name punk::ansi::example -help "Display .ans image files in a grid that will fit in console
@id -id ::punk::ansi::example
@cmd -name punk::ansi::example -help "Display .ans image files in a grid that will fit in console
"
-colwidth -default 82 -help "Width of each column - default of 82 will fit a standard 80wide ansi image (when framed)
You can specify a narrower width to truncate images on the right side"
-folder -default "${[punk::ansi::Get_ansifolder]}" -help "Base folder for files if relative paths are used.
Defaults to <projectbase>/src/testansi - where projectbase is determined from current directory.
"
*values -min 0 -max -1
@values -min 0 -max -1
files -default {belinda.ans bot.ans flower.ans fish.ans} -multiple true -help "List of filenames - leave empty to display 4 defaults"
} ""]
proc example {args} {
set argd [punk::args::get_by_id punk::ansi::example $args]
set argd [punk::args::get_by_id ::punk::ansi::example $args]
set colwidth [dict get $argd opts -colwidth]
set ansifolder [file normalize [dict get $argd opts -folder]]
set fnames [dict get $argd values files]
@ -2355,21 +2355,21 @@ Brightblack 100 Brightred 101 Brightgreen 102 Brightyellow 103 Brightblu
#sgr_cache clear called by punk::console::ansi when set to off
#punk::args depends on punk::ansi - REVIEW
lappend PUNKARGS [list {
@id -id ::punk::ansi::sgr_cache
@cmd -name punk::ansi::sgr_cache -help\
"Convenience function to view and optionally clear the ansi character attribute cache (ansi SGR codes)
"
-action -default "" -choices "clear" -help\
"-action clear will unset the keys in the punk::ansi::sgr_cache dict
This is called automatically when setting 'colour false' in the console"
-pretty -default 1 -type boolean -help\
"use 'pdict punk::ansi::sgr_cache */%str,%ansiview' output"
@values -min 0 -max 0
}]
proc sgr_cache {args} {
set argdef {
*id punk::ansi::sgr_cache
*proc -name punk::ansi::sgr_cache -help\
"Convenience function to view and optionally clear the ansi character attribute cache (ansi SGR codes)
"
-action -default "" -choices "clear" -help\
"-action clear will unset the keys in the punk::ansi::sgr_cache dict
This is called automatically when setting 'colour false' in the console"
-pretty -default 1 -type boolean -help\
"use 'pdict punk::ansi::sgr_cache */%str,%ansiview' output"
*values -min 0 -max 0
}
set argd [punk::args::get_dict $argdef $args]
set argd [punk::args::get_by_id ::punk::ansi::sgr_cache $args]
set action [dict get $argd opts -action]
set pretty [dict get $argd opts -pretty]
@ -2412,34 +2412,7 @@ Brightblack 100 Brightred 101 Brightgreen 102 Brightyellow 103 Brightblu
return [join $lines \n]
}
lappend PUNKARGS [list {
*id punk::ansi::a+
*proc -name "punk::ansi::a+" -help\
"Returns an ANSI sgr escape sequence based on the list of supplied codes.
Unlike punk::ansi::a - it is not prefixed with an ANSI reset.
"
*values -min 0 -max -1
} [string map [list <choices> [dict keys $SGR_map]] {
code -type string -optional 1 -multiple 1 -choices {<choices>} -choiceprefix 0 -choicerestricted 0 -help\
"SGR code from the list below, or an integer corresponding to the code e.g 31 = red.
A leading capital letter indicates a codename applies to the background colour.
Other accepted codes are:
term-<int> Term-<int> foreground/background where int is 0-255 terminal color
term-<termcolour> Term-<termcolour> foreground/background
rgb-<r>-<g>-<b> Rgb-<r>-<g>-<b> foreground/background where <r> <g> <b> are the
0-255 int values for red, green and blue.
rgb#<hexcode> Rgb#<hexcode> where <hexcode> is a 6 char hex colour e.g rgb#C71585
web-<webcolour> Web-<webcolour>
The acceptable values for <termcolour> and <webcolour> can be queried using
punk::ansi::a? term
and
punk::ansi::a? web
Example to set foreground red and background cyan followed by a reset:
set str \"[a+ red Cyan]sample text[a]\"
"
}]]
#PUNKARGS doc performed below, after we create the proc
proc a+ {args} {
#*** !doctools
#[call [fun a+] [opt {ansicode...}]]
@ -2907,6 +2880,41 @@ Brightblack 100 Brightred 101 Brightgreen 102 Brightyellow 103 Brightblu
return $result
}
set SGR_samples [dict create]
foreach k [dict keys $SGR_map] {
dict set SGR_samples $k "[punk::ansi::a+ $k]sample\x1b\[m"
}
lappend PUNKARGS [list {
@id -id ::punk::ansi::a+
@cmd -name "punk::ansi::a+" -help\
"Returns an ANSI sgr escape sequence based on the list of supplied codes.
Unlike punk::ansi::a - it is not prefixed with an ANSI reset.
"
@values -min 0 -max -1
} [string map [list <choices> [dict keys $SGR_map] <choicelabels> $SGR_samples] {
code -type string -optional 1 -multiple 1 -choices {<choices>}\
-choicelabels {<choicelabels>}\
-choicecolumns 5 -choiceprefix 0 -choicerestricted 0 -help\
"SGR code from the list below, or an integer corresponding to the code e.g 31 = red.
A leading capital letter indicates a codename applies to the background colour.
Other accepted codes are:
term-<int> Term-<int> foreground/background where int is 0-255 terminal color
term-<termcolour> Term-<termcolour> foreground/background
rgb-<r>-<g>-<b> Rgb-<r>-<g>-<b> foreground/background where <r> <g> <b> are the
0-255 int values for red, green and blue.
rgb#<hexcode> Rgb#<hexcode> where <hexcode> is a 6 char hex colour e.g rgb#C71585
web-<webcolour> Web-<webcolour>
The acceptable values for <termcolour> and <webcolour> can be queried using
punk::ansi::a? term
and
punk::ansi::a? web
Example to set foreground red and background cyan followed by a reset:
set str \"[a+ red Cyan]sample text[a]\"
"
}]]
proc a {args} {
#*** !doctools
#[call [fun a] [opt {ansicode...}]]
@ -4281,6 +4289,7 @@ tcl::namespace::eval punk::ansi {
}
4 {
#REVIEW - merging extended (e.g 4:4) underline attributes suppresses all other SGR attributes on at least some terminals which don't support extended underlines
#e.g hyper on windows
if {[llength $paramsplit] == 1} {
tcl::dict::set codestate underline 4
} else {
@ -4634,6 +4643,8 @@ tcl::namespace::eval punk::ansi::ta {
#[list_begin definitions]
tcl::namespace::path ::punk::ansi
variable PUNKARGS
#handle both 7-bit and 8-bit csi
#review - does codepage affect this? e.g ebcdic has 8bit csi in different position
@ -4706,15 +4717,31 @@ tcl::namespace::eval punk::ansi::ta {
#variable re_ansi_split "${re_csi_code}|${re_esc_osc1}|${re_esc_osc2}|${re_esc_osc3}|${re_standalones}|${re_ST}|${re_g0_open}|${re_g0_close}"
set re_ansi_split $re_ansi_detect
lappend PUNKARGS [list -dynamic 0 {
@id -id ::punk::ansi::ta::detect
@cmd -name punk::ansi::ta::detect -help\
"Return a boolean indicating whether Ansi codes were detected in text.
Important caveat:
When text is a tcl list made from splitting (or lappending) some ansi string
- individual elements may be braced or have certain chars escaped.
(one example is if a list element contains an unbalanced brace)
This can cause square brackets that form part of the ansi to be backslash escaped
- and the function can fail to match it as an Ansi code.
"
@values -min 1
text -type string
} ]
#*** !doctools
#[call [fun detect] [arg text]]
#[para]Return a boolean indicating whether Ansi codes were detected in text
#[para]Important caveat:
#[para] When text is a tcl list made from splitting (or lappending) some ansi string - individual elements may be braced or have certain chars escaped. (one example is if a list element contains an unbalanced brace)
#[para] This can cause square brackets that form part of the ansi being backslash escaped - and the regexp can fail to match
#detect any ansi escapes
#review - only detect 'complete' codes - or just use the opening escapes for performance?
proc detect {text} [string map [list <re> [list $re_ansi_detect]] {
#*** !doctools
#[call [fun detect] [arg text]]
#[para]Return a boolean indicating whether Ansi codes were detected in text
#[para]Important caveat:
#[para] When text is a tcl list made from splitting (or lappending) some ansi string - individual elements may be braced or have certain chars escaped. (one example is if a list element contains an unbalanced brace)
#[para] This can cause square brackets that form part of the ansi being backslash escaped - and the regexp can fail to match
regexp <re> $text
}]
@ -7405,7 +7432,7 @@ if {![info exists ::punk::args::register::NAMESPACES]} {
set NAMESPACES [list]
}
}
lappend ::punk::args::register::NAMESPACES ::punk::ansi ::punk::ansi::class
lappend ::punk::args::register::NAMESPACES ::punk::ansi ::punk::ansi::class ::punk::ansi::ta
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
## Ready

1114
src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/args-0.1.0.tm

File diff suppressed because it is too large Load Diff

15
src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/cap/handlers/templates-0.1.0.tm

@ -254,8 +254,9 @@ namespace eval punk::cap::handlers::templates {
}
method folders {args} {
set argd [punk::args::get_dict {
@id -id "::punk::cap::handlers::templates::class::api folders"
-startdir -default ""
*values -max 0
@values -max 0
} $args]
set opts [dict get $argd opts]
@ -471,10 +472,11 @@ namespace eval punk::cap::handlers::templates {
}
method get_itemdict_projectlayouts {args} {
set argd [punk::args::get_dict {
*opts -anyopts 1
@id -id "::punk::cap::handlers::templates::class::api get_itemdict_projectlayouts"
@opts -anyopts 1
#peek -startdir while allowing all other opts/vals to be verified down-the-line instead of here
-startdir -default ""
*values -maxvalues -1
@values -maxvalues -1
} $args]
set opt_startdir [dict get $argd opts -startdir]
@ -648,14 +650,15 @@ namespace eval punk::cap::handlers::templates {
#and a name determining command -command_get_item_name
method _get_itemdict {args} {
set argd [punk::args::get_dict {
*proc -name _get_itemdict
*opts -anyopts 0
@id -id "::punk::cap::handlers::templates::class::api _get_itemdict"
@cmd -name _get_itemdict
@opts -anyopts 0
-startdir -default ""
-templatefolder_subdir -optional 0
-command_get_items_from_base -optional 0
-command_get_item_name -optional 0
-not -default "" -multiple 1
*values -maxvalues -1
@values -maxvalues -1
globsearches -default * -multiple 1
} $args]
set opts [dict get $argd opts]

12
src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/config-0.1.tm

@ -362,10 +362,10 @@ tcl::namespace::eval punk::config {
proc configure {args} {
set argdef {
*id punk::config::configure
*proc -name punk::config::configure -help\
@id -id ::punk::config::configure
@cmd -name punk::config::configure -help\
"UNIMPLEMENTED"
*values -min 1 -max 1
@values -min 1 -max 1
whichconfig -type string -choices {startup running stop}
}
set argd [punk::args::get_dict $argdef $args]
@ -388,15 +388,15 @@ tcl::namespace::eval punk::config {
#This is to allow partial configs to be loaded to running, whereas a save of running to any target is always a complete configuration
proc copy {args} {
set argdef {
*id punk::config::copy
*proc -name punk::config::copy -help\
@id -id ::punk::config::copy
@cmd -name punk::config::copy -help\
"Copy a partial or full configuration from one config to another
If a target config has additional settings, then the source config can be considered to be partial with regards to the target.
"
-type -default "" -choices {replace merge} -help\
"Defaults to merge when target is running-config
Defaults to replace when source is running-config"
*values -min 2 -max 2
@values -min 2 -max 2
fromconfig -help\
"running or startup or file name (not fully implemented)"
toconfig -help\

8
src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/console-0.1.1.tm

@ -875,7 +875,7 @@ namespace eval punk::console {
}
}
punk::args::set_alias punk::console::code_a+ punk::ansi::a+
punk::args::set_alias ::punk::console::code_a+ ::punk::ansi::a+
proc code_a+ {args} {
variable ansi_wanted
if {$ansi_wanted <= 0} {
@ -1187,14 +1187,14 @@ namespace eval punk::console {
#todo - change -inoutchannels to -terminalobject with prebuilt default
punk::args::definition {
*id punk::console::cell_size
@id -id ::punk::console::cell_size
-inoutchannels -default {stdin stdout} -type list
*values -min 0 -max 1
@values -min 0 -max 1
newsize -default "" -help\
"character cell pixel dimensions WxH"
}
proc cell_size {args} {
set argd [punk::args::get_by_id punk::console::cell_size $args]
set argd [punk::args::get_by_id ::punk::console::cell_size $args]
set inoutchannels [dict get $argd opts -inoutchannels]
set newsize [dict get $argd values newsize]

6
src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/du-0.1.0.tm

@ -563,9 +563,10 @@ namespace eval punk::du {
variable win_reparse_tags_by_int
set argd [punk::args::get_dict {
@id -id ::punk::du::lib::Get_attributes_from_iteminfo
-debug -default 0 -help "set 1 for raw data on -debugchannel (default stderr)"
-debugchannel -default stderr -help "channel to write debug output, or none to append to output"
*values -min 1 -max 1
@values -min 1 -max 1
iteminfo -help "iteminfo dict as set by 'twapi::find_file_next <iterator> iteminfo'"
} $args]
set opts [dict get $argd opts]
@ -621,10 +622,11 @@ namespace eval punk::du {
proc attributes_twapi {args} {
set argd [punk::args::get_dict {
@id -id ::punk::du::lib::attributes_twapi
-debug -default 0 -help "set 1 for raw data on -debugchannel (default stderr)"
-debugchannel -default stderr -help "channel to write debug output, or none to append to output"
-detail -default basic -choices {basic full} -help "full returns also the altname/shortname field"
*values -min 1 -max 1
@values -min 1 -max 1
path -help "path to file or folder for which to retrieve attributes"
} $args]
set opts [dict get $argd opts]

8
src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/fileline-0.1.0.tm

@ -1252,14 +1252,14 @@ namespace eval punk::fileline {
#[list_begin definitions]
punk::args::definition {
*id punk::fileline::get_textinfo
*proc -name punk::fileline::get_textinfo -help\
@id -id ::punk::fileline::get_textinfo
@cmd -name punk::fileline::get_textinfo -help\
"return: textinfo object instance"
-file -default {} -type existingfile
-translation -default iso8859-1
-encoding -default "\uFFFF"
-includebom -default 0
*values -min 0 -max 1
@values -min 0 -max 1
}
proc get_textinfo {args} {
#*** !doctools
@ -1276,7 +1276,7 @@ namespace eval punk::fileline {
#[para]Currently only utf-8, utf-16* and utf-32* are properly supported even though the other BOMs are detected, reported via get_bomid, and stripped from the data.
#[para]GB18030 falls back to cp936/gbk (unless a gb18030 encoding has been installed). Use -encoding iso8859-1 if this isn't suitable and you need to do your own processing of the bytes.
lassign [dict values [punk::args::get_by_id punk::fileline::get_textinfo $args]] opts values
lassign [dict values [punk::args::get_by_id ::punk::fileline::get_textinfo $args]] opts values
# -- --- --- ---
set opt_file [dict get $opts -file]
set opt_translation [dict get $opts -translation]

26
src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/lib-0.1.1.tm

@ -1009,13 +1009,13 @@ namespace eval punk::lib {
set sep " [punk::ansi::a+ Green]=[punk::ansi::a] "
}
set argspec [string map [list %sep% $sep] {
*id punk::lib::pdict
*proc -name pdict -help\
@id -id ::punk::lib::pdict
@cmd -name pdict -help\
"Print dict keys,values to channel
The pdict function operates on variable names - passing the value to the showdict function which operates on values
(see also showdict)"
*opts -any 1
@opts -any 1
#default separator to provide similarity to tcl's parray function
-separator -default "%sep%"
@ -1023,7 +1023,7 @@ namespace eval punk::lib {
-substructure -default {}
-channel -default stdout -help "existing channel - or 'none' to return as string"
*values -min 1 -max -1
@values -min 1 -max -1
dictvar -type string -help "name of variable. Can be a dict, list or array"
@ -1095,14 +1095,16 @@ namespace eval punk::lib {
package require textblock
set argd [punk::args::get_dict [string map [list %sep% $sep %sep_mismatch% $sep_mismatch] {
*id punk::lib::showdict
*proc -name punk::lib::showdict -help "display dictionary keys and values"
@id -id ::punk::lib::showdict
@cmd -name punk::lib::showdict -help "display dictionary keys and values"
#todo - table tableobject
-return -default "tailtohead" -choices {tailtohead sidebyside}
-channel -default none
-trimright -default 1 -type boolean -help "Trim whitespace off rhs of each line.
This can help prevent a single long line that wraps in terminal from making every line wrap due to long rhs padding
"
-trimright -default 1 -type boolean -help\
"Trim whitespace off rhs of each line.
This can help prevent a single long line that wraps in terminal from making
every line wrap due to long rhs padding.
"
-separator -default {%sep%} -help "Separator column between keys and values"
-separator_mismatch -default {%sep_mismatch%} -help "Separator to use when patterns mismatch"
-roottype -default "dict" -help "list,dict,string"
@ -1114,7 +1116,7 @@ namespace eval punk::lib {
-keysortdirection -default increasing -choices {increasing decreasing}
-debug -default 0 -type boolean -help\
"When enabled, produces some rudimentary debug output on stderr"
*values -min 1 -max -1
@values -min 1 -max -1
dictvalue -type list -help "dict or list value"
patterns -default "*" -type string -multiple 1 -help "key or key glob pattern"
}] $args]
@ -2816,7 +2818,7 @@ namespace eval punk::lib {
#eat or own dogfood version - shows the implementation is simpler - but unfortunately not suitable for a simple function like this which should be as fast as possible?
lassign [tcl::dict::values [punk::args::get_dict {
-joinchar -default \n
*values -min 1 -max 1
@values -min 1 -max 1
} $args]] leaders opts values
puts "opts:$opts"
puts "values:$values"
@ -2857,7 +2859,7 @@ namespace eval punk::lib {
#we don't have to decide what is an opt vs a value
#even if the caller provides the argument -block without a value the next function's validation will report a reasonable error because there is now nothing in $values (consumed by -block)
lassign [tcl::dict::values [punk::args::get_dict {
*opts -any 1
@opts -any 1
-block -default {}
} $args]] leaderdict opts valuedict
tailcall linelist {*}$opts {*}[tcl::dict::values $valuedict]

3
src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/mix/commandset/doc-0.1.0.tm

@ -168,9 +168,10 @@ namespace eval punk::mix::commandset::doc {
}
proc validate {args} {
set argd [punk::args::get_dict {
@id -id ::punk::mix::commandset::doc::validate
-- -type none -optional 1 -help "end of options marker --"
-individual -type boolean -default 1
*values -min 0 -max -1
@values -min 0 -max -1
patterns -default {*.man} -type any -multiple 1
} $args]
set opt_individual [tcl::dict::get $argd opts -individual]

6
src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/mix/commandset/layout-0.1.0.tm

@ -34,7 +34,8 @@ namespace eval punk::mix::commandset::layout {
#per layout functions
proc files {{layout ""}} {
set argd [punk::args::get_dict {
*values -min 1 -max 1
@id -id ::punk::mix::commandset::layout::files
@values -min 1 -max 1
layout -type string -minsize 1
} [list $layout]]
@ -88,7 +89,8 @@ namespace eval punk::mix::commandset::layout {
proc _default {args} {
punk::args::get_dict [subst {
*proc -name ::punk::mix::commandset::layout::collection::_default
@id -id ::punk::mix::commandset::layout::collection::_default
@cmd -name ::punk::mix::commandset::layout::collection::_default
-startdir -type string
-not -type string -multiple 1
globsearches -default * -multiple 1

18
src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/mix/commandset/loadedlib-0.1.0.tm

@ -27,20 +27,24 @@ namespace eval punk::mix::commandset::loadedlib {
namespace export *
#search automatically wrapped in * * - can contain inner * ? globs
punk::args::definition {
*id punk::mix::commandset::loadedlib::search
*proc -name "punk::mix::commandset::loadedlib search" -help "search all Tcl libraries available to your local interpreter"
@id -id ::punk::mix::commandset::loadedlib::search
@cmd -name "punk::mix::commandset::loadedlib search" -help "search all Tcl libraries available to your local interpreter"
-return -type string -default table -choices {table tableobject list lines}
-present -type integer -default 2 -choices {0 1 2} -choicelabels {absent present both} -help\
"(unimplemented) Display only those that are 0:absent 1:present 2:both"
-highlight -type boolean -default 1 -help "Highlight which version is present with ansi underline and colour"
"(unimplemented) Display only those that are 0:absent 1:present 2:either"
-highlight -type boolean -default 1 -help\
"Highlight which version is present with ansi underline and colour"
-refresh -default 0 -type boolean -help "Re-scan the tm and library folders"
searchstrings -default * -multiple 1 -help\
"Names to search for, may contain glob chars (* ?) e.g *lib*
If no glob chars are explicitly specified, the searchstring will be wrapped with star globs.
eg name -> *name*"
eg name -> *name*
To search for an exact name prefix it with =
e.g =name -> name
"
}
proc search {args} {
set argd [punk::args::get_by_id punk::mix::commandset::loadedlib::search $args]
set argd [punk::args::get_by_id ::punk::mix::commandset::loadedlib::search $args]
set searchstrings [dict get $argd values searchstrings]
set opts [dict get $argd opts]
set opt_return [dict get $opts -return]
@ -55,7 +59,7 @@ namespace eval punk::mix::commandset::loadedlib {
set packages [package names]
set matches [list]
foreach search $searchstrings {
if {[regexp {[?*]} $search]} {
if {[regexp {[?*\[]} $search]} {
#caller has specified specific glob pattern - use it
#todo - respect supplied case only if uppers present? require another flag?
lappend matches {*}[lsearch -all -inline -nocase $packages $search]

13
src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/mix/commandset/module-0.1.0.tm

@ -123,10 +123,11 @@ namespace eval punk::mix::commandset::module {
#return all module templates with repeated ones suffixed with .2 .3 etc
proc templates_dict {args} {
set argspec {
*proc -name templates_dict -help "Templates from module and project paths"
@id -id ::punk::mix::commandset::module::templates_dict
@cmd -name templates_dict -help "Templates from module and project paths"
-startdir -default "" -help "Project folder used in addition to module paths"
-not -default "" -multiple 1
*values
@values
globsearches -default * -multiple 1
}
set argd [punk::args::get_dict $argspec $args]
@ -141,8 +142,8 @@ namespace eval punk::mix::commandset::module {
set moduletypes [punk::mix::cli::lib::module_types]
punk::args::definition [subst {
*id punk::mix::commandset::module::new
*proc -name "punk::mix::commandset::module::new" -help\
@id -id ::punk::mix::commandset::module::new
@cmd -name "punk::mix::commandset::module::new" -help\
"Create a new module file in the appropriate folder within src/modules.
If the name given in the module argument is namespaced,
the necessary subfolder(s) will be used or created."
@ -160,7 +161,7 @@ namespace eval punk::mix::commandset::module {
If false (default) an error will be raised if there is a conflict."
-quiet -default 0 -type boolean -help\
"Suppress information messages on stdout"
*values -min 1 -max 1
@values -min 1 -max 1
module -type string -help\
"Name of module, possibly including a namespace and/or version number
e.g mynamespace::mymodule-1.0"
@ -168,7 +169,7 @@ namespace eval punk::mix::commandset::module {
proc new {args} {
set year [clock format [clock seconds] -format %Y]
# use \uFFFD because unicode replacement char should consistently render as 1 wide
set argd [punk::args::get_by_id punk::mix::commandset::module::new $args]
set argd [punk::args::get_by_id ::punk::mix::commandset::module::new $args]
lassign [dict values $argd] leaders opts values received
set module [dict get $values module]

8
src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/mix/commandset/scriptwrap-0.1.0.tm

@ -1262,15 +1262,15 @@ namespace eval punk::mix::commandset::scriptwrap {
# [list_begin arguments]
# [arg_def string args] name-value pairs -scriptpath <path>
# [list_end]
*id punk::mix::commandset::scriptwrap
*proc -name punk::mix::commandset::get_wrapper_folders
@id -id ::punk::mix::commandset::scriptwrap
@cmd -name punk::mix::commandset::get_wrapper_folders
*opts -anyopts 0
@opts -anyopts 0
-scriptpath -default "" -type directory\
-help ""
#todo -help folder within a punk.templates provided area???
*values -minvalues 0 -maxvalues 0
@values -minvalues 0 -maxvalues 0
} $args]
# -- --- --- --- --- --- --- --- ---

34
src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/nav/fs-0.1.0.tm

@ -636,13 +636,14 @@ tcl::namespace::eval punk::nav::fs {
# c:/repo/jn/punk/../../blah
#dirfiles assumes we don't have glob chars in the filenames or paths - dirfiles_dict can be called directly with explicit -tailglob in the rare case that assumption doesn't hold
# dirfiles will test last segment (tail) of supplied searchspecs for fileness vs folderness (when no globchars present in tail) so that it can pass the appropriate flags downstream
punk::args::definition {
@id -id ::punk::nav::fs::dirfiles
-stripbase -default 1 -type boolean
-formatsizes -default 1 -type boolean -help "Format file size numbers for clarity"
@values -min 0 -max -1
}
proc dirfiles {args} {
set argspecs {
-stripbase -default 1 -type boolean
-formatsizes -default 1 -type boolean -help "Format file size numbers for clarity"
*values -min 0 -max -1
}
set argd [punk::args::get_dict $argspecs $args]
set argd [punk::args::get_by_id ::punk::nav::fs::dirfiles $args]
lassign [dict values $argd] leaders opts values_dict
set opt_stripbase [dict get $opts -stripbase]
@ -726,14 +727,14 @@ tcl::namespace::eval punk::nav::fs {
# -searchbase is always passed through - and is only used to construct a location path if a relative searchspec was supplied
proc dirfiles_dict {args} {
set argspecs {
*id punk::nav::fs::dirfiles_dict
*opts -any 0
@id -id ::punk::nav::fs::dirfiles_dict
@opts -any 0
-searchbase -default ""
-tailglob -default "\uFFFF"
#with_sizes & with_times must accept 0|1|f|d|l where f = files d = dirs l = links (punk::du)
-with_sizes -default "\uFFFF" -type string
-with_times -default "\uFFFF" -type string
*values -min 0 -max -1 -type string
@values -min 0 -max -1 -type string
}
set argd [punk::args::get_dict $argspecs $args]
lassign [dict values $argd] leaders opts vals
@ -991,16 +992,17 @@ tcl::namespace::eval punk::nav::fs {
return [dict merge $listing $updated]
}
punk::args::definition {
@id -id ::punk::nav::fs::dirfiles_dict_as_lines
-stripbase -default 0 -type boolean
-formatsizes -default 1 -type boolean
@values -min 1 -max -1 -type dict
}
#todo - color key via repl-telemetry? help command? documentation? or add tag columns as done in namespace listing?
proc dirfiles_dict_as_lines {args} {
package require overtype
set argspecs {
-stripbase -default 0 -type boolean
-formatsizes -default 1 -type boolean
*values -min 1 -max -1 -type dict
}
set argd [punk::args::get_dict $argspecs $args]
set argd [punk::args::get_by_id ::punk::nav::fs::dirfiles_dict_as_lines $args]
lassign [dict values $argd] leaders opts vals
set list_of_dicts [dict values $vals]

421
src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/ns-0.1.0.tm

@ -1608,7 +1608,7 @@ tcl::namespace::eval punk::ns {
if {$word1 eq "punk::mix::base::_cli"} {
#special case for punk deck - REVIEW
#e.g punk::mix::base::_cli -extension ::punk::mix::cli
set fq [lindex $tgt end]
set fq [lindex $tgt end] ;#todo - explicitly get -extension argval in case _cli extended with other options
} else {
#todo - alias may have prefilled some leading args - so usage report should reflect that???
#(currying)
@ -1618,7 +1618,8 @@ tcl::namespace::eval punk::ns {
set fq [nsjoin $location $c]
}
if {$has_punkargs} {
set id [string trimleft $fq :]
#set id [string trimleft $fq :]
set id $fq
if {[::punk::args::id_exists $id]} {
lappend usageinfo $c
} else {
@ -1892,110 +1893,188 @@ tcl::namespace::eval punk::ns {
}
} |data@@ok/result> {lmap v $data {punk::ns::nstail $v}} |> lsort |> {join $data \n} <ns/0|
proc ensemble_subcommands {origin} {
set ensembleinfo [namespace ensemble configure $origin]
set prefixes [dict get $ensembleinfo -prefixes]
set map [dict get $ensembleinfo -map]
set ns [dict get $ensembleinfo -namespace]
#review - we can have a combination of commands from -map as well as those exported from -namespace
# if and only if -subcommands is specified
set subcommand_dict [dict create]
set commands [list]
set nscommands [list]
if {[llength [dict get $ensembleinfo -subcommands]]} {
#set exportspecs [namespace eval $ns {namespace export}]
#foreach pat $exportspecs {
# lappend nscommands {*}[info commands ${ns}::$pat]
#}
#when using -subcommands, even unexported commands are available
set nscommands [info commands ${ns}::*]
foreach sub [dict get $ensembleinfo -subcommands] {
if {[dict exists $map $sub]} {
#-map takes precence over same name exported from -namespace
dict set subcommand_dict $sub [dict get $map $sub]
} elseif {"${ns}::$sub" in $nscommands} {
dict set subcommand_dict $sub ${ns}::$sub
} else {
#subcommand probably supplied via -unknown handler?
dict set subcommand_dict $sub ""
}
}
} else {
if {[dict size $map]} {
set subcommand_dict $map
} else {
set exportspecs [namespace eval $ns {namespace export}]
foreach pat $exportspecs {
lappend nscommands {*}[info commands ${ns}::$pat]
}
foreach fqc $nscommands {
dict set subcommand_dict [namespace tail $fqc] $fqc
}
}
}
return $subcommand_dict
}
#todo - -cache or -refresh to configure whether we introspect ensembles/objects each time?
# - as this is interactive generally introspection should be ok at the top level
# but if we need to go down multiple levels of subcommands generating/testing prefixes - could be an issue ??
punk::args::definition {
*id punk::ns::arginfo
*proc -name punk::ns::arginfo -help\
"Show usage info for a command"
@id -id ::punk::ns::arginfo
@cmd -name punk::ns::arginfo -help\
"Show usage info for a command.
It supports the following:
1) Procedures or builtins for which a punk::args definition has
been loaded.
2) tepam procedures (returns string form only)
3) ensemble commands - auto-generated unless documented via punk::args
(subcommands will show with an indicator if they are
explicitly documented or are themselves ensembles)
4) tcl::oo objects - auto-gnerated unless documented via punk::args
5) dereferencing of aliases to find underlying command
(will not work with some renamed aliases)
Note that native commands commands not explicitly documented will
generally produce no useful info. For example sqlite3 dbcmd objects
could theoretically be documented - but as 'info cmdtype' just shows
'native' they can't (?) be identified as belonging to sqlite3 without
calling them. arginfo deliberately avoids calling commands to elicit
usage information as this is inherently risky. (could create a file,
exit the interp etc)
"
-return -type string -default table -choices {string table tableobject}
-- -type none -help\
"End of options marker
Use this if the command to view begins with a -"
*values -min 1
@values -min 1
commandpath -help\
"command (may be alias or ensemble)"
"command (may be alias, ensemble, tcl::oo object, tepam proc etc)"
subcommand -optional 1 -multiple 1 -default {} -help\
"subcommand if commandpath is an ensemble.
Multiple subcommands can be supplied if ensembles are further nested"
}
proc arginfo {args} {
lassign [dict values [punk::args::get_by_id punk::ns::arginfo $args]] leaders opts values received
set commandpath [dict get $values commandpath]
set commandargs [dict get $values subcommand]
lassign [dict values [punk::args::get_by_id ::punk::ns::arginfo $args]] leaders opts values received
set querycommand [dict get $values commandpath]
set queryargs [dict get $values subcommand]
punk::args::update_definitions ;#ensure any packages that register PUNKARGS have been loaded
#todo - similar to corp? review corp resolution process
#should handle lazy loaded commands (via ::auto_index) that are not yet present but may be documented
if {[string match ::* $commandpath]} {
set targetns [nsprefix $commandpath]
set name [nstail $commandpath]
#don't use 'info commands $commandpath' - or Tcl will use 'namespace path' resolution to find command in another ns or in global
if {[string match ::* $querycommand]} {
set targetns [nsprefix $querycommand]
set name [nstail $querycommand]
#don't use 'info commands $querycommand' - or Tcl will use 'namespace path' resolution to find command in another ns or in global
#when arginfo given a fully qualified path - we only want an answer for that exact command
set nscommands [info commands ${targetns}::*]
if {[lsearch -exact $nscommands $commandpath] >= 0} {
if {[lsearch -exact $nscommands $querycommand] >= 0} {
#use nseval_ifexists to avoid creating intermediate namespaces for bogus paths
if {[catch {
set origin [nseval_ifexists $targetns [list ::namespace origin $name]]
set resolved [nseval_ifexists $targetns [list ::namespace which $name]]
}]} {
set origin $commandpath
set resolved $commandpath
set origin $querycommand
set resolved $querycommand
}
} else {
#fully qualified command specified but doesn't exist
set origin $commandpath
set resolved $commandpath
set origin $querycommand
set resolved $querycommand
}
} else {
set thispath [uplevel 1 [list ::nsthis $commandpath]]
set targetns [nsprefix $thispath]
set name [nstail $thispath]
set targetparts [nsparts $targetns]
if {[lsearch $targetparts :*] >=0} {
#weird ns
set valid_ns [nsexists $targetns]
#relative comandpath
if {[string match (autodef)* $querycommand]} {
#pass through - should be found with id lookup
set origin $querycommand
set resolved $querycommand
} else {
set valid_ns [namespace exists $targetns]
}
if {$valid_ns} {
if {[catch {
set origin [nseval_ifexists $targetns [list ::namespace origin $name]]
set resolved [nseval_ifexists $targetns [list ::namespace which $name]]
}]} {
set thiscmd [nsjoin $targetns $name]
#relative commandpath specified - but Tcl didn't find a match in namespace path
#assume global (todo - look for namespace match in auto_index first ?)
set origin ::$name
set resolved ::$name
set thispath [uplevel 1 [list ::nsthis $querycommand]]
set targetns [nsprefix $thispath]
set name [nstail $thispath]
set targetparts [nsparts $targetns]
if {[lsearch $targetparts :*] >=0} {
#weird ns
set valid_ns [nsexists $targetns]
} else {
set valid_ns [namespace exists $targetns]
}
if {$valid_ns} {
if {[catch {
set origin [nseval_ifexists $targetns [list ::namespace origin $name]]
set resolved [nseval_ifexists $targetns [list ::namespace which $name]]
}]} {
set thiscmd [nsjoin $targetns $name]
#relative querycommand specified - but Tcl didn't find a match in namespace path
#assume global (todo - look for namespace match in auto_index first ?)
set origin ::$name
set resolved ::$name
}
} else {
#namespace as relative to current doesn't seem to exist
#Tcl would also attempt to resolve as global
set numvals [expr {[llength $queryargs]+1}]
#puts "THROWBACK: namespace eval :: [list punk::ns::arginfo {*}[lrange $args 0 end-$numvals] $querycommand {*}$queryargs]"
return [namespace eval :: [list punk::ns::arginfo {*}[lrange $args 0 end-$numvals] $querycommand {*}$queryargs]]
#set origin $querycommand
#set resolved $querycommand
}
} else {
#namespace doesn't seem to exist - but there still could be documentation for lazy loaded ns and command
set origin $commandpath
set resolved $commandpath
}
}
#set thiscmd [nsjoin $targetns $name]
#if {[info commands $thiscmd] eq ""} {
# set origin $thiscmd
# set resolved $thiscmd
#} else {
# set origin [nseval $targetns [list ::namespace origin $name]]
# set resolved [nseval $targetns [list ::namespace which $name]]
#}
}
}
#ns::cmdtype only detects alias type on 8.7+?
set initial_cmdtype [punk::ns::cmdtype $origin]
switch -- $initial_cmdtype {
na - alias {
#REVIEW - alias entry doesn't necessarily match command!
#considure using which_alias (wiki)
#consider using which_alias (wiki)
set tgt [interp alias "" $origin]
if {$tgt eq ""} {
set tgt [interp alias "" [string trimleft $origin :]]
}
#first word of tgt may be namespace relative or absolute
if {$tgt ne ""} {
set word1 [lindex $tgt 0]
if {$word1 eq "punk::mix::base::_cli"} {
#special case for punk deck - REVIEW
#e.g punk::mix::base::_cli -extension ::punk::mix::cli
set fq [lindex $tgt end]
set targetword [lindex $tgt end]
} else {
#todo - alias may have prefilled some leading args - so usage report should reflect that???
#(possible curried arguments)
#review - curried arguments could be for ensembles!
set fq $word1
set targetword $word1
set numvals [expr {[llength $queryargs]+1}]
#puts "ALIAS THROWBACK: namespace eval :: [list punk::ns::arginfo {*}[lrange $args 0 end-$numvals] $targetword {*}[lrange $tgt 1 end] {*}$queryargs]"
return [namespace eval :: [list punk::ns::arginfo {*}[lrange $args 0 end-$numvals] $targetword {*}[lrange $tgt 1 end] {*}$queryargs]]
}
set origin $fq
set origin $targetword
#retest cmdtype on modified origin
set cmdtype [punk::ns::cmdtype $origin]
} else {
@ -2013,6 +2092,83 @@ tcl::namespace::eval punk::ns {
}
}
set id $origin
if {[info commands ::punk::args::id_exists] ne ""} {
#cycle through longest first checking for id matching ::cmd ?subcmd..?
#REVIEW - this doesn't cater for prefix callable subcommands!
set argcopy $queryargs
while {[llength $argcopy]} {
if {[punk::args::id_exists [list $id {*}$argcopy]]} {
return [uplevel 1 [list punk::args::usage {*}$opts [list $id {*}$argcopy]]]
}
lpop argcopy
}
#didn't find any exact matches
#traverse from other direction taking prefixes into account
if {[punk::args::id_exists $id]} {
#cycle forward through leading values
set def [punk::args::get_def $id]
if {[llength $queryargs]} {
set nextqueryargs [list] ;#build a list of prefix-resolved queryargs
set queryargs_untested $queryargs
foreach q $queryargs {
if {[llength [dict get $def leader_names]]} {
set subitems [dict get $def leader_names]
if {[llength $subitems]} {
set next [lindex $subitems 0]
set arginfo [dict get $def arg_info $next]
set allchoices [list]
set choices [punk::args::system::Dict_getdef $arginfo -choices {}]
set choicegroups [punk::args::system::Dict_getdef $arginfo -choicegroups {}]
if {[dict exists $choicegroups ""]} {
dict lappend choicegroups "" {*}$choices
} else {
set choicegroups [dict merge [dict create "" $choices] $choicegroups]
}
dict for {groupname clist} $choicegroups {
lappend allchoices {*}$clist
}
set resolved_q [tcl::prefix::match -error "" $allchoices $q]
if {$resolved_q eq ""} {
break
}
lappend nextqueryargs $resolved_q
lpop queryargs_untested 0
if {$resolved_q ne $q} {
#we have our first difference - recurse with new query args
set numvals [expr {[llength $queryargs]+1}]
return [ punk::ns::arginfo {*}[lrange $args 0 end-$numvals] $querycommand {*}$nextqueryargs {*}$queryargs_untested]
}
#check if subcommands so far have a custom args def
set currentid [list $querycommand {*}$nextqueryargs]
if {[punk::args::id_exists $currentid]} {
set def [punk::args::get_def $currentid
} else {
#We can get no further with custom defs
break
}
}
} else {
#review
break
}
}
} else {
return [uplevel 1 [list punk::args::usage {*}$opts $id]]
}
}
}
if {[string match "(autodef)*" $origin]} {
#wasn't resolved by id - so take this as a request to generate it (probably there is an existing custom def - and this has been manually requested to get the default)
set origin [string range $origin [string length (autodef)] end]
set resolved $origin
}
switch -- $cmdtype {
object {
#class is also an object
@ -2025,19 +2181,19 @@ tcl::namespace::eval punk::ns {
#set class_methods [info class methods $class]
#set object_methods [info object methods $origin]
if {[llength $commandargs]} {
set c1 [lindex $commandargs 0]
if {[llength $queryargs]} {
set c1 [lindex $queryargs 0]
if {$c1 in $public_methods} {
switch -- $c1 {
new {
set constructorinfo [info class constructor $origin]
set arglist [lindex $constructorinfo 0]
set argspec [punk::lib::tstr -return string {
*id "${$origin} new"
*proc -name "${$origin} new" -help\
@id -id "(autodef)${$origin} new"
@cmd -name "${$origin} new" -help\
"create object with specified command name.
Arguments are passed to the constructor."
*values
@values
}]
set i 0
foreach a $arglist {
@ -2054,17 +2210,17 @@ tcl::namespace::eval punk::ns {
incr i
}
punk::args::definition $argspec
return [punk::args::usage {*}$opts "$origin new"]
return [punk::args::usage {*}$opts "(autodef)$origin new"]
}
create {
set constructorinfo [info class constructor $origin]
set arglist [lindex $constructorinfo 0]
set argspec [punk::lib::tstr -return string {
*id "${$origin} create"
*proc -name "${$origin} create" -help\
@id -id "(autodef)${$origin} create"
@cmd -name "${$origin} create" -help\
"create object with specified command name.
Arguments following objectName are passed to the constructor."
*values -min 1
@values -min 1
objectName -type string -help\
"possibly namespaced name for object instance command"
}]
@ -2083,20 +2239,20 @@ tcl::namespace::eval punk::ns {
incr i
}
punk::args::definition $argspec
return [punk::args::usage {*}$opts "$origin create"]
return [punk::args::usage {*}$opts "(autodef)$origin create"]
}
destroy {
#review - generally no doc
# but we may want notes about a specific destructor
set argspec [punk::lib::tstr -return string {
*id "${$origin} destroy"
*proc -name "destroy" -help\
@id -id "(audodef)${$origin} destroy"
@cmd -name "destroy" -help\
"delete object, calling destructor if any.
destroy accepts no arguments."
*values -min 0 -max 0
@values -min 0 -max 0
}]
punk::args::definition $argspec
return [punk::args::usage {*}$opts "$origin destroy"]
return [punk::args::usage {*}$opts "(autodef)$origin destroy"]
}
default {
#use info object call <obj> <method> to resolve callchain
@ -2111,20 +2267,24 @@ tcl::namespace::eval punk::ns {
lassign $impl generaltype mname location methodtype
switch -- $generaltype {
method - private {
#objects being dynamic systems - we should always reinspect.
#Don't use the cached (autodef) def
#If there is a custom def override - use it (should really be -dynamic - but we don't check)
if {$location eq "object"} {
set id "[string trimleft $origin :] $c1" ;# "<object> <method>"
set idcustom "$origin $c1"
#set id "[string trimleft $origin :] $c1" ;# "<object> <method>"
if {[info commands ::punk::args::id_exists] ne ""} {
if {[punk::args::id_exists $id]} {
return [uplevel 1 [list punk::args::usage {*}$opts $id]]
if {[punk::args::id_exists $idcustom]} {
return [uplevel 1 [list punk::args::usage {*}$opts $idcustom]]
}
}
set def [::info object definition $origin $c1]
} else {
set id "[string trimleft $location :] $c1" ;# "<class> <method>"
#set id "[string trimleft $location :] $c1" ;# "<class> <method>"
set idcustom "$location $c1"
if {[info commands ::punk::args::id_exists] ne ""} {
if {[punk::args::id_exists $id]} {
return [uplevel 1 [list punk::args::usage {*}$opts $id]]
if {[punk::args::id_exists $idcustom]} {
return [uplevel 1 [list punk::args::usage {*}$opts $idcustom]]
}
}
set def [::info class definition $location $c1]
@ -2138,12 +2298,15 @@ tcl::namespace::eval punk::ns {
}
}
if {$def ne ""} {
#assert - if we pre
set autoid "(autodef)$location $c1"
set arglist [lindex $def 0]
set argspec [punk::lib::tstr -return string {
*id "${$location} ${$c1}"
*proc -name "${$location} ${$c1}" -help\
"arglist:${$arglist}"
*values
@id -id "${$autoid}"
@cmd -name "${$location} ${$c1}" -help\
"(autogenerated)
arglist:${$arglist}"
@values
}]
set i 0
foreach a $arglist {
@ -2166,7 +2329,7 @@ tcl::namespace::eval punk::ns {
incr i
}
punk::args::definition $argspec
return [punk::args::usage {*}$opts "$location $c1"]
return [punk::args::usage {*}$opts $autoid]
} else {
return "unable to resolve $origin method $c1"
}
@ -2189,9 +2352,11 @@ tcl::namespace::eval punk::ns {
switch -- $generaltype {
method - private {
if {$location eq "object"} {
set id "[string trimleft $origin :] $cmd" ;# "<object> <method>"
#set id "[string trimleft $origin :] $cmd" ;# "<object> <method>"
set id "$origin $cmd"
} else {
set id "[string trimleft $location :] $cmd" ;# "<class> <method>"
#set id "[string trimleft $location :] $cmd" ;# "<class> <method>"
set id "$location $cmd"
}
if {[info commands ::punk::args::id_exists] ne ""} {
if {[punk::args::id_exists $id]} {
@ -2212,15 +2377,16 @@ tcl::namespace::eval punk::ns {
set vline [list method -choices $public_methods -choicelabels $choicelabeldict -choiceprefix 0] ;#methods must be specified in full always? - review
#puts stderr "--->$vline"
set idauto "(autodef)$origin"
set argspec [punk::lib::tstr -return string {
*id ${$origin}
*proc -name "Object: ${$origin}" -help\
"Instance of class: ${$class}"
*values -min 1
@id -id ${$idauto}
@cmd -name "Object: ${$origin}" -help\
"Instance of class: ${$class} (info autogenerated)"
@values -min 1
}]
append argspec \n $vline
punk::args::definition $argspec
return [punk::args::usage {*}$opts $origin]
return [punk::args::usage {*}$opts $idauto]
}
privateObject {
return "Command is a privateObject - no info currently available"
@ -2287,11 +2453,11 @@ tcl::namespace::eval punk::ns {
set subcommands [lsort [dict keys $subcommand_dict]]
if {[llength $commandargs]} {
set match [tcl::prefix::match $subcommands [lindex $commandargs 0]]
if {[llength $queryargs]} {
set match [tcl::prefix::match $subcommands [lindex $queryargs 0]]
if {$match in $subcommands} {
set subcmd [dict get $subcommand_dict $match]
return [arginfo {*}$subcmd {*}[lrange $commandargs 1 end]] ;#subcmd is sometimes multiple words (implemented as a further ensemble subcommand) (e.g huddle string -> "Type_string string")
return [arginfo {*}$subcmd {*}[lrange $queryargs 1 end]] ;#subcmd is sometimes multiple words (implemented as a further ensemble subcommand) (e.g huddle string -> "Type_string string")
}
}
@ -2307,9 +2473,9 @@ tcl::namespace::eval punk::ns {
set is_object [list]
foreach ns $namespaces {
set nsinfo [lindex [punk::ns::nslist_dict [nsjoin [nsprefix $ns] *]] 0]
lappend have_usageinfo {*}[dict get $nsinfo usageinfo]
lappend is_ensemble {*}[dict get $nsinfo ensembles]
lappend is_object {*}[dict get $nsinfo ooobjects]
lappend have_usageinfo {*}[dict get $nsinfo usageinfo]
lappend is_ensemble {*}[dict get $nsinfo ensembles]
lappend is_object {*}[dict get $nsinfo ooobjects]
}
set choicelabeldict [dict create]
@ -2324,14 +2490,17 @@ tcl::namespace::eval punk::ns {
}
set vline [list subcommand -choices $subcommands -choiceprefix $prefixes -choicelabels $choicelabeldict]
set autoid "(autodef)$origin"
set argspec [punk::lib::tstr -return string {
*id ${$origin}
*proc -help "ensemble: ${$origin}"
*values -min 1
@id -id ${$autoid}
@cmd -help\
"(autogenerated)
ensemble: ${$origin}"
@values -min 1
}]
append argspec \n $vline
punk::args::definition $argspec
return [punk::args::usage {*}$opts $origin]
return [punk::args::usage {*}$opts $autoid]
}
#check for tepam help
@ -2364,12 +2533,6 @@ tcl::namespace::eval punk::ns {
}
}
set id [string trimleft $origin :]
if {[info commands ::punk::args::id_exists] ne ""} {
if {[punk::args::id_exists $id]} {
return [uplevel 1 [list punk::args::usage {*}$opts $id]]
}
}
set origin_ns [nsprefix $origin]
set parts [nsparts $origin_ns]
set weird_ns 0
@ -2379,24 +2542,42 @@ tcl::namespace::eval punk::ns {
if {$weird_ns} {
set argl {}
set tail [nstail $origin]
foreach a [nseval_ifexists $origin_ns [list info args $tail]] {
if {[nseval_ifexists $origin_ns [list info default $tail $a def]]} {
lappend a $def
set cmdtype [nseval_ifexists $origin_ns [list punk::ns::cmdtype $tail]]
if {$cmdtype eq "proc"} {
foreach a [nseval_ifexists $origin_ns [list info args $tail]] {
if {[nseval_ifexists $origin_ns [list info default $tail $a def]]} {
lappend a $def
}
lappend argl $a
}
lappend argl $a
}
} else {
set argl {}
foreach a [info args $origin] {
if {[info default $origin $a def]} {
lappend a $def
set cmdtype [punk::ns::cmdtype $origin]
if {$cmdtype eq "proc"} {
set argl {}
set infoargs [info args $origin]
foreach a $infoargs {
if {[info default $origin $a def]} {
lappend a $def
}
lappend argl $a
}
lappend argl $a
}
}
set msg "No argument processor detected"
append msg \n "function signature: $resolved $argl"
if {[llength $queryargs]} {
#todo - something better
set msg "Undocumented or nonexistant subcommand $origin $queryargs"
append msg \n "$origin Type: $cmdtype"
} else {
if {$cmdtype eq "proc"} {
set msg "Undocumented proc $origin"
append msg \n "No argument processor detected"
append msg \n "function signature: $resolved $argl"
} else {
set msg "Undocumented command $origin. Type: $cmdtype"
}
}
return $msg
}
@ -2738,8 +2919,8 @@ tcl::namespace::eval punk::ns {
interp alias "" use "" punk::ns::pkguse
punk::args::definition {
*id punk::ns::nsimport_noclobber
*proc -name punk::ns::nsimport_noclobber -help\
@id -id ::punk::ns::nsimport_noclobber
@cmd -name punk::ns::nsimport_noclobber -help\
"Import exported commands from a namespace into either the current namespace,
or that specified in -targetnamespace.
Return list of imported commands, ignores failures due to name conflicts"
@ -2750,14 +2931,14 @@ tcl::namespace::eval punk::ns {
If not supplied, caller's namespace is used."
-prefix -optional 1 -help\
"string prefix for command names in target namespace"
*values -min 1 -max 1
@values -min 1 -max 1
sourcepattern -type string -optional 0 -help\
"Glob pattern for source namespace.
Globbing only active in the tail segment.
e.g ::mynamespace::*"
}
proc nsimport_noclobber {args} {
lassign [dict values [punk::args::get_by_id punk::ns::nsimport_noclobber $args]] leaders opts values received
lassign [dict values [punk::args::get_by_id ::punk::ns::nsimport_noclobber $args]] leaders opts values received
set sourcepattern [dict get $values sourcepattern]
set source_ns [tcl::namespace::qualifiers $sourcepattern]

6
src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/path-0.1.0.tm

@ -645,14 +645,14 @@ namespace eval punk::path {
}
punk::args::definition {
*id punk::path::treefilenames
@id -id ::punk::path::treefilenames
-directory -type directory -help\
"folder in which to begin recursive scan for files."
-call-depth-internal -default 0 -type integer
-antiglob_paths -default {} -help\
"list of path patterns to exclude
may include * and ** path segments e.g /usr/**"
*values -min 0 -max -1 -optional 1 -type string
@values -min 0 -max -1 -optional 1 -type string
tailglobs -multiple 1 -help\
"Patterns to match against filename portion (last segment) of each file path
within the directory tree being searched."
@ -671,7 +671,7 @@ namespace eval punk::path {
#[para] list of path patterns to exclude - may include * and ** path segments e.g /usr/**
#[para]no natsorting - so order is dependent on filesystem
set argd [punk::args::get_by_id punk::path::treefilenames $args]
set argd [punk::args::get_by_id ::punk::path::treefilenames $args]
lassign [dict values $argd] leaders opts values received
set tailglobs [dict values $values]
# -- --- --- --- --- --- ---

84
src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/repo-0.1.1.tm

@ -62,6 +62,73 @@ package require punk::mix::util ;#do_in_path
# -- --- --- --- --- --- --- --- --- --- ---
namespace eval punk::repo {
variable PUNKARGS
variable PUNKARGS_aliases
proc get_fossil_usage {} {
set allcmds [runout -n fossil help -a]
set mainhelp [runout -n fossil help]
set maincommands [list]
foreach ln [split $mainhelp \n] {
set ln [string trim $ln]
if {$ln eq "" || [regexp {^[A-Z]+} $ln]} {
continue
}
lappend maincommands {*}$ln
}
set othercmds [punk::lib::ldiff $allcmds $maincommands]
set result "@leaders -min 0\n"
append result [tstr -return string {
subcommand -type string -choicecolumns 8 -choicegroups {
"frequently used commands" {${$maincommands}}
"" {${$othercmds}}
}
}]
return $result
}
#lappend PUNKARGS [list -dynamic 1 {
# @id -id ::punk::repo::fossil_proxy
# @cmd -name fossil -help "fossil executable
# "
# @argdisplay -header "fossil help" -body {${[runout -n fossil help]}}
# } ""]
lappend PUNKARGS [list -dynamic 1 {
@id -id ::punk::repo::fossil_proxy
@cmd -name fossil -help "fossil executable"
${[punk::repo::get_fossil_usage]}
} ]
#experiment
lappend PUNKARGS [list -dynamic 1 {
@id -id "::punk::repo::fossil_proxy diff"
@cmd -name "fossil diff" -help "fossil diff
"
@argdisplay -header "fossil help diff" -body {${[runout -n fossil help diff]}}
} ""]
lappend PUNKARGS [list -dynamic 1 {
@id -id "::punk::repo::fossil_proxy add"
@cmd -name "fossil add" -help "fossil add
"
@argdisplay -header "fossil help add" -body {${[runout -n fossil help add]}}
} ""]
#TODO
#lappend PUNKARGS [list -dynamic 1 {
# @id -glob 1 -id "::punk::repo::fossil_proxy *" -aliases {fs}
# @cmd -name "fossil add" -help "fossil add
# "
# @argdisplay -header "fossil help add" -body {${[runout -n fossil help add]}}
# } ""]
lappend PUNKARGS_aliases {"::fossil" "::punk::repo::fossil_proxy"}
lappend PUNKARGS_aliases {"::fossil diff" "::punk::repo::fossil_proxy diff"}
#Todo - investigate proper way to install a client-side commit hook in the fossil project
#Then we may still use this proxy to check the hook - but the required checks will occur when another shell used
@ -137,7 +204,7 @@ namespace eval punk::repo {
puts stderr "fossil command not found. Please install fossil"
}
}
interp alias "" fossil "" punk::repo::fossil_proxy
# ---
# Calling auto_execok on an external tool can be too slow to do during package load (e.g could be 150ms)
@ -153,6 +220,7 @@ namespace eval punk::repo {
# ----------
#
#uppercase FOSSIL to bypass fossil as alias to fossil_proxy
proc establish_FOSSIL {args} {
if {![info exists ::auto_execs(FOSSIL)]} {
@ -161,7 +229,6 @@ namespace eval punk::repo {
interp alias "" FOSSIL "" ;#delete establishment alias
FOSSIL {*}$args
}
interp alias "" FOSSIL "" punk::repo::establish_FOSSIL
# ----------
proc askuser {question} {
@ -1577,6 +1644,8 @@ namespace eval punk::repo {
}
}
interp alias "" fossil "" punk::repo::fossil_proxy
interp alias "" FOSSIL "" punk::repo::establish_FOSSIL
interp alias {} is_fossil {} ::punk::repo::is_fossil
interp alias {} is_fossil_root {} ::punk::repo::is_fossil_root
@ -1609,6 +1678,17 @@ namespace eval punk::repo::lib {
}
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
if {![info exists ::punk::args::register::NAMESPACES]} {
namespace eval ::punk::args::register {
set ::punk::args::register::NAMESPACES [list] ;#use fully qualified so 8.6 doesn't find existing var in global namespace
}
}
lappend ::punk::args::register::NAMESPACES ::punk::repo
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
## Ready
package provide punk::repo [namespace eval punk::repo {

19
src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/zip-0.1.1.tm

@ -180,10 +180,11 @@ tcl::namespace::eval punk::zip {
#}]
set argd [punk::args::get_dict {
*proc -name punk::zip::walk
@id -id ::punk::zip::walk
@cmd -name punk::zip::walk
-excludes -default "" -help "list of glob expressions to match against files and exclude"
-subpath -default ""
*values -min 1 -max -1
@values -min 1 -max -1
base
fileglobs -default {*} -multiple 1
} $args]
@ -373,11 +374,12 @@ tcl::namespace::eval punk::zip {
#[para] The return value is the central directory record that will need to be used when finalizing the zip archive.
set argd [punk::args::get_dict {
*proc -name punk::zip::Addentry -help "Add a single file at 'path' to open channel 'zipchan'
@id -id ::punk::zip::Addentry
@cmd -name punk::zip::Addentry -help "Add a single file at 'path' to open channel 'zipchan'
return a central directory file record"
*opts
@opts
-comment -default "" -help "An optional comment specific to the added file"
*values -min 3 -max 4
@values -min 3 -max 4
zipchan -help "open file descriptor with cursor at position appropriate for writing a local file header"
base -help "base path for entries"
path -type file -help "path of file to add"
@ -525,9 +527,10 @@ tcl::namespace::eval punk::zip {
#[para] Call 'punk::zip::mkzip' with no arguments for usage display.
set argd [punk::args::get_dict {
*proc -name punk::zip::mkzip\
@id -id ::punk::zip::mkzip
@cmd -name punk::zip::mkzip\
-help "Create a zip archive in 'filename'"
*opts
@opts
-offsettype -default "archive" -choices {archive file}\
-help "zip offsets stored relative to start of entire file or relative to start of zip-archive
Only relevant if the created file has a script/runtime prefix.
@ -557,7 +560,7 @@ tcl::namespace::eval punk::zip {
it must be a parent of -directory or the same path as -directory"
-exclude -default {CVS/* */CVS/* *~ ".#*" "*/.#*"}
*values -min 1 -max -1
@values -min 1 -max -1
filename -type file -default ""\
-help "name of zipfile to create"
globs -default {*} -multiple 1\

139
src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/textblock-0.1.2.tm

@ -123,12 +123,12 @@ tcl::namespace::eval textblock {
set choicemsg " (unavailable packages: $unavailable)"
}
set argd [punk::args::get_dict [tstr -return string {
*id textblock::use_hash
*proc -name "textblock::use_hash" -help\
@id -id ::textblock::use_hash
@cmd -name "textblock::use_hash" -help\
"Hashing algorithm to use for framecache lookup.
'none' may be slightly faster but less compact
when viewing textblock::framecache"
*values -min 0 -max 1
@values -min 0 -max 1
hash_algorithm -choices {${$choices}} -optional 1 -help\
"algorithm choice ${$choicemsg}"
}] $args]
@ -423,7 +423,6 @@ tcl::namespace::eval textblock {
}
}
}
my configure {*}$o_opts_table
#foreach {k v} $args {
# #todo - convert to literal switch using tcl::string::map so we don't have to define o_opts_table_defaults here.
@ -453,6 +452,7 @@ tcl::namespace::eval textblock {
-minheight 1\
-maxheight ""\
]
my configure {*}$o_opts_table
}
method width_algorithm {{alg ""}} {
@ -593,7 +593,7 @@ tcl::namespace::eval textblock {
tcl::dict::set o_opts_table_effective -framelimits_header $hlims
return [tcl::dict::create body $blims header $hlims]
}
method configure args {
method configure {args} {
#*** !doctools
#[call class::table [method configure] [arg args]]
#[para] get or set various table-level properties
@ -781,6 +781,14 @@ tcl::namespace::eval textblock {
}
}
}
-title {
set twidth [punk::ansi::printing_length $v]
if {[my width] < [expr {$twidth+2}]} {
set o_calculated_column_widths [list]
tcl::dict::set o_opts_table -minwidth [expr {$twidth+2}]
}
tcl::dict::set o_opts_table -title $v
}
default {
tcl::dict::set o_opts_table $k $v
}
@ -3943,14 +3951,13 @@ tcl::namespace::eval textblock {
if {$header_build eq "" && ![llength $body_blocks]} {
set header_build $nextcol_header
lappend body_blocks $nextcol_body
} else {
if {$headerheight > 0} {
set header_build [overtype::renderspace -startcolumn [expr {$padwidth + 1}] -expand_right 1 -transparent $TSUB $header_build[unset header_build] $nextcol_header[unset nextcol_header]]
}
lappend body_blocks $nextcol_body
#set body_build [textblock::join -- $body_build[unset body_build] $nextcol_body]
}
lappend body_blocks $nextcol_body
incr padwidth $bodywidth
incr colposn
}
@ -4096,8 +4103,8 @@ tcl::namespace::eval textblock {
}
punk::args::definition {
*id textblock::periodic
*proc -name textblock::periodic -help "A rudimentary periodic table
@id -id ::textblock::periodic
@cmd -name textblock::periodic -help "A rudimentary periodic table
This is primarily a test of textblock::class::table"
-return -default table\
@ -4109,13 +4116,13 @@ tcl::namespace::eval textblock {
-show_header -default "" -type boolean
-show_edge -default "" -type boolean
-forcecolour -default 0 -type boolean -help "If punk::colour is off - this enables the produced table to still be ansi coloured"
*values -min 0 -max 0
@values -min 0 -max 0
}
proc periodic {args} {
#For an impressive interactive terminal app (javascript)
# see: https://github.com/spirometaxas/periodic-table-cli
set opts [dict get [punk::args::get_by_id textblock::periodic $args] opts]
set opts [dict get [punk::args::get_by_id ::textblock::periodic $args] opts]
set opt_return [tcl::dict::get $opts -return]
if {[tcl::dict::get $opts -forcecolour]} {
set fc forcecolour
@ -4345,7 +4352,10 @@ tcl::namespace::eval textblock {
set FRAMETYPES [textblock::frametypes]
punk::args::definition [punk::lib::tstr -return string {
*id textblock::list_as_table
@id -id ::textblock::list_as_table
@cmd -name "textblock::list_as_table" -help\
"Display a list in a bordered table
"
-return -default table -choices {table tableobject}
-frametype -default "light" -type dict -choices {${$FRAMETYPES}} -choicerestricted 0\
@ -4376,13 +4386,13 @@ tcl::namespace::eval textblock {
-help "Number of table columns
Will default to 2 if not using an existing -table object"
*values -min 0 -max 1
@values -min 0 -max 1
datalist -default {} -type list -help "flat list of table cell values which will be wrapped based on -columns value"
}]
proc list_as_table {args} {
set FRAMETYPES [textblock::frametypes]
set argd [punk::args::get_by_id textblock::list_as_table $args]
set argd [punk::args::get_by_id ::textblock::list_as_table $args]
set opts [dict get $argd opts]
set datalist [dict get $argd values datalist]
@ -4894,7 +4904,7 @@ tcl::namespace::eval textblock {
#review!?
#-within_ansi means after a leading ansi code when doing left pad on all but last line
#-within_ansi means before a trailing ansi code when doing right pad on all but last line
set usage "pad ?-padchar <sp>|<character>? ?-which right|left|centre? ?-known_hasansi \"\"|<bool>? ?-known_blockwidth \"\"|<int>? ?-width auto|<int>? ?-within_ansi 1|0?"
set usage "pad block ?-padchar <sp>|<character>? ?-which right|left|centre? ?-known_hasansi \"\"|<bool>? ?-known_blockwidth \"\"|<int>? ?-width auto|<int>? ?-within_ansi 1|0?"
foreach {k v} $args {
switch -- $k {
-padchar - -which - -known_hasansi - -known_samewidth - -known_blockwidth - -width - -overflow - -within_ansi {
@ -5420,16 +5430,21 @@ tcl::namespace::eval textblock {
return [punk::lib::list_as_lines -- $outlines]
}
punk::args::definition {
@id -id ::textblock::join_basic
@cmd -name textblock::join_basic -help\
"Join blocks of text line by line but don't add padding on each line to enforce uniform width.
Already uniform blocks will join faster than textblock::join, and ragged blocks will join in a ragged manner
"
-- -type none -optional 0 -help "end of options marker -- is mandatory because joined blocks may easily conflict with flags"
-ansiresets -type any -default auto
blocks -type any -multiple 1
}
#join without regard to each line length in a block (no padding added to make each block uniform)
proc ::textblock::join_basic {args} {
#*proc -name textblock::join_basic -help "Join blocks line by line but don't add padding on each line to enforce uniform width.
# Already uniform blocks will join faster than textblock::join, and ragged blocks will join in a ragged manner
#"
set argd [punk::args::get_dict {
-- -type none -optional 0 -help "end of options marker -- is mandatory because joined blocks may easily conflict with flags"
-ansiresets -type any -default auto
blocks -type any -multiple 1
} $args]
set argd [punk::args::get_by_id ::textblock::join_basic $args]
set ansiresets [tcl::dict::get $argd opts -ansiresets]
set blocks [tcl::dict::get $argd values blocks]
@ -5466,7 +5481,7 @@ tcl::namespace::eval textblock {
return [::join $outlines \n]
}
proc ::textblock::join_basic2 {args} {
#*proc -name textblock::join_basic -help "Join blocks line by line but don't add padding on each line to enforce uniform width.
#@cmd -name textblock::join_basic -help "Join blocks line by line but don't add padding on each line to enforce uniform width.
# Already uniform blocks will join faster than textblock::join, and ragged blocks will join in a ragged manner
#"
set argd [punk::args::get_dict {
@ -6046,8 +6061,8 @@ tcl::namespace::eval textblock {
if {$bad_option || [llength $values] == 0} {
#no framedef supplied, or unrecognised opt seen
set spec [string map [list <ftlist> $::textblock::frametypes] {
*id textblock::framedef
*proc -name textblock::framedef\
@id -id ::textblock::framedef
@cmd -name textblock::framedef\
-help "Return a dict of the elements that make up a frame border.
May return a subset of available elements based on memberglob values."
@ -6058,7 +6073,7 @@ tcl::namespace::eval textblock {
-help "-boxonly true restricts results to the corner,vertical and horizontal box elements
It excludes the extra top and side join elements htlj,hlbj,vllj,vlrj."
*values -min 1
@values -min 1
frametype -choices "<ftlist>" -choiceprefix 0 -choicerestricted 0 -type dict\
-help "name from the predefined frametypes or an adhoc dictionary."
memberglob -type globstring -optional 1 -multiple 1 -choiceprefix 0 -choicerestricted 0 -choices {
@ -7438,17 +7453,17 @@ tcl::namespace::eval textblock {
set frame_cache [tcl::dict::create]
punk::args::definition {
*id textblock::frame_cache
*proc -name textblock::frame_cache -help\
@id -id ::textblock::frame_cache
@cmd -name textblock::frame_cache -help\
"Display or clear the frame cache."
-action -default {} -choices {clear} -help\
"Clear the textblock::frame_cache dictionary"
-pretty -default 1 -help\
"Use 'pdict textblock::frame_cache */*' for prettier output"
*values -min 0 -max 0
@values -min 0 -max 0
}
proc frame_cache {args} {
set argd [punk::args::get_by_id textblock::frame_cache $args]
set argd [punk::args::get_by_id ::textblock::frame_cache $args]
set action [dict get $argd opts -action]
if {$action ni [list clear ""]} {
@ -7490,13 +7505,40 @@ tcl::namespace::eval textblock {
}
variable FRAMETYPES
set FRAMETYPES [textblock::frametypes]
variable EG
set EG [a+ brightblack]
variable RST
set RST [a]
proc frame_samples {} {
set FRAMETYPELABELS [dict create]
if {[info commands ::textblock::frame] ne ""} {
foreach ft [frametypes] {
dict set FRAMETYPELABELS $ft [textblock::frame -checkargs 0 -type $ft " "]
}
}
set FRAMETYPELABELS [dict remove $FRAMETYPELABELS block2hack]
return $FRAMETYPELABELS
}
#proc EG {} "return {[a+ brightblack]}"
#make EG fetch from SGR cache so as to abide by colour off/on
proc EG {} {
a+ brightblack
}
#proc RST {} "return {\x1b\[m}"
proc RST {} {
return "\x1b\[m"
}
#catch 22 for -choicelabels - need some sort of lazy evaluation
# ${[textblock::frame_samples]}
#todo punk::args alias for centre center etc?
punk::args::definition [punk::lib::tstr -return string {
*id textblock::frame
*proc -name "textblock::frame"\
punk::args::definition -dynamic 1 {
@id -id ::textblock::frame
@cmd -name "textblock::frame"\
-help "Frame a block of text with a border."
-checkargs -default 1 -type boolean\
-help "If true do extra argument checks and
@ -7504,18 +7546,21 @@ tcl::namespace::eval textblock {
Set false for slight performance improvement."
-etabs -default 0\
-help "expanding tabs - experimental/unimplemented."
-type -default light -choices {${$FRAMETYPES}} -choicerestricted 0 -type dict\
-type -default light -choices {${[textblock::frametypes]}} -choicerestricted 0 -choicecolumns 8 -type dict\
-choicelabels {
${[textblock::frame_samples]}
}\
-help "Type of border for frame."
-boxlimits -default {hl vl tlc blc trc brc} -type list -help "Limit the border box to listed elements.
passing an empty string will result in no box, but title/subtitle will still appear if supplied.
${$EG}e.g: -frame -boxlimits {} -title things [a+ red White]my\\ncontent${$RST}"
${[textblock::EG]}e.g: -frame -boxlimits {} -title things [a+ red White]my\\ncontent${[textblock::RST]}"
-boxmap -default {} -type dict
-joins -default {} -type list
-title -default "" -type string -regexprefail {\n}\
-help "Frame title placed on topbar - no newlines.
May contain ANSI - no trailing reset required.
${$EG}e.g 1: frame -title My[a+ green]Green[a]Thing
e.g 2: frame -title [a+ red underline]MyThing${$RST}"
${[textblock::EG]}e.g 1: frame -title My[a+ green]Green[a]Thing
e.g 2: frame -title [a+ red underline]MyThing${[textblock::RST]}"
-subtitle -default "" -type string -regexprefail {\n}\
-help "Frame subtitle placed on bottombar - no newlines
May contain Ansi - no trailing reset required."
@ -7526,8 +7571,8 @@ tcl::namespace::eval textblock {
-help "Height of resulting frame including borders."
-ansiborder -default "" -type ansistring\
-help "Ansi escape sequence to set border attributes.
${$EG}e.g 1: frame -ansiborder [a+ web-red] contents
e.g 2: frame -ansiborder \"\\x1b\\\[31m\" contents${$RST}"
${[textblock::EG]}e.g 1: frame -ansiborder [a+ web-red] contents
e.g 2: frame -ansiborder \"\\x1b\\\[31m\" contents${[textblock::RST]}"
-ansibase -default "" -type ansistring\
-help "Default ANSI attributes within frame."
-blockalign -default centre -choices {left right centre}\
@ -7547,13 +7592,13 @@ tcl::namespace::eval textblock {
Frame width doesn't adapt and content may be truncated
so -width may need to be manually set to display more."
*values -min 0 -max 1
@values -min 0 -max 1
contents -default "" -type string\
-help "Frame contents - may be a block of text containing newlines and ANSI.
Text may be 'ragged' - ie unequal line-lengths.
No trailing ANSI reset required.
${$EG}e.g: frame \"[a+ blue White] \\nMy blue foreground text on\\nwhite background\\n\"${$RST}"
}]
${[textblock::EG]}e.g: frame \"[a+ blue White] \\nMy blue foreground text on\\nwhite background\\n\"${[textblock::RST]}"
}
#options before content argument - which is allowed to be absent
#frame performance (noticeable with complex tables even of modest size) is improved somewhat by frame_cache - but is still (2024) a fairly expensive operation.
@ -7638,7 +7683,7 @@ tcl::namespace::eval textblock {
#only use punk::args if check_args is true or our basic checks failed
#never need to checkargs if only one argument supplied even if it looks like an option - as it will be treated as data to frame
if {[llength $args] != 1 && (!$opts_ok || $check_args)} {
set argd [punk::args::get_by_id textblock::frame $args]
set argd [punk::args::get_by_id ::textblock::frame $args]
set opts [dict get $argd opts]
set contents [dict get $argd values contents]
}
@ -8346,18 +8391,18 @@ tcl::namespace::eval textblock {
}
}
punk::args::definition {
*id textblock::gcross
@id -id ::textblock::gcross
-max_cross_size -default 0 -type integer -help "Largest size cross to use to make up the block
Only cross sizes that divide the size of the overall block will be used.
e.g if the 'size' chosen is 19 (a prime number) - only 1 or the full size of 19 can be used as the crosses to make up the block.
Whereas for a block size of 24, -max_cross_size of 1,2,3,4,6,8,12 or 24 will work. (all divisors)
If a number chosen for -max_cross_size isn't a divisor, the largest divisor below the chosen value will be used.
"
*values -min 0 -max 1
@values -min 0 -max 1
size -default 1 -type integer
}
proc gcross {args} {
set argd [punk::args::get_by_id textblock::gcross $args]
set argd [punk::args::get_by_id ::textblock::gcross $args]
set size [dict get $argd values size]
set opts [dict get $argd opts]

27
src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/overtype-1.6.5.tm

@ -402,7 +402,10 @@ tcl::namespace::eval overtype {
set looplimit [expr {[tcl::string::length $overblock] + 10}]
}
set scheme 3
#overblock height/width isn't useful in the presence of an ansi input overlay with movements. The number of lines may bear little relationship to the output height
#lassign [blocksize $overblock] _w overblock_width _h overblock_height
set scheme 4
switch -- $scheme {
0 {
#one big chunk
@ -443,11 +446,18 @@ tcl::namespace::eval overtype {
set inputchunks [lindex [list $lflines [unset lflines]] 0]
}
4 {
set inputchunks [list]
foreach ln [split $overblock \n] {
lappend inputchunks [string cat $ln \n]
}
if {[llength $inputchunks]} {
lset inputchunks end [tcl::string::range [lindex $inputchunks end] 0 end-1]
}
}
}
#overblock height/width isn't useful in the presence of an ansi input overlay with movements. The number of lines may bear little relationship to the output height
#lassign [blocksize $overblock] _w overblock_width _h overblock_height
set replay_codes_underlay [tcl::dict::create 1 ""]
@ -495,7 +505,7 @@ tcl::namespace::eval overtype {
}
#review insert_mode. As an 'overtype' function whose main function is not interactive keystrokes - insert is secondary -
#but even if we didn't want it as an option to the function call - to process ansi adequately we need to support IRM (insertion-replacement mode) ESC [ 4 h|l
set renderargs [list -experimental $opt_experimental\
set renderopts [list -experimental $opt_experimental\
-cp437 $opt_cp437\
-info 1\
-crm_mode [tcl::dict::get $vtstate crm_mode]\
@ -510,11 +520,8 @@ tcl::namespace::eval overtype {
-expand_right $opt_expand_right\
-cursor_column $col\
-cursor_row $row\
$undertext\
$overtext\
]
set LASTCALL $renderargs
set rinfo [renderline {*}$renderargs]
set rinfo [renderline {*}$renderopts $undertext $overtext]
set instruction [tcl::dict::get $rinfo instruction]
tcl::dict::set vtstate crm_mode [tcl::dict::get $rinfo crm_mode]
@ -1237,8 +1244,8 @@ tcl::namespace::eval overtype {
append debugmsg "looplimit $looplimit reached\n"
append debugmsg "data_mode:$data_mode\n"
append debugmsg "opt_appendlines:$opt_appendlines\n"
append debugmsg "prev_row :[tcl::dict::get $LASTCALL -cursor_row]\n"
append debugmsg "prev_col :[tcl::dict::get $LASTCALL -cursor_column]\n"
append debugmsg "prev_row :[tcl::dict::get $renderopts -cursor_row]\n"
append debugmsg "prev_col :[tcl::dict::get $renderopts -cursor_column]\n"
tcl::dict::for {k v} $rinfo {
append debugmsg "${Y}$k [ansistring VIEW -lf 1 -vt 1 $v]$RST" \n
}

15
src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk-0.1.tm

@ -306,10 +306,11 @@ namespace eval punk {
#get last command result that was run through the repl
proc ::punk::get_runchunk {args} {
set argd [punk::args::get_dict {
*opts
@id -id ::punk::get_runchunk
@opts
-1 -optional 1 -type none
-2 -optional 1 -type none
*values -min 0 -max 0
@values -min 0 -max 0
} $args]
#todo - make this command run without truncating previous runchunks
set runchunks [tsv::array names repl runchunks-*]
@ -7152,8 +7153,8 @@ namespace eval punk {
}
punk::args::definition {
*id punk::inspect
*proc -name punk::inspect -help\
@id -id ::punk::inspect
@cmd -name punk::inspect -help\
"Function to display values - used pimarily in a punk pipeline.
The raw value arguments (not options) are always returned to pass
forward in the pipeline.
@ -7227,9 +7228,9 @@ namespace eval punk {
Does not affect return value."
-- -type none -help\
"End of options marker.
It is advisable to use this, as data in a pipeline may often being with -"
It is advisable to use this, as data in a pipeline may often begin with -"
*values -min 0 -max -1
@values -min 0 -max -1
arg -type string -optional 1 -multiple 1 -help\
"value to display"
}
@ -7261,7 +7262,7 @@ namespace eval punk {
foreach {k v} $flags {
if {$k ni [dict keys $defaults]} {
#error "inspect: unknown option $k. Known options: [dict keys $defaults]. If data contains flaglike elements, consider calling with end-of-opts marker. e.g inspect --"
punk::args::get_by_id punk::inspect $args
punk::args::get_by_id ::punk::inspect $args
}
}
set opts [dict merge $defaults $flags]

145
src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/ansi-0.1.1.tm

@ -134,27 +134,27 @@ tcl::namespace::eval punk::ansi::class {
}
lappend ::punk::ansi::class::PUNKARGS [list {
*id "punk::ansi::class::class_ansi render_to_input_line"
*proc -name "punk::ansi::class::class_ansi render_to_input_line" -help\
@id -id "::punk::ansi::class::class_ansi render_to_input_line"
@cmd -name "punk::ansi::class::class_ansi render_to_input_line" -help\
"render string from line 0 to line
(experimental/debug)"
-dimensions -type string -help\
"WxH where W is integer width >= 1 and H is integer heigth >= 1"
-minus -type integer -help\
"number of chars to exclude from end"
*values -min 1 -max 1
@values -min 1 -max 1
line -type indexexpression
}]
method render_to_input_line {args} {
if {[llength $args] < 1} {
puts stderr "render_to_input_line usage: ?-dimensions WxH? ?-minus charcount? x"
punk::args::get_by_id "punk::ansi::class::class_ansi render_to_input_line" $args
punk::args::get_by_id "::punk::ansi::class::class_ansi render_to_input_line" $args
}
set x [lindex $args end]
set arglist [lrange $args 0 end-1]
if {[llength $arglist] %2 != 0} {
puts stderr "render_to_input_line usage: ?-dimensions WxH? ?-minus charcount? x"
punk::args::get_by_id "punk::ansi::class::class_ansi render_to_input_line" $args
punk::args::get_by_id "::punk::ansi::class::class_ansi render_to_input_line" $args
}
set opts [tcl::dict::create\
-dimensions 80x24\
@ -167,7 +167,7 @@ tcl::namespace::eval punk::ansi::class {
}
default {
puts stderr "render_to_input_line unexpected argument '$k' usage: ?-dimensions WxH? ?-minus charcount? x"
punk::args::get_by_id "punk::ansi::class::class_ansi render_to_input_line" $args
punk::args::get_by_id "::punk::ansi::class::class_ansi render_to_input_line" $args
}
}
}
@ -588,20 +588,20 @@ tcl::namespace::eval punk::ansi {
}
lappend PUNKARGS [list -dynamic 1 {
*id punk::ansi::example
*proc -name punk::ansi::example -help "Display .ans image files in a grid that will fit in console
@id -id ::punk::ansi::example
@cmd -name punk::ansi::example -help "Display .ans image files in a grid that will fit in console
"
-colwidth -default 82 -help "Width of each column - default of 82 will fit a standard 80wide ansi image (when framed)
You can specify a narrower width to truncate images on the right side"
-folder -default "${[punk::ansi::Get_ansifolder]}" -help "Base folder for files if relative paths are used.
Defaults to <projectbase>/src/testansi - where projectbase is determined from current directory.
"
*values -min 0 -max -1
@values -min 0 -max -1
files -default {belinda.ans bot.ans flower.ans fish.ans} -multiple true -help "List of filenames - leave empty to display 4 defaults"
} ""]
proc example {args} {
set argd [punk::args::get_by_id punk::ansi::example $args]
set argd [punk::args::get_by_id ::punk::ansi::example $args]
set colwidth [dict get $argd opts -colwidth]
set ansifolder [file normalize [dict get $argd opts -folder]]
set fnames [dict get $argd values files]
@ -2355,21 +2355,21 @@ Brightblack 100 Brightred 101 Brightgreen 102 Brightyellow 103 Brightblu
#sgr_cache clear called by punk::console::ansi when set to off
#punk::args depends on punk::ansi - REVIEW
lappend PUNKARGS [list {
@id -id ::punk::ansi::sgr_cache
@cmd -name punk::ansi::sgr_cache -help\
"Convenience function to view and optionally clear the ansi character attribute cache (ansi SGR codes)
"
-action -default "" -choices "clear" -help\
"-action clear will unset the keys in the punk::ansi::sgr_cache dict
This is called automatically when setting 'colour false' in the console"
-pretty -default 1 -type boolean -help\
"use 'pdict punk::ansi::sgr_cache */%str,%ansiview' output"
@values -min 0 -max 0
}]
proc sgr_cache {args} {
set argdef {
*id punk::ansi::sgr_cache
*proc -name punk::ansi::sgr_cache -help\
"Convenience function to view and optionally clear the ansi character attribute cache (ansi SGR codes)
"
-action -default "" -choices "clear" -help\
"-action clear will unset the keys in the punk::ansi::sgr_cache dict
This is called automatically when setting 'colour false' in the console"
-pretty -default 1 -type boolean -help\
"use 'pdict punk::ansi::sgr_cache */%str,%ansiview' output"
*values -min 0 -max 0
}
set argd [punk::args::get_dict $argdef $args]
set argd [punk::args::get_by_id ::punk::ansi::sgr_cache $args]
set action [dict get $argd opts -action]
set pretty [dict get $argd opts -pretty]
@ -2412,34 +2412,7 @@ Brightblack 100 Brightred 101 Brightgreen 102 Brightyellow 103 Brightblu
return [join $lines \n]
}
lappend PUNKARGS [list {
*id punk::ansi::a+
*proc -name "punk::ansi::a+" -help\
"Returns an ANSI sgr escape sequence based on the list of supplied codes.
Unlike punk::ansi::a - it is not prefixed with an ANSI reset.
"
*values -min 0 -max -1
} [string map [list <choices> [dict keys $SGR_map]] {
code -type string -optional 1 -multiple 1 -choices {<choices>} -choiceprefix 0 -choicerestricted 0 -help\
"SGR code from the list below, or an integer corresponding to the code e.g 31 = red.
A leading capital letter indicates a codename applies to the background colour.
Other accepted codes are:
term-<int> Term-<int> foreground/background where int is 0-255 terminal color
term-<termcolour> Term-<termcolour> foreground/background
rgb-<r>-<g>-<b> Rgb-<r>-<g>-<b> foreground/background where <r> <g> <b> are the
0-255 int values for red, green and blue.
rgb#<hexcode> Rgb#<hexcode> where <hexcode> is a 6 char hex colour e.g rgb#C71585
web-<webcolour> Web-<webcolour>
The acceptable values for <termcolour> and <webcolour> can be queried using
punk::ansi::a? term
and
punk::ansi::a? web
Example to set foreground red and background cyan followed by a reset:
set str \"[a+ red Cyan]sample text[a]\"
"
}]]
#PUNKARGS doc performed below, after we create the proc
proc a+ {args} {
#*** !doctools
#[call [fun a+] [opt {ansicode...}]]
@ -2907,6 +2880,41 @@ Brightblack 100 Brightred 101 Brightgreen 102 Brightyellow 103 Brightblu
return $result
}
set SGR_samples [dict create]
foreach k [dict keys $SGR_map] {
dict set SGR_samples $k "[punk::ansi::a+ $k]sample\x1b\[m"
}
lappend PUNKARGS [list {
@id -id ::punk::ansi::a+
@cmd -name "punk::ansi::a+" -help\
"Returns an ANSI sgr escape sequence based on the list of supplied codes.
Unlike punk::ansi::a - it is not prefixed with an ANSI reset.
"
@values -min 0 -max -1
} [string map [list <choices> [dict keys $SGR_map] <choicelabels> $SGR_samples] {
code -type string -optional 1 -multiple 1 -choices {<choices>}\
-choicelabels {<choicelabels>}\
-choicecolumns 5 -choiceprefix 0 -choicerestricted 0 -help\
"SGR code from the list below, or an integer corresponding to the code e.g 31 = red.
A leading capital letter indicates a codename applies to the background colour.
Other accepted codes are:
term-<int> Term-<int> foreground/background where int is 0-255 terminal color
term-<termcolour> Term-<termcolour> foreground/background
rgb-<r>-<g>-<b> Rgb-<r>-<g>-<b> foreground/background where <r> <g> <b> are the
0-255 int values for red, green and blue.
rgb#<hexcode> Rgb#<hexcode> where <hexcode> is a 6 char hex colour e.g rgb#C71585
web-<webcolour> Web-<webcolour>
The acceptable values for <termcolour> and <webcolour> can be queried using
punk::ansi::a? term
and
punk::ansi::a? web
Example to set foreground red and background cyan followed by a reset:
set str \"[a+ red Cyan]sample text[a]\"
"
}]]
proc a {args} {
#*** !doctools
#[call [fun a] [opt {ansicode...}]]
@ -4281,6 +4289,7 @@ tcl::namespace::eval punk::ansi {
}
4 {
#REVIEW - merging extended (e.g 4:4) underline attributes suppresses all other SGR attributes on at least some terminals which don't support extended underlines
#e.g hyper on windows
if {[llength $paramsplit] == 1} {
tcl::dict::set codestate underline 4
} else {
@ -4634,6 +4643,8 @@ tcl::namespace::eval punk::ansi::ta {
#[list_begin definitions]
tcl::namespace::path ::punk::ansi
variable PUNKARGS
#handle both 7-bit and 8-bit csi
#review - does codepage affect this? e.g ebcdic has 8bit csi in different position
@ -4706,15 +4717,31 @@ tcl::namespace::eval punk::ansi::ta {
#variable re_ansi_split "${re_csi_code}|${re_esc_osc1}|${re_esc_osc2}|${re_esc_osc3}|${re_standalones}|${re_ST}|${re_g0_open}|${re_g0_close}"
set re_ansi_split $re_ansi_detect
lappend PUNKARGS [list -dynamic 0 {
@id -id ::punk::ansi::ta::detect
@cmd -name punk::ansi::ta::detect -help\
"Return a boolean indicating whether Ansi codes were detected in text.
Important caveat:
When text is a tcl list made from splitting (or lappending) some ansi string
- individual elements may be braced or have certain chars escaped.
(one example is if a list element contains an unbalanced brace)
This can cause square brackets that form part of the ansi to be backslash escaped
- and the function can fail to match it as an Ansi code.
"
@values -min 1
text -type string
} ]
#*** !doctools
#[call [fun detect] [arg text]]
#[para]Return a boolean indicating whether Ansi codes were detected in text
#[para]Important caveat:
#[para] When text is a tcl list made from splitting (or lappending) some ansi string - individual elements may be braced or have certain chars escaped. (one example is if a list element contains an unbalanced brace)
#[para] This can cause square brackets that form part of the ansi being backslash escaped - and the regexp can fail to match
#detect any ansi escapes
#review - only detect 'complete' codes - or just use the opening escapes for performance?
proc detect {text} [string map [list <re> [list $re_ansi_detect]] {
#*** !doctools
#[call [fun detect] [arg text]]
#[para]Return a boolean indicating whether Ansi codes were detected in text
#[para]Important caveat:
#[para] When text is a tcl list made from splitting (or lappending) some ansi string - individual elements may be braced or have certain chars escaped. (one example is if a list element contains an unbalanced brace)
#[para] This can cause square brackets that form part of the ansi being backslash escaped - and the regexp can fail to match
regexp <re> $text
}]
@ -7405,7 +7432,7 @@ if {![info exists ::punk::args::register::NAMESPACES]} {
set NAMESPACES [list]
}
}
lappend ::punk::args::register::NAMESPACES ::punk::ansi ::punk::ansi::class
lappend ::punk::args::register::NAMESPACES ::punk::ansi ::punk::ansi::class ::punk::ansi::ta
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
## Ready

1114
src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/args-0.1.0.tm

File diff suppressed because it is too large Load Diff

15
src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/cap/handlers/templates-0.1.0.tm

@ -254,8 +254,9 @@ namespace eval punk::cap::handlers::templates {
}
method folders {args} {
set argd [punk::args::get_dict {
@id -id "::punk::cap::handlers::templates::class::api folders"
-startdir -default ""
*values -max 0
@values -max 0
} $args]
set opts [dict get $argd opts]
@ -471,10 +472,11 @@ namespace eval punk::cap::handlers::templates {
}
method get_itemdict_projectlayouts {args} {
set argd [punk::args::get_dict {
*opts -anyopts 1
@id -id "::punk::cap::handlers::templates::class::api get_itemdict_projectlayouts"
@opts -anyopts 1
#peek -startdir while allowing all other opts/vals to be verified down-the-line instead of here
-startdir -default ""
*values -maxvalues -1
@values -maxvalues -1
} $args]
set opt_startdir [dict get $argd opts -startdir]
@ -648,14 +650,15 @@ namespace eval punk::cap::handlers::templates {
#and a name determining command -command_get_item_name
method _get_itemdict {args} {
set argd [punk::args::get_dict {
*proc -name _get_itemdict
*opts -anyopts 0
@id -id "::punk::cap::handlers::templates::class::api _get_itemdict"
@cmd -name _get_itemdict
@opts -anyopts 0
-startdir -default ""
-templatefolder_subdir -optional 0
-command_get_items_from_base -optional 0
-command_get_item_name -optional 0
-not -default "" -multiple 1
*values -maxvalues -1
@values -maxvalues -1
globsearches -default * -multiple 1
} $args]
set opts [dict get $argd opts]

12
src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/config-0.1.tm

@ -362,10 +362,10 @@ tcl::namespace::eval punk::config {
proc configure {args} {
set argdef {
*id punk::config::configure
*proc -name punk::config::configure -help\
@id -id ::punk::config::configure
@cmd -name punk::config::configure -help\
"UNIMPLEMENTED"
*values -min 1 -max 1
@values -min 1 -max 1
whichconfig -type string -choices {startup running stop}
}
set argd [punk::args::get_dict $argdef $args]
@ -388,15 +388,15 @@ tcl::namespace::eval punk::config {
#This is to allow partial configs to be loaded to running, whereas a save of running to any target is always a complete configuration
proc copy {args} {
set argdef {
*id punk::config::copy
*proc -name punk::config::copy -help\
@id -id ::punk::config::copy
@cmd -name punk::config::copy -help\
"Copy a partial or full configuration from one config to another
If a target config has additional settings, then the source config can be considered to be partial with regards to the target.
"
-type -default "" -choices {replace merge} -help\
"Defaults to merge when target is running-config
Defaults to replace when source is running-config"
*values -min 2 -max 2
@values -min 2 -max 2
fromconfig -help\
"running or startup or file name (not fully implemented)"
toconfig -help\

8
src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/console-0.1.1.tm

@ -875,7 +875,7 @@ namespace eval punk::console {
}
}
punk::args::set_alias punk::console::code_a+ punk::ansi::a+
punk::args::set_alias ::punk::console::code_a+ ::punk::ansi::a+
proc code_a+ {args} {
variable ansi_wanted
if {$ansi_wanted <= 0} {
@ -1187,14 +1187,14 @@ namespace eval punk::console {
#todo - change -inoutchannels to -terminalobject with prebuilt default
punk::args::definition {
*id punk::console::cell_size
@id -id ::punk::console::cell_size
-inoutchannels -default {stdin stdout} -type list
*values -min 0 -max 1
@values -min 0 -max 1
newsize -default "" -help\
"character cell pixel dimensions WxH"
}
proc cell_size {args} {
set argd [punk::args::get_by_id punk::console::cell_size $args]
set argd [punk::args::get_by_id ::punk::console::cell_size $args]
set inoutchannels [dict get $argd opts -inoutchannels]
set newsize [dict get $argd values newsize]

6
src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/du-0.1.0.tm

@ -563,9 +563,10 @@ namespace eval punk::du {
variable win_reparse_tags_by_int
set argd [punk::args::get_dict {
@id -id ::punk::du::lib::Get_attributes_from_iteminfo
-debug -default 0 -help "set 1 for raw data on -debugchannel (default stderr)"
-debugchannel -default stderr -help "channel to write debug output, or none to append to output"
*values -min 1 -max 1
@values -min 1 -max 1
iteminfo -help "iteminfo dict as set by 'twapi::find_file_next <iterator> iteminfo'"
} $args]
set opts [dict get $argd opts]
@ -621,10 +622,11 @@ namespace eval punk::du {
proc attributes_twapi {args} {
set argd [punk::args::get_dict {
@id -id ::punk::du::lib::attributes_twapi
-debug -default 0 -help "set 1 for raw data on -debugchannel (default stderr)"
-debugchannel -default stderr -help "channel to write debug output, or none to append to output"
-detail -default basic -choices {basic full} -help "full returns also the altname/shortname field"
*values -min 1 -max 1
@values -min 1 -max 1
path -help "path to file or folder for which to retrieve attributes"
} $args]
set opts [dict get $argd opts]

8
src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/fileline-0.1.0.tm

@ -1252,14 +1252,14 @@ namespace eval punk::fileline {
#[list_begin definitions]
punk::args::definition {
*id punk::fileline::get_textinfo
*proc -name punk::fileline::get_textinfo -help\
@id -id ::punk::fileline::get_textinfo
@cmd -name punk::fileline::get_textinfo -help\
"return: textinfo object instance"
-file -default {} -type existingfile
-translation -default iso8859-1
-encoding -default "\uFFFF"
-includebom -default 0
*values -min 0 -max 1
@values -min 0 -max 1
}
proc get_textinfo {args} {
#*** !doctools
@ -1276,7 +1276,7 @@ namespace eval punk::fileline {
#[para]Currently only utf-8, utf-16* and utf-32* are properly supported even though the other BOMs are detected, reported via get_bomid, and stripped from the data.
#[para]GB18030 falls back to cp936/gbk (unless a gb18030 encoding has been installed). Use -encoding iso8859-1 if this isn't suitable and you need to do your own processing of the bytes.
lassign [dict values [punk::args::get_by_id punk::fileline::get_textinfo $args]] opts values
lassign [dict values [punk::args::get_by_id ::punk::fileline::get_textinfo $args]] opts values
# -- --- --- ---
set opt_file [dict get $opts -file]
set opt_translation [dict get $opts -translation]

26
src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/lib-0.1.1.tm

@ -1009,13 +1009,13 @@ namespace eval punk::lib {
set sep " [punk::ansi::a+ Green]=[punk::ansi::a] "
}
set argspec [string map [list %sep% $sep] {
*id punk::lib::pdict
*proc -name pdict -help\
@id -id ::punk::lib::pdict
@cmd -name pdict -help\
"Print dict keys,values to channel
The pdict function operates on variable names - passing the value to the showdict function which operates on values
(see also showdict)"
*opts -any 1
@opts -any 1
#default separator to provide similarity to tcl's parray function
-separator -default "%sep%"
@ -1023,7 +1023,7 @@ namespace eval punk::lib {
-substructure -default {}
-channel -default stdout -help "existing channel - or 'none' to return as string"
*values -min 1 -max -1
@values -min 1 -max -1
dictvar -type string -help "name of variable. Can be a dict, list or array"
@ -1095,14 +1095,16 @@ namespace eval punk::lib {
package require textblock
set argd [punk::args::get_dict [string map [list %sep% $sep %sep_mismatch% $sep_mismatch] {
*id punk::lib::showdict
*proc -name punk::lib::showdict -help "display dictionary keys and values"
@id -id ::punk::lib::showdict
@cmd -name punk::lib::showdict -help "display dictionary keys and values"
#todo - table tableobject
-return -default "tailtohead" -choices {tailtohead sidebyside}
-channel -default none
-trimright -default 1 -type boolean -help "Trim whitespace off rhs of each line.
This can help prevent a single long line that wraps in terminal from making every line wrap due to long rhs padding
"
-trimright -default 1 -type boolean -help\
"Trim whitespace off rhs of each line.
This can help prevent a single long line that wraps in terminal from making
every line wrap due to long rhs padding.
"
-separator -default {%sep%} -help "Separator column between keys and values"
-separator_mismatch -default {%sep_mismatch%} -help "Separator to use when patterns mismatch"
-roottype -default "dict" -help "list,dict,string"
@ -1114,7 +1116,7 @@ namespace eval punk::lib {
-keysortdirection -default increasing -choices {increasing decreasing}
-debug -default 0 -type boolean -help\
"When enabled, produces some rudimentary debug output on stderr"
*values -min 1 -max -1
@values -min 1 -max -1
dictvalue -type list -help "dict or list value"
patterns -default "*" -type string -multiple 1 -help "key or key glob pattern"
}] $args]
@ -2816,7 +2818,7 @@ namespace eval punk::lib {
#eat or own dogfood version - shows the implementation is simpler - but unfortunately not suitable for a simple function like this which should be as fast as possible?
lassign [tcl::dict::values [punk::args::get_dict {
-joinchar -default \n
*values -min 1 -max 1
@values -min 1 -max 1
} $args]] leaders opts values
puts "opts:$opts"
puts "values:$values"
@ -2857,7 +2859,7 @@ namespace eval punk::lib {
#we don't have to decide what is an opt vs a value
#even if the caller provides the argument -block without a value the next function's validation will report a reasonable error because there is now nothing in $values (consumed by -block)
lassign [tcl::dict::values [punk::args::get_dict {
*opts -any 1
@opts -any 1
-block -default {}
} $args]] leaderdict opts valuedict
tailcall linelist {*}$opts {*}[tcl::dict::values $valuedict]

3
src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/mix/commandset/doc-0.1.0.tm

@ -168,9 +168,10 @@ namespace eval punk::mix::commandset::doc {
}
proc validate {args} {
set argd [punk::args::get_dict {
@id -id ::punk::mix::commandset::doc::validate
-- -type none -optional 1 -help "end of options marker --"
-individual -type boolean -default 1
*values -min 0 -max -1
@values -min 0 -max -1
patterns -default {*.man} -type any -multiple 1
} $args]
set opt_individual [tcl::dict::get $argd opts -individual]

6
src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/mix/commandset/layout-0.1.0.tm

@ -34,7 +34,8 @@ namespace eval punk::mix::commandset::layout {
#per layout functions
proc files {{layout ""}} {
set argd [punk::args::get_dict {
*values -min 1 -max 1
@id -id ::punk::mix::commandset::layout::files
@values -min 1 -max 1
layout -type string -minsize 1
} [list $layout]]
@ -88,7 +89,8 @@ namespace eval punk::mix::commandset::layout {
proc _default {args} {
punk::args::get_dict [subst {
*proc -name ::punk::mix::commandset::layout::collection::_default
@id -id ::punk::mix::commandset::layout::collection::_default
@cmd -name ::punk::mix::commandset::layout::collection::_default
-startdir -type string
-not -type string -multiple 1
globsearches -default * -multiple 1

18
src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/mix/commandset/loadedlib-0.1.0.tm

@ -27,20 +27,24 @@ namespace eval punk::mix::commandset::loadedlib {
namespace export *
#search automatically wrapped in * * - can contain inner * ? globs
punk::args::definition {
*id punk::mix::commandset::loadedlib::search
*proc -name "punk::mix::commandset::loadedlib search" -help "search all Tcl libraries available to your local interpreter"
@id -id ::punk::mix::commandset::loadedlib::search
@cmd -name "punk::mix::commandset::loadedlib search" -help "search all Tcl libraries available to your local interpreter"
-return -type string -default table -choices {table tableobject list lines}
-present -type integer -default 2 -choices {0 1 2} -choicelabels {absent present both} -help\
"(unimplemented) Display only those that are 0:absent 1:present 2:both"
-highlight -type boolean -default 1 -help "Highlight which version is present with ansi underline and colour"
"(unimplemented) Display only those that are 0:absent 1:present 2:either"
-highlight -type boolean -default 1 -help\
"Highlight which version is present with ansi underline and colour"
-refresh -default 0 -type boolean -help "Re-scan the tm and library folders"
searchstrings -default * -multiple 1 -help\
"Names to search for, may contain glob chars (* ?) e.g *lib*
If no glob chars are explicitly specified, the searchstring will be wrapped with star globs.
eg name -> *name*"
eg name -> *name*
To search for an exact name prefix it with =
e.g =name -> name
"
}
proc search {args} {
set argd [punk::args::get_by_id punk::mix::commandset::loadedlib::search $args]
set argd [punk::args::get_by_id ::punk::mix::commandset::loadedlib::search $args]
set searchstrings [dict get $argd values searchstrings]
set opts [dict get $argd opts]
set opt_return [dict get $opts -return]
@ -55,7 +59,7 @@ namespace eval punk::mix::commandset::loadedlib {
set packages [package names]
set matches [list]
foreach search $searchstrings {
if {[regexp {[?*]} $search]} {
if {[regexp {[?*\[]} $search]} {
#caller has specified specific glob pattern - use it
#todo - respect supplied case only if uppers present? require another flag?
lappend matches {*}[lsearch -all -inline -nocase $packages $search]

13
src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/mix/commandset/module-0.1.0.tm

@ -123,10 +123,11 @@ namespace eval punk::mix::commandset::module {
#return all module templates with repeated ones suffixed with .2 .3 etc
proc templates_dict {args} {
set argspec {
*proc -name templates_dict -help "Templates from module and project paths"
@id -id ::punk::mix::commandset::module::templates_dict
@cmd -name templates_dict -help "Templates from module and project paths"
-startdir -default "" -help "Project folder used in addition to module paths"
-not -default "" -multiple 1
*values
@values
globsearches -default * -multiple 1
}
set argd [punk::args::get_dict $argspec $args]
@ -141,8 +142,8 @@ namespace eval punk::mix::commandset::module {
set moduletypes [punk::mix::cli::lib::module_types]
punk::args::definition [subst {
*id punk::mix::commandset::module::new
*proc -name "punk::mix::commandset::module::new" -help\
@id -id ::punk::mix::commandset::module::new
@cmd -name "punk::mix::commandset::module::new" -help\
"Create a new module file in the appropriate folder within src/modules.
If the name given in the module argument is namespaced,
the necessary subfolder(s) will be used or created."
@ -160,7 +161,7 @@ namespace eval punk::mix::commandset::module {
If false (default) an error will be raised if there is a conflict."
-quiet -default 0 -type boolean -help\
"Suppress information messages on stdout"
*values -min 1 -max 1
@values -min 1 -max 1
module -type string -help\
"Name of module, possibly including a namespace and/or version number
e.g mynamespace::mymodule-1.0"
@ -168,7 +169,7 @@ namespace eval punk::mix::commandset::module {
proc new {args} {
set year [clock format [clock seconds] -format %Y]
# use \uFFFD because unicode replacement char should consistently render as 1 wide
set argd [punk::args::get_by_id punk::mix::commandset::module::new $args]
set argd [punk::args::get_by_id ::punk::mix::commandset::module::new $args]
lassign [dict values $argd] leaders opts values received
set module [dict get $values module]

8
src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/mix/commandset/scriptwrap-0.1.0.tm

@ -1262,15 +1262,15 @@ namespace eval punk::mix::commandset::scriptwrap {
# [list_begin arguments]
# [arg_def string args] name-value pairs -scriptpath <path>
# [list_end]
*id punk::mix::commandset::scriptwrap
*proc -name punk::mix::commandset::get_wrapper_folders
@id -id ::punk::mix::commandset::scriptwrap
@cmd -name punk::mix::commandset::get_wrapper_folders
*opts -anyopts 0
@opts -anyopts 0
-scriptpath -default "" -type directory\
-help ""
#todo -help folder within a punk.templates provided area???
*values -minvalues 0 -maxvalues 0
@values -minvalues 0 -maxvalues 0
} $args]
# -- --- --- --- --- --- --- --- ---

34
src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/nav/fs-0.1.0.tm

@ -636,13 +636,14 @@ tcl::namespace::eval punk::nav::fs {
# c:/repo/jn/punk/../../blah
#dirfiles assumes we don't have glob chars in the filenames or paths - dirfiles_dict can be called directly with explicit -tailglob in the rare case that assumption doesn't hold
# dirfiles will test last segment (tail) of supplied searchspecs for fileness vs folderness (when no globchars present in tail) so that it can pass the appropriate flags downstream
punk::args::definition {
@id -id ::punk::nav::fs::dirfiles
-stripbase -default 1 -type boolean
-formatsizes -default 1 -type boolean -help "Format file size numbers for clarity"
@values -min 0 -max -1
}
proc dirfiles {args} {
set argspecs {
-stripbase -default 1 -type boolean
-formatsizes -default 1 -type boolean -help "Format file size numbers for clarity"
*values -min 0 -max -1
}
set argd [punk::args::get_dict $argspecs $args]
set argd [punk::args::get_by_id ::punk::nav::fs::dirfiles $args]
lassign [dict values $argd] leaders opts values_dict
set opt_stripbase [dict get $opts -stripbase]
@ -726,14 +727,14 @@ tcl::namespace::eval punk::nav::fs {
# -searchbase is always passed through - and is only used to construct a location path if a relative searchspec was supplied
proc dirfiles_dict {args} {
set argspecs {
*id punk::nav::fs::dirfiles_dict
*opts -any 0
@id -id ::punk::nav::fs::dirfiles_dict
@opts -any 0
-searchbase -default ""
-tailglob -default "\uFFFF"
#with_sizes & with_times must accept 0|1|f|d|l where f = files d = dirs l = links (punk::du)
-with_sizes -default "\uFFFF" -type string
-with_times -default "\uFFFF" -type string
*values -min 0 -max -1 -type string
@values -min 0 -max -1 -type string
}
set argd [punk::args::get_dict $argspecs $args]
lassign [dict values $argd] leaders opts vals
@ -991,16 +992,17 @@ tcl::namespace::eval punk::nav::fs {
return [dict merge $listing $updated]
}
punk::args::definition {
@id -id ::punk::nav::fs::dirfiles_dict_as_lines
-stripbase -default 0 -type boolean
-formatsizes -default 1 -type boolean
@values -min 1 -max -1 -type dict
}
#todo - color key via repl-telemetry? help command? documentation? or add tag columns as done in namespace listing?
proc dirfiles_dict_as_lines {args} {
package require overtype
set argspecs {
-stripbase -default 0 -type boolean
-formatsizes -default 1 -type boolean
*values -min 1 -max -1 -type dict
}
set argd [punk::args::get_dict $argspecs $args]
set argd [punk::args::get_by_id ::punk::nav::fs::dirfiles_dict_as_lines $args]
lassign [dict values $argd] leaders opts vals
set list_of_dicts [dict values $vals]

421
src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/ns-0.1.0.tm

@ -1608,7 +1608,7 @@ tcl::namespace::eval punk::ns {
if {$word1 eq "punk::mix::base::_cli"} {
#special case for punk deck - REVIEW
#e.g punk::mix::base::_cli -extension ::punk::mix::cli
set fq [lindex $tgt end]
set fq [lindex $tgt end] ;#todo - explicitly get -extension argval in case _cli extended with other options
} else {
#todo - alias may have prefilled some leading args - so usage report should reflect that???
#(currying)
@ -1618,7 +1618,8 @@ tcl::namespace::eval punk::ns {
set fq [nsjoin $location $c]
}
if {$has_punkargs} {
set id [string trimleft $fq :]
#set id [string trimleft $fq :]
set id $fq
if {[::punk::args::id_exists $id]} {
lappend usageinfo $c
} else {
@ -1892,110 +1893,188 @@ tcl::namespace::eval punk::ns {
}
} |data@@ok/result> {lmap v $data {punk::ns::nstail $v}} |> lsort |> {join $data \n} <ns/0|
proc ensemble_subcommands {origin} {
set ensembleinfo [namespace ensemble configure $origin]
set prefixes [dict get $ensembleinfo -prefixes]
set map [dict get $ensembleinfo -map]
set ns [dict get $ensembleinfo -namespace]
#review - we can have a combination of commands from -map as well as those exported from -namespace
# if and only if -subcommands is specified
set subcommand_dict [dict create]
set commands [list]
set nscommands [list]
if {[llength [dict get $ensembleinfo -subcommands]]} {
#set exportspecs [namespace eval $ns {namespace export}]
#foreach pat $exportspecs {
# lappend nscommands {*}[info commands ${ns}::$pat]
#}
#when using -subcommands, even unexported commands are available
set nscommands [info commands ${ns}::*]
foreach sub [dict get $ensembleinfo -subcommands] {
if {[dict exists $map $sub]} {
#-map takes precence over same name exported from -namespace
dict set subcommand_dict $sub [dict get $map $sub]
} elseif {"${ns}::$sub" in $nscommands} {
dict set subcommand_dict $sub ${ns}::$sub
} else {
#subcommand probably supplied via -unknown handler?
dict set subcommand_dict $sub ""
}
}
} else {
if {[dict size $map]} {
set subcommand_dict $map
} else {
set exportspecs [namespace eval $ns {namespace export}]
foreach pat $exportspecs {
lappend nscommands {*}[info commands ${ns}::$pat]
}
foreach fqc $nscommands {
dict set subcommand_dict [namespace tail $fqc] $fqc
}
}
}
return $subcommand_dict
}
#todo - -cache or -refresh to configure whether we introspect ensembles/objects each time?
# - as this is interactive generally introspection should be ok at the top level
# but if we need to go down multiple levels of subcommands generating/testing prefixes - could be an issue ??
punk::args::definition {
*id punk::ns::arginfo
*proc -name punk::ns::arginfo -help\
"Show usage info for a command"
@id -id ::punk::ns::arginfo
@cmd -name punk::ns::arginfo -help\
"Show usage info for a command.
It supports the following:
1) Procedures or builtins for which a punk::args definition has
been loaded.
2) tepam procedures (returns string form only)
3) ensemble commands - auto-generated unless documented via punk::args
(subcommands will show with an indicator if they are
explicitly documented or are themselves ensembles)
4) tcl::oo objects - auto-gnerated unless documented via punk::args
5) dereferencing of aliases to find underlying command
(will not work with some renamed aliases)
Note that native commands commands not explicitly documented will
generally produce no useful info. For example sqlite3 dbcmd objects
could theoretically be documented - but as 'info cmdtype' just shows
'native' they can't (?) be identified as belonging to sqlite3 without
calling them. arginfo deliberately avoids calling commands to elicit
usage information as this is inherently risky. (could create a file,
exit the interp etc)
"
-return -type string -default table -choices {string table tableobject}
-- -type none -help\
"End of options marker
Use this if the command to view begins with a -"
*values -min 1
@values -min 1
commandpath -help\
"command (may be alias or ensemble)"
"command (may be alias, ensemble, tcl::oo object, tepam proc etc)"
subcommand -optional 1 -multiple 1 -default {} -help\
"subcommand if commandpath is an ensemble.
Multiple subcommands can be supplied if ensembles are further nested"
}
proc arginfo {args} {
lassign [dict values [punk::args::get_by_id punk::ns::arginfo $args]] leaders opts values received
set commandpath [dict get $values commandpath]
set commandargs [dict get $values subcommand]
lassign [dict values [punk::args::get_by_id ::punk::ns::arginfo $args]] leaders opts values received
set querycommand [dict get $values commandpath]
set queryargs [dict get $values subcommand]
punk::args::update_definitions ;#ensure any packages that register PUNKARGS have been loaded
#todo - similar to corp? review corp resolution process
#should handle lazy loaded commands (via ::auto_index) that are not yet present but may be documented
if {[string match ::* $commandpath]} {
set targetns [nsprefix $commandpath]
set name [nstail $commandpath]
#don't use 'info commands $commandpath' - or Tcl will use 'namespace path' resolution to find command in another ns or in global
if {[string match ::* $querycommand]} {
set targetns [nsprefix $querycommand]
set name [nstail $querycommand]
#don't use 'info commands $querycommand' - or Tcl will use 'namespace path' resolution to find command in another ns or in global
#when arginfo given a fully qualified path - we only want an answer for that exact command
set nscommands [info commands ${targetns}::*]
if {[lsearch -exact $nscommands $commandpath] >= 0} {
if {[lsearch -exact $nscommands $querycommand] >= 0} {
#use nseval_ifexists to avoid creating intermediate namespaces for bogus paths
if {[catch {
set origin [nseval_ifexists $targetns [list ::namespace origin $name]]
set resolved [nseval_ifexists $targetns [list ::namespace which $name]]
}]} {
set origin $commandpath
set resolved $commandpath
set origin $querycommand
set resolved $querycommand
}
} else {
#fully qualified command specified but doesn't exist
set origin $commandpath
set resolved $commandpath
set origin $querycommand
set resolved $querycommand
}
} else {
set thispath [uplevel 1 [list ::nsthis $commandpath]]
set targetns [nsprefix $thispath]
set name [nstail $thispath]
set targetparts [nsparts $targetns]
if {[lsearch $targetparts :*] >=0} {
#weird ns
set valid_ns [nsexists $targetns]
#relative comandpath
if {[string match (autodef)* $querycommand]} {
#pass through - should be found with id lookup
set origin $querycommand
set resolved $querycommand
} else {
set valid_ns [namespace exists $targetns]
}
if {$valid_ns} {
if {[catch {
set origin [nseval_ifexists $targetns [list ::namespace origin $name]]
set resolved [nseval_ifexists $targetns [list ::namespace which $name]]
}]} {
set thiscmd [nsjoin $targetns $name]
#relative commandpath specified - but Tcl didn't find a match in namespace path
#assume global (todo - look for namespace match in auto_index first ?)
set origin ::$name
set resolved ::$name
set thispath [uplevel 1 [list ::nsthis $querycommand]]
set targetns [nsprefix $thispath]
set name [nstail $thispath]
set targetparts [nsparts $targetns]
if {[lsearch $targetparts :*] >=0} {
#weird ns
set valid_ns [nsexists $targetns]
} else {
set valid_ns [namespace exists $targetns]
}
if {$valid_ns} {
if {[catch {
set origin [nseval_ifexists $targetns [list ::namespace origin $name]]
set resolved [nseval_ifexists $targetns [list ::namespace which $name]]
}]} {
set thiscmd [nsjoin $targetns $name]
#relative querycommand specified - but Tcl didn't find a match in namespace path
#assume global (todo - look for namespace match in auto_index first ?)
set origin ::$name
set resolved ::$name
}
} else {
#namespace as relative to current doesn't seem to exist
#Tcl would also attempt to resolve as global
set numvals [expr {[llength $queryargs]+1}]
#puts "THROWBACK: namespace eval :: [list punk::ns::arginfo {*}[lrange $args 0 end-$numvals] $querycommand {*}$queryargs]"
return [namespace eval :: [list punk::ns::arginfo {*}[lrange $args 0 end-$numvals] $querycommand {*}$queryargs]]
#set origin $querycommand
#set resolved $querycommand
}
} else {
#namespace doesn't seem to exist - but there still could be documentation for lazy loaded ns and command
set origin $commandpath
set resolved $commandpath
}
}
#set thiscmd [nsjoin $targetns $name]
#if {[info commands $thiscmd] eq ""} {
# set origin $thiscmd
# set resolved $thiscmd
#} else {
# set origin [nseval $targetns [list ::namespace origin $name]]
# set resolved [nseval $targetns [list ::namespace which $name]]
#}
}
}
#ns::cmdtype only detects alias type on 8.7+?
set initial_cmdtype [punk::ns::cmdtype $origin]
switch -- $initial_cmdtype {
na - alias {
#REVIEW - alias entry doesn't necessarily match command!
#considure using which_alias (wiki)
#consider using which_alias (wiki)
set tgt [interp alias "" $origin]
if {$tgt eq ""} {
set tgt [interp alias "" [string trimleft $origin :]]
}
#first word of tgt may be namespace relative or absolute
if {$tgt ne ""} {
set word1 [lindex $tgt 0]
if {$word1 eq "punk::mix::base::_cli"} {
#special case for punk deck - REVIEW
#e.g punk::mix::base::_cli -extension ::punk::mix::cli
set fq [lindex $tgt end]
set targetword [lindex $tgt end]
} else {
#todo - alias may have prefilled some leading args - so usage report should reflect that???
#(possible curried arguments)
#review - curried arguments could be for ensembles!
set fq $word1
set targetword $word1
set numvals [expr {[llength $queryargs]+1}]
#puts "ALIAS THROWBACK: namespace eval :: [list punk::ns::arginfo {*}[lrange $args 0 end-$numvals] $targetword {*}[lrange $tgt 1 end] {*}$queryargs]"
return [namespace eval :: [list punk::ns::arginfo {*}[lrange $args 0 end-$numvals] $targetword {*}[lrange $tgt 1 end] {*}$queryargs]]
}
set origin $fq
set origin $targetword
#retest cmdtype on modified origin
set cmdtype [punk::ns::cmdtype $origin]
} else {
@ -2013,6 +2092,83 @@ tcl::namespace::eval punk::ns {
}
}
set id $origin
if {[info commands ::punk::args::id_exists] ne ""} {
#cycle through longest first checking for id matching ::cmd ?subcmd..?
#REVIEW - this doesn't cater for prefix callable subcommands!
set argcopy $queryargs
while {[llength $argcopy]} {
if {[punk::args::id_exists [list $id {*}$argcopy]]} {
return [uplevel 1 [list punk::args::usage {*}$opts [list $id {*}$argcopy]]]
}
lpop argcopy
}
#didn't find any exact matches
#traverse from other direction taking prefixes into account
if {[punk::args::id_exists $id]} {
#cycle forward through leading values
set def [punk::args::get_def $id]
if {[llength $queryargs]} {
set nextqueryargs [list] ;#build a list of prefix-resolved queryargs
set queryargs_untested $queryargs
foreach q $queryargs {
if {[llength [dict get $def leader_names]]} {
set subitems [dict get $def leader_names]
if {[llength $subitems]} {
set next [lindex $subitems 0]
set arginfo [dict get $def arg_info $next]
set allchoices [list]
set choices [punk::args::system::Dict_getdef $arginfo -choices {}]
set choicegroups [punk::args::system::Dict_getdef $arginfo -choicegroups {}]
if {[dict exists $choicegroups ""]} {
dict lappend choicegroups "" {*}$choices
} else {
set choicegroups [dict merge [dict create "" $choices] $choicegroups]
}
dict for {groupname clist} $choicegroups {
lappend allchoices {*}$clist
}
set resolved_q [tcl::prefix::match -error "" $allchoices $q]
if {$resolved_q eq ""} {
break
}
lappend nextqueryargs $resolved_q
lpop queryargs_untested 0
if {$resolved_q ne $q} {
#we have our first difference - recurse with new query args
set numvals [expr {[llength $queryargs]+1}]
return [ punk::ns::arginfo {*}[lrange $args 0 end-$numvals] $querycommand {*}$nextqueryargs {*}$queryargs_untested]
}
#check if subcommands so far have a custom args def
set currentid [list $querycommand {*}$nextqueryargs]
if {[punk::args::id_exists $currentid]} {
set def [punk::args::get_def $currentid
} else {
#We can get no further with custom defs
break
}
}
} else {
#review
break
}
}
} else {
return [uplevel 1 [list punk::args::usage {*}$opts $id]]
}
}
}
if {[string match "(autodef)*" $origin]} {
#wasn't resolved by id - so take this as a request to generate it (probably there is an existing custom def - and this has been manually requested to get the default)
set origin [string range $origin [string length (autodef)] end]
set resolved $origin
}
switch -- $cmdtype {
object {
#class is also an object
@ -2025,19 +2181,19 @@ tcl::namespace::eval punk::ns {
#set class_methods [info class methods $class]
#set object_methods [info object methods $origin]
if {[llength $commandargs]} {
set c1 [lindex $commandargs 0]
if {[llength $queryargs]} {
set c1 [lindex $queryargs 0]
if {$c1 in $public_methods} {
switch -- $c1 {
new {
set constructorinfo [info class constructor $origin]
set arglist [lindex $constructorinfo 0]
set argspec [punk::lib::tstr -return string {
*id "${$origin} new"
*proc -name "${$origin} new" -help\
@id -id "(autodef)${$origin} new"
@cmd -name "${$origin} new" -help\
"create object with specified command name.
Arguments are passed to the constructor."
*values
@values
}]
set i 0
foreach a $arglist {
@ -2054,17 +2210,17 @@ tcl::namespace::eval punk::ns {
incr i
}
punk::args::definition $argspec
return [punk::args::usage {*}$opts "$origin new"]
return [punk::args::usage {*}$opts "(autodef)$origin new"]
}
create {
set constructorinfo [info class constructor $origin]
set arglist [lindex $constructorinfo 0]
set argspec [punk::lib::tstr -return string {
*id "${$origin} create"
*proc -name "${$origin} create" -help\
@id -id "(autodef)${$origin} create"
@cmd -name "${$origin} create" -help\
"create object with specified command name.
Arguments following objectName are passed to the constructor."
*values -min 1
@values -min 1
objectName -type string -help\
"possibly namespaced name for object instance command"
}]
@ -2083,20 +2239,20 @@ tcl::namespace::eval punk::ns {
incr i
}
punk::args::definition $argspec
return [punk::args::usage {*}$opts "$origin create"]
return [punk::args::usage {*}$opts "(autodef)$origin create"]
}
destroy {
#review - generally no doc
# but we may want notes about a specific destructor
set argspec [punk::lib::tstr -return string {
*id "${$origin} destroy"
*proc -name "destroy" -help\
@id -id "(audodef)${$origin} destroy"
@cmd -name "destroy" -help\
"delete object, calling destructor if any.
destroy accepts no arguments."
*values -min 0 -max 0
@values -min 0 -max 0
}]
punk::args::definition $argspec
return [punk::args::usage {*}$opts "$origin destroy"]
return [punk::args::usage {*}$opts "(autodef)$origin destroy"]
}
default {
#use info object call <obj> <method> to resolve callchain
@ -2111,20 +2267,24 @@ tcl::namespace::eval punk::ns {
lassign $impl generaltype mname location methodtype
switch -- $generaltype {
method - private {
#objects being dynamic systems - we should always reinspect.
#Don't use the cached (autodef) def
#If there is a custom def override - use it (should really be -dynamic - but we don't check)
if {$location eq "object"} {
set id "[string trimleft $origin :] $c1" ;# "<object> <method>"
set idcustom "$origin $c1"
#set id "[string trimleft $origin :] $c1" ;# "<object> <method>"
if {[info commands ::punk::args::id_exists] ne ""} {
if {[punk::args::id_exists $id]} {
return [uplevel 1 [list punk::args::usage {*}$opts $id]]
if {[punk::args::id_exists $idcustom]} {
return [uplevel 1 [list punk::args::usage {*}$opts $idcustom]]
}
}
set def [::info object definition $origin $c1]
} else {
set id "[string trimleft $location :] $c1" ;# "<class> <method>"
#set id "[string trimleft $location :] $c1" ;# "<class> <method>"
set idcustom "$location $c1"
if {[info commands ::punk::args::id_exists] ne ""} {
if {[punk::args::id_exists $id]} {
return [uplevel 1 [list punk::args::usage {*}$opts $id]]
if {[punk::args::id_exists $idcustom]} {
return [uplevel 1 [list punk::args::usage {*}$opts $idcustom]]
}
}
set def [::info class definition $location $c1]
@ -2138,12 +2298,15 @@ tcl::namespace::eval punk::ns {
}
}
if {$def ne ""} {
#assert - if we pre
set autoid "(autodef)$location $c1"
set arglist [lindex $def 0]
set argspec [punk::lib::tstr -return string {
*id "${$location} ${$c1}"
*proc -name "${$location} ${$c1}" -help\
"arglist:${$arglist}"
*values
@id -id "${$autoid}"
@cmd -name "${$location} ${$c1}" -help\
"(autogenerated)
arglist:${$arglist}"
@values
}]
set i 0
foreach a $arglist {
@ -2166,7 +2329,7 @@ tcl::namespace::eval punk::ns {
incr i
}
punk::args::definition $argspec
return [punk::args::usage {*}$opts "$location $c1"]
return [punk::args::usage {*}$opts $autoid]
} else {
return "unable to resolve $origin method $c1"
}
@ -2189,9 +2352,11 @@ tcl::namespace::eval punk::ns {
switch -- $generaltype {
method - private {
if {$location eq "object"} {
set id "[string trimleft $origin :] $cmd" ;# "<object> <method>"
#set id "[string trimleft $origin :] $cmd" ;# "<object> <method>"
set id "$origin $cmd"
} else {
set id "[string trimleft $location :] $cmd" ;# "<class> <method>"
#set id "[string trimleft $location :] $cmd" ;# "<class> <method>"
set id "$location $cmd"
}
if {[info commands ::punk::args::id_exists] ne ""} {
if {[punk::args::id_exists $id]} {
@ -2212,15 +2377,16 @@ tcl::namespace::eval punk::ns {
set vline [list method -choices $public_methods -choicelabels $choicelabeldict -choiceprefix 0] ;#methods must be specified in full always? - review
#puts stderr "--->$vline"
set idauto "(autodef)$origin"
set argspec [punk::lib::tstr -return string {
*id ${$origin}
*proc -name "Object: ${$origin}" -help\
"Instance of class: ${$class}"
*values -min 1
@id -id ${$idauto}
@cmd -name "Object: ${$origin}" -help\
"Instance of class: ${$class} (info autogenerated)"
@values -min 1
}]
append argspec \n $vline
punk::args::definition $argspec
return [punk::args::usage {*}$opts $origin]
return [punk::args::usage {*}$opts $idauto]
}
privateObject {
return "Command is a privateObject - no info currently available"
@ -2287,11 +2453,11 @@ tcl::namespace::eval punk::ns {
set subcommands [lsort [dict keys $subcommand_dict]]
if {[llength $commandargs]} {
set match [tcl::prefix::match $subcommands [lindex $commandargs 0]]
if {[llength $queryargs]} {
set match [tcl::prefix::match $subcommands [lindex $queryargs 0]]
if {$match in $subcommands} {
set subcmd [dict get $subcommand_dict $match]
return [arginfo {*}$subcmd {*}[lrange $commandargs 1 end]] ;#subcmd is sometimes multiple words (implemented as a further ensemble subcommand) (e.g huddle string -> "Type_string string")
return [arginfo {*}$subcmd {*}[lrange $queryargs 1 end]] ;#subcmd is sometimes multiple words (implemented as a further ensemble subcommand) (e.g huddle string -> "Type_string string")
}
}
@ -2307,9 +2473,9 @@ tcl::namespace::eval punk::ns {
set is_object [list]
foreach ns $namespaces {
set nsinfo [lindex [punk::ns::nslist_dict [nsjoin [nsprefix $ns] *]] 0]
lappend have_usageinfo {*}[dict get $nsinfo usageinfo]
lappend is_ensemble {*}[dict get $nsinfo ensembles]
lappend is_object {*}[dict get $nsinfo ooobjects]
lappend have_usageinfo {*}[dict get $nsinfo usageinfo]
lappend is_ensemble {*}[dict get $nsinfo ensembles]
lappend is_object {*}[dict get $nsinfo ooobjects]
}
set choicelabeldict [dict create]
@ -2324,14 +2490,17 @@ tcl::namespace::eval punk::ns {
}
set vline [list subcommand -choices $subcommands -choiceprefix $prefixes -choicelabels $choicelabeldict]
set autoid "(autodef)$origin"
set argspec [punk::lib::tstr -return string {
*id ${$origin}
*proc -help "ensemble: ${$origin}"
*values -min 1
@id -id ${$autoid}
@cmd -help\
"(autogenerated)
ensemble: ${$origin}"
@values -min 1
}]
append argspec \n $vline
punk::args::definition $argspec
return [punk::args::usage {*}$opts $origin]
return [punk::args::usage {*}$opts $autoid]
}
#check for tepam help
@ -2364,12 +2533,6 @@ tcl::namespace::eval punk::ns {
}
}
set id [string trimleft $origin :]
if {[info commands ::punk::args::id_exists] ne ""} {
if {[punk::args::id_exists $id]} {
return [uplevel 1 [list punk::args::usage {*}$opts $id]]
}
}
set origin_ns [nsprefix $origin]
set parts [nsparts $origin_ns]
set weird_ns 0
@ -2379,24 +2542,42 @@ tcl::namespace::eval punk::ns {
if {$weird_ns} {
set argl {}
set tail [nstail $origin]
foreach a [nseval_ifexists $origin_ns [list info args $tail]] {
if {[nseval_ifexists $origin_ns [list info default $tail $a def]]} {
lappend a $def
set cmdtype [nseval_ifexists $origin_ns [list punk::ns::cmdtype $tail]]
if {$cmdtype eq "proc"} {
foreach a [nseval_ifexists $origin_ns [list info args $tail]] {
if {[nseval_ifexists $origin_ns [list info default $tail $a def]]} {
lappend a $def
}
lappend argl $a
}
lappend argl $a
}
} else {
set argl {}
foreach a [info args $origin] {
if {[info default $origin $a def]} {
lappend a $def
set cmdtype [punk::ns::cmdtype $origin]
if {$cmdtype eq "proc"} {
set argl {}
set infoargs [info args $origin]
foreach a $infoargs {
if {[info default $origin $a def]} {
lappend a $def
}
lappend argl $a
}
lappend argl $a
}
}
set msg "No argument processor detected"
append msg \n "function signature: $resolved $argl"
if {[llength $queryargs]} {
#todo - something better
set msg "Undocumented or nonexistant subcommand $origin $queryargs"
append msg \n "$origin Type: $cmdtype"
} else {
if {$cmdtype eq "proc"} {
set msg "Undocumented proc $origin"
append msg \n "No argument processor detected"
append msg \n "function signature: $resolved $argl"
} else {
set msg "Undocumented command $origin. Type: $cmdtype"
}
}
return $msg
}
@ -2738,8 +2919,8 @@ tcl::namespace::eval punk::ns {
interp alias "" use "" punk::ns::pkguse
punk::args::definition {
*id punk::ns::nsimport_noclobber
*proc -name punk::ns::nsimport_noclobber -help\
@id -id ::punk::ns::nsimport_noclobber
@cmd -name punk::ns::nsimport_noclobber -help\
"Import exported commands from a namespace into either the current namespace,
or that specified in -targetnamespace.
Return list of imported commands, ignores failures due to name conflicts"
@ -2750,14 +2931,14 @@ tcl::namespace::eval punk::ns {
If not supplied, caller's namespace is used."
-prefix -optional 1 -help\
"string prefix for command names in target namespace"
*values -min 1 -max 1
@values -min 1 -max 1
sourcepattern -type string -optional 0 -help\
"Glob pattern for source namespace.
Globbing only active in the tail segment.
e.g ::mynamespace::*"
}
proc nsimport_noclobber {args} {
lassign [dict values [punk::args::get_by_id punk::ns::nsimport_noclobber $args]] leaders opts values received
lassign [dict values [punk::args::get_by_id ::punk::ns::nsimport_noclobber $args]] leaders opts values received
set sourcepattern [dict get $values sourcepattern]
set source_ns [tcl::namespace::qualifiers $sourcepattern]

6
src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/path-0.1.0.tm

@ -645,14 +645,14 @@ namespace eval punk::path {
}
punk::args::definition {
*id punk::path::treefilenames
@id -id ::punk::path::treefilenames
-directory -type directory -help\
"folder in which to begin recursive scan for files."
-call-depth-internal -default 0 -type integer
-antiglob_paths -default {} -help\
"list of path patterns to exclude
may include * and ** path segments e.g /usr/**"
*values -min 0 -max -1 -optional 1 -type string
@values -min 0 -max -1 -optional 1 -type string
tailglobs -multiple 1 -help\
"Patterns to match against filename portion (last segment) of each file path
within the directory tree being searched."
@ -671,7 +671,7 @@ namespace eval punk::path {
#[para] list of path patterns to exclude - may include * and ** path segments e.g /usr/**
#[para]no natsorting - so order is dependent on filesystem
set argd [punk::args::get_by_id punk::path::treefilenames $args]
set argd [punk::args::get_by_id ::punk::path::treefilenames $args]
lassign [dict values $argd] leaders opts values received
set tailglobs [dict values $values]
# -- --- --- --- --- --- ---

84
src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/repo-0.1.1.tm

@ -62,6 +62,73 @@ package require punk::mix::util ;#do_in_path
# -- --- --- --- --- --- --- --- --- --- ---
namespace eval punk::repo {
variable PUNKARGS
variable PUNKARGS_aliases
proc get_fossil_usage {} {
set allcmds [runout -n fossil help -a]
set mainhelp [runout -n fossil help]
set maincommands [list]
foreach ln [split $mainhelp \n] {
set ln [string trim $ln]
if {$ln eq "" || [regexp {^[A-Z]+} $ln]} {
continue
}
lappend maincommands {*}$ln
}
set othercmds [punk::lib::ldiff $allcmds $maincommands]
set result "@leaders -min 0\n"
append result [tstr -return string {
subcommand -type string -choicecolumns 8 -choicegroups {
"frequently used commands" {${$maincommands}}
"" {${$othercmds}}
}
}]
return $result
}
#lappend PUNKARGS [list -dynamic 1 {
# @id -id ::punk::repo::fossil_proxy
# @cmd -name fossil -help "fossil executable
# "
# @argdisplay -header "fossil help" -body {${[runout -n fossil help]}}
# } ""]
lappend PUNKARGS [list -dynamic 1 {
@id -id ::punk::repo::fossil_proxy
@cmd -name fossil -help "fossil executable"
${[punk::repo::get_fossil_usage]}
} ]
#experiment
lappend PUNKARGS [list -dynamic 1 {
@id -id "::punk::repo::fossil_proxy diff"
@cmd -name "fossil diff" -help "fossil diff
"
@argdisplay -header "fossil help diff" -body {${[runout -n fossil help diff]}}
} ""]
lappend PUNKARGS [list -dynamic 1 {
@id -id "::punk::repo::fossil_proxy add"
@cmd -name "fossil add" -help "fossil add
"
@argdisplay -header "fossil help add" -body {${[runout -n fossil help add]}}
} ""]
#TODO
#lappend PUNKARGS [list -dynamic 1 {
# @id -glob 1 -id "::punk::repo::fossil_proxy *" -aliases {fs}
# @cmd -name "fossil add" -help "fossil add
# "
# @argdisplay -header "fossil help add" -body {${[runout -n fossil help add]}}
# } ""]
lappend PUNKARGS_aliases {"::fossil" "::punk::repo::fossil_proxy"}
lappend PUNKARGS_aliases {"::fossil diff" "::punk::repo::fossil_proxy diff"}
#Todo - investigate proper way to install a client-side commit hook in the fossil project
#Then we may still use this proxy to check the hook - but the required checks will occur when another shell used
@ -137,7 +204,7 @@ namespace eval punk::repo {
puts stderr "fossil command not found. Please install fossil"
}
}
interp alias "" fossil "" punk::repo::fossil_proxy
# ---
# Calling auto_execok on an external tool can be too slow to do during package load (e.g could be 150ms)
@ -153,6 +220,7 @@ namespace eval punk::repo {
# ----------
#
#uppercase FOSSIL to bypass fossil as alias to fossil_proxy
proc establish_FOSSIL {args} {
if {![info exists ::auto_execs(FOSSIL)]} {
@ -161,7 +229,6 @@ namespace eval punk::repo {
interp alias "" FOSSIL "" ;#delete establishment alias
FOSSIL {*}$args
}
interp alias "" FOSSIL "" punk::repo::establish_FOSSIL
# ----------
proc askuser {question} {
@ -1577,6 +1644,8 @@ namespace eval punk::repo {
}
}
interp alias "" fossil "" punk::repo::fossil_proxy
interp alias "" FOSSIL "" punk::repo::establish_FOSSIL
interp alias {} is_fossil {} ::punk::repo::is_fossil
interp alias {} is_fossil_root {} ::punk::repo::is_fossil_root
@ -1609,6 +1678,17 @@ namespace eval punk::repo::lib {
}
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
if {![info exists ::punk::args::register::NAMESPACES]} {
namespace eval ::punk::args::register {
set ::punk::args::register::NAMESPACES [list] ;#use fully qualified so 8.6 doesn't find existing var in global namespace
}
}
lappend ::punk::args::register::NAMESPACES ::punk::repo
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
## Ready
package provide punk::repo [namespace eval punk::repo {

19
src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/zip-0.1.1.tm

@ -180,10 +180,11 @@ tcl::namespace::eval punk::zip {
#}]
set argd [punk::args::get_dict {
*proc -name punk::zip::walk
@id -id ::punk::zip::walk
@cmd -name punk::zip::walk
-excludes -default "" -help "list of glob expressions to match against files and exclude"
-subpath -default ""
*values -min 1 -max -1
@values -min 1 -max -1
base
fileglobs -default {*} -multiple 1
} $args]
@ -373,11 +374,12 @@ tcl::namespace::eval punk::zip {
#[para] The return value is the central directory record that will need to be used when finalizing the zip archive.
set argd [punk::args::get_dict {
*proc -name punk::zip::Addentry -help "Add a single file at 'path' to open channel 'zipchan'
@id -id ::punk::zip::Addentry
@cmd -name punk::zip::Addentry -help "Add a single file at 'path' to open channel 'zipchan'
return a central directory file record"
*opts
@opts
-comment -default "" -help "An optional comment specific to the added file"
*values -min 3 -max 4
@values -min 3 -max 4
zipchan -help "open file descriptor with cursor at position appropriate for writing a local file header"
base -help "base path for entries"
path -type file -help "path of file to add"
@ -525,9 +527,10 @@ tcl::namespace::eval punk::zip {
#[para] Call 'punk::zip::mkzip' with no arguments for usage display.
set argd [punk::args::get_dict {
*proc -name punk::zip::mkzip\
@id -id ::punk::zip::mkzip
@cmd -name punk::zip::mkzip\
-help "Create a zip archive in 'filename'"
*opts
@opts
-offsettype -default "archive" -choices {archive file}\
-help "zip offsets stored relative to start of entire file or relative to start of zip-archive
Only relevant if the created file has a script/runtime prefix.
@ -557,7 +560,7 @@ tcl::namespace::eval punk::zip {
it must be a parent of -directory or the same path as -directory"
-exclude -default {CVS/* */CVS/* *~ ".#*" "*/.#*"}
*values -min 1 -max -1
@values -min 1 -max -1
filename -type file -default ""\
-help "name of zipfile to create"
globs -default {*} -multiple 1\

139
src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/textblock-0.1.2.tm

@ -123,12 +123,12 @@ tcl::namespace::eval textblock {
set choicemsg " (unavailable packages: $unavailable)"
}
set argd [punk::args::get_dict [tstr -return string {
*id textblock::use_hash
*proc -name "textblock::use_hash" -help\
@id -id ::textblock::use_hash
@cmd -name "textblock::use_hash" -help\
"Hashing algorithm to use for framecache lookup.
'none' may be slightly faster but less compact
when viewing textblock::framecache"
*values -min 0 -max 1
@values -min 0 -max 1
hash_algorithm -choices {${$choices}} -optional 1 -help\
"algorithm choice ${$choicemsg}"
}] $args]
@ -423,7 +423,6 @@ tcl::namespace::eval textblock {
}
}
}
my configure {*}$o_opts_table
#foreach {k v} $args {
# #todo - convert to literal switch using tcl::string::map so we don't have to define o_opts_table_defaults here.
@ -453,6 +452,7 @@ tcl::namespace::eval textblock {
-minheight 1\
-maxheight ""\
]
my configure {*}$o_opts_table
}
method width_algorithm {{alg ""}} {
@ -593,7 +593,7 @@ tcl::namespace::eval textblock {
tcl::dict::set o_opts_table_effective -framelimits_header $hlims
return [tcl::dict::create body $blims header $hlims]
}
method configure args {
method configure {args} {
#*** !doctools
#[call class::table [method configure] [arg args]]
#[para] get or set various table-level properties
@ -781,6 +781,14 @@ tcl::namespace::eval textblock {
}
}
}
-title {
set twidth [punk::ansi::printing_length $v]
if {[my width] < [expr {$twidth+2}]} {
set o_calculated_column_widths [list]
tcl::dict::set o_opts_table -minwidth [expr {$twidth+2}]
}
tcl::dict::set o_opts_table -title $v
}
default {
tcl::dict::set o_opts_table $k $v
}
@ -3943,14 +3951,13 @@ tcl::namespace::eval textblock {
if {$header_build eq "" && ![llength $body_blocks]} {
set header_build $nextcol_header
lappend body_blocks $nextcol_body
} else {
if {$headerheight > 0} {
set header_build [overtype::renderspace -startcolumn [expr {$padwidth + 1}] -expand_right 1 -transparent $TSUB $header_build[unset header_build] $nextcol_header[unset nextcol_header]]
}
lappend body_blocks $nextcol_body
#set body_build [textblock::join -- $body_build[unset body_build] $nextcol_body]
}
lappend body_blocks $nextcol_body
incr padwidth $bodywidth
incr colposn
}
@ -4096,8 +4103,8 @@ tcl::namespace::eval textblock {
}
punk::args::definition {
*id textblock::periodic
*proc -name textblock::periodic -help "A rudimentary periodic table
@id -id ::textblock::periodic
@cmd -name textblock::periodic -help "A rudimentary periodic table
This is primarily a test of textblock::class::table"
-return -default table\
@ -4109,13 +4116,13 @@ tcl::namespace::eval textblock {
-show_header -default "" -type boolean
-show_edge -default "" -type boolean
-forcecolour -default 0 -type boolean -help "If punk::colour is off - this enables the produced table to still be ansi coloured"
*values -min 0 -max 0
@values -min 0 -max 0
}
proc periodic {args} {
#For an impressive interactive terminal app (javascript)
# see: https://github.com/spirometaxas/periodic-table-cli
set opts [dict get [punk::args::get_by_id textblock::periodic $args] opts]
set opts [dict get [punk::args::get_by_id ::textblock::periodic $args] opts]
set opt_return [tcl::dict::get $opts -return]
if {[tcl::dict::get $opts -forcecolour]} {
set fc forcecolour
@ -4345,7 +4352,10 @@ tcl::namespace::eval textblock {
set FRAMETYPES [textblock::frametypes]
punk::args::definition [punk::lib::tstr -return string {
*id textblock::list_as_table
@id -id ::textblock::list_as_table
@cmd -name "textblock::list_as_table" -help\
"Display a list in a bordered table
"
-return -default table -choices {table tableobject}
-frametype -default "light" -type dict -choices {${$FRAMETYPES}} -choicerestricted 0\
@ -4376,13 +4386,13 @@ tcl::namespace::eval textblock {
-help "Number of table columns
Will default to 2 if not using an existing -table object"
*values -min 0 -max 1
@values -min 0 -max 1
datalist -default {} -type list -help "flat list of table cell values which will be wrapped based on -columns value"
}]
proc list_as_table {args} {
set FRAMETYPES [textblock::frametypes]
set argd [punk::args::get_by_id textblock::list_as_table $args]
set argd [punk::args::get_by_id ::textblock::list_as_table $args]
set opts [dict get $argd opts]
set datalist [dict get $argd values datalist]
@ -4894,7 +4904,7 @@ tcl::namespace::eval textblock {
#review!?
#-within_ansi means after a leading ansi code when doing left pad on all but last line
#-within_ansi means before a trailing ansi code when doing right pad on all but last line
set usage "pad ?-padchar <sp>|<character>? ?-which right|left|centre? ?-known_hasansi \"\"|<bool>? ?-known_blockwidth \"\"|<int>? ?-width auto|<int>? ?-within_ansi 1|0?"
set usage "pad block ?-padchar <sp>|<character>? ?-which right|left|centre? ?-known_hasansi \"\"|<bool>? ?-known_blockwidth \"\"|<int>? ?-width auto|<int>? ?-within_ansi 1|0?"
foreach {k v} $args {
switch -- $k {
-padchar - -which - -known_hasansi - -known_samewidth - -known_blockwidth - -width - -overflow - -within_ansi {
@ -5420,16 +5430,21 @@ tcl::namespace::eval textblock {
return [punk::lib::list_as_lines -- $outlines]
}
punk::args::definition {
@id -id ::textblock::join_basic
@cmd -name textblock::join_basic -help\
"Join blocks of text line by line but don't add padding on each line to enforce uniform width.
Already uniform blocks will join faster than textblock::join, and ragged blocks will join in a ragged manner
"
-- -type none -optional 0 -help "end of options marker -- is mandatory because joined blocks may easily conflict with flags"
-ansiresets -type any -default auto
blocks -type any -multiple 1
}
#join without regard to each line length in a block (no padding added to make each block uniform)
proc ::textblock::join_basic {args} {
#*proc -name textblock::join_basic -help "Join blocks line by line but don't add padding on each line to enforce uniform width.
# Already uniform blocks will join faster than textblock::join, and ragged blocks will join in a ragged manner
#"
set argd [punk::args::get_dict {
-- -type none -optional 0 -help "end of options marker -- is mandatory because joined blocks may easily conflict with flags"
-ansiresets -type any -default auto
blocks -type any -multiple 1
} $args]
set argd [punk::args::get_by_id ::textblock::join_basic $args]
set ansiresets [tcl::dict::get $argd opts -ansiresets]
set blocks [tcl::dict::get $argd values blocks]
@ -5466,7 +5481,7 @@ tcl::namespace::eval textblock {
return [::join $outlines \n]
}
proc ::textblock::join_basic2 {args} {
#*proc -name textblock::join_basic -help "Join blocks line by line but don't add padding on each line to enforce uniform width.
#@cmd -name textblock::join_basic -help "Join blocks line by line but don't add padding on each line to enforce uniform width.
# Already uniform blocks will join faster than textblock::join, and ragged blocks will join in a ragged manner
#"
set argd [punk::args::get_dict {
@ -6046,8 +6061,8 @@ tcl::namespace::eval textblock {
if {$bad_option || [llength $values] == 0} {
#no framedef supplied, or unrecognised opt seen
set spec [string map [list <ftlist> $::textblock::frametypes] {
*id textblock::framedef
*proc -name textblock::framedef\
@id -id ::textblock::framedef
@cmd -name textblock::framedef\
-help "Return a dict of the elements that make up a frame border.
May return a subset of available elements based on memberglob values."
@ -6058,7 +6073,7 @@ tcl::namespace::eval textblock {
-help "-boxonly true restricts results to the corner,vertical and horizontal box elements
It excludes the extra top and side join elements htlj,hlbj,vllj,vlrj."
*values -min 1
@values -min 1
frametype -choices "<ftlist>" -choiceprefix 0 -choicerestricted 0 -type dict\
-help "name from the predefined frametypes or an adhoc dictionary."
memberglob -type globstring -optional 1 -multiple 1 -choiceprefix 0 -choicerestricted 0 -choices {
@ -7438,17 +7453,17 @@ tcl::namespace::eval textblock {
set frame_cache [tcl::dict::create]
punk::args::definition {
*id textblock::frame_cache
*proc -name textblock::frame_cache -help\
@id -id ::textblock::frame_cache
@cmd -name textblock::frame_cache -help\
"Display or clear the frame cache."
-action -default {} -choices {clear} -help\
"Clear the textblock::frame_cache dictionary"
-pretty -default 1 -help\
"Use 'pdict textblock::frame_cache */*' for prettier output"
*values -min 0 -max 0
@values -min 0 -max 0
}
proc frame_cache {args} {
set argd [punk::args::get_by_id textblock::frame_cache $args]
set argd [punk::args::get_by_id ::textblock::frame_cache $args]
set action [dict get $argd opts -action]
if {$action ni [list clear ""]} {
@ -7490,13 +7505,40 @@ tcl::namespace::eval textblock {
}
variable FRAMETYPES
set FRAMETYPES [textblock::frametypes]
variable EG
set EG [a+ brightblack]
variable RST
set RST [a]
proc frame_samples {} {
set FRAMETYPELABELS [dict create]
if {[info commands ::textblock::frame] ne ""} {
foreach ft [frametypes] {
dict set FRAMETYPELABELS $ft [textblock::frame -checkargs 0 -type $ft " "]
}
}
set FRAMETYPELABELS [dict remove $FRAMETYPELABELS block2hack]
return $FRAMETYPELABELS
}
#proc EG {} "return {[a+ brightblack]}"
#make EG fetch from SGR cache so as to abide by colour off/on
proc EG {} {
a+ brightblack
}
#proc RST {} "return {\x1b\[m}"
proc RST {} {
return "\x1b\[m"
}
#catch 22 for -choicelabels - need some sort of lazy evaluation
# ${[textblock::frame_samples]}
#todo punk::args alias for centre center etc?
punk::args::definition [punk::lib::tstr -return string {
*id textblock::frame
*proc -name "textblock::frame"\
punk::args::definition -dynamic 1 {
@id -id ::textblock::frame
@cmd -name "textblock::frame"\
-help "Frame a block of text with a border."
-checkargs -default 1 -type boolean\
-help "If true do extra argument checks and
@ -7504,18 +7546,21 @@ tcl::namespace::eval textblock {
Set false for slight performance improvement."
-etabs -default 0\
-help "expanding tabs - experimental/unimplemented."
-type -default light -choices {${$FRAMETYPES}} -choicerestricted 0 -type dict\
-type -default light -choices {${[textblock::frametypes]}} -choicerestricted 0 -choicecolumns 8 -type dict\
-choicelabels {
${[textblock::frame_samples]}
}\
-help "Type of border for frame."
-boxlimits -default {hl vl tlc blc trc brc} -type list -help "Limit the border box to listed elements.
passing an empty string will result in no box, but title/subtitle will still appear if supplied.
${$EG}e.g: -frame -boxlimits {} -title things [a+ red White]my\\ncontent${$RST}"
${[textblock::EG]}e.g: -frame -boxlimits {} -title things [a+ red White]my\\ncontent${[textblock::RST]}"
-boxmap -default {} -type dict
-joins -default {} -type list
-title -default "" -type string -regexprefail {\n}\
-help "Frame title placed on topbar - no newlines.
May contain ANSI - no trailing reset required.
${$EG}e.g 1: frame -title My[a+ green]Green[a]Thing
e.g 2: frame -title [a+ red underline]MyThing${$RST}"
${[textblock::EG]}e.g 1: frame -title My[a+ green]Green[a]Thing
e.g 2: frame -title [a+ red underline]MyThing${[textblock::RST]}"
-subtitle -default "" -type string -regexprefail {\n}\
-help "Frame subtitle placed on bottombar - no newlines
May contain Ansi - no trailing reset required."
@ -7526,8 +7571,8 @@ tcl::namespace::eval textblock {
-help "Height of resulting frame including borders."
-ansiborder -default "" -type ansistring\
-help "Ansi escape sequence to set border attributes.
${$EG}e.g 1: frame -ansiborder [a+ web-red] contents
e.g 2: frame -ansiborder \"\\x1b\\\[31m\" contents${$RST}"
${[textblock::EG]}e.g 1: frame -ansiborder [a+ web-red] contents
e.g 2: frame -ansiborder \"\\x1b\\\[31m\" contents${[textblock::RST]}"
-ansibase -default "" -type ansistring\
-help "Default ANSI attributes within frame."
-blockalign -default centre -choices {left right centre}\
@ -7547,13 +7592,13 @@ tcl::namespace::eval textblock {
Frame width doesn't adapt and content may be truncated
so -width may need to be manually set to display more."
*values -min 0 -max 1
@values -min 0 -max 1
contents -default "" -type string\
-help "Frame contents - may be a block of text containing newlines and ANSI.
Text may be 'ragged' - ie unequal line-lengths.
No trailing ANSI reset required.
${$EG}e.g: frame \"[a+ blue White] \\nMy blue foreground text on\\nwhite background\\n\"${$RST}"
}]
${[textblock::EG]}e.g: frame \"[a+ blue White] \\nMy blue foreground text on\\nwhite background\\n\"${[textblock::RST]}"
}
#options before content argument - which is allowed to be absent
#frame performance (noticeable with complex tables even of modest size) is improved somewhat by frame_cache - but is still (2024) a fairly expensive operation.
@ -7638,7 +7683,7 @@ tcl::namespace::eval textblock {
#only use punk::args if check_args is true or our basic checks failed
#never need to checkargs if only one argument supplied even if it looks like an option - as it will be treated as data to frame
if {[llength $args] != 1 && (!$opts_ok || $check_args)} {
set argd [punk::args::get_by_id textblock::frame $args]
set argd [punk::args::get_by_id ::textblock::frame $args]
set opts [dict get $argd opts]
set contents [dict get $argd values contents]
}
@ -8346,18 +8391,18 @@ tcl::namespace::eval textblock {
}
}
punk::args::definition {
*id textblock::gcross
@id -id ::textblock::gcross
-max_cross_size -default 0 -type integer -help "Largest size cross to use to make up the block
Only cross sizes that divide the size of the overall block will be used.
e.g if the 'size' chosen is 19 (a prime number) - only 1 or the full size of 19 can be used as the crosses to make up the block.
Whereas for a block size of 24, -max_cross_size of 1,2,3,4,6,8,12 or 24 will work. (all divisors)
If a number chosen for -max_cross_size isn't a divisor, the largest divisor below the chosen value will be used.
"
*values -min 0 -max 1
@values -min 0 -max 1
size -default 1 -type integer
}
proc gcross {args} {
set argd [punk::args::get_by_id textblock::gcross $args]
set argd [punk::args::get_by_id ::textblock::gcross $args]
set size [dict get $argd values size]
set opts [dict get $argd opts]

27
src/vendormodules/overtype-1.6.5.tm

@ -402,7 +402,10 @@ tcl::namespace::eval overtype {
set looplimit [expr {[tcl::string::length $overblock] + 10}]
}
set scheme 3
#overblock height/width isn't useful in the presence of an ansi input overlay with movements. The number of lines may bear little relationship to the output height
#lassign [blocksize $overblock] _w overblock_width _h overblock_height
set scheme 4
switch -- $scheme {
0 {
#one big chunk
@ -443,11 +446,18 @@ tcl::namespace::eval overtype {
set inputchunks [lindex [list $lflines [unset lflines]] 0]
}
4 {
set inputchunks [list]
foreach ln [split $overblock \n] {
lappend inputchunks [string cat $ln \n]
}
if {[llength $inputchunks]} {
lset inputchunks end [tcl::string::range [lindex $inputchunks end] 0 end-1]
}
}
}
#overblock height/width isn't useful in the presence of an ansi input overlay with movements. The number of lines may bear little relationship to the output height
#lassign [blocksize $overblock] _w overblock_width _h overblock_height
set replay_codes_underlay [tcl::dict::create 1 ""]
@ -495,7 +505,7 @@ tcl::namespace::eval overtype {
}
#review insert_mode. As an 'overtype' function whose main function is not interactive keystrokes - insert is secondary -
#but even if we didn't want it as an option to the function call - to process ansi adequately we need to support IRM (insertion-replacement mode) ESC [ 4 h|l
set renderargs [list -experimental $opt_experimental\
set renderopts [list -experimental $opt_experimental\
-cp437 $opt_cp437\
-info 1\
-crm_mode [tcl::dict::get $vtstate crm_mode]\
@ -510,11 +520,8 @@ tcl::namespace::eval overtype {
-expand_right $opt_expand_right\
-cursor_column $col\
-cursor_row $row\
$undertext\
$overtext\
]
set LASTCALL $renderargs
set rinfo [renderline {*}$renderargs]
set rinfo [renderline {*}$renderopts $undertext $overtext]
set instruction [tcl::dict::get $rinfo instruction]
tcl::dict::set vtstate crm_mode [tcl::dict::get $rinfo crm_mode]
@ -1237,8 +1244,8 @@ tcl::namespace::eval overtype {
append debugmsg "looplimit $looplimit reached\n"
append debugmsg "data_mode:$data_mode\n"
append debugmsg "opt_appendlines:$opt_appendlines\n"
append debugmsg "prev_row :[tcl::dict::get $LASTCALL -cursor_row]\n"
append debugmsg "prev_col :[tcl::dict::get $LASTCALL -cursor_column]\n"
append debugmsg "prev_row :[tcl::dict::get $renderopts -cursor_row]\n"
append debugmsg "prev_col :[tcl::dict::get $renderopts -cursor_column]\n"
tcl::dict::for {k v} $rinfo {
append debugmsg "${Y}$k [ansistring VIEW -lf 1 -vt 1 $v]$RST" \n
}

46
src/vfs/_vfscommon.vfs/modules/argparsingtest-0.1.0.tm

@ -277,8 +277,9 @@ namespace eval argparsingtest {
#punk::args is slower than argp - but comparable, and argp doesn't support solo flags
proc test1_punkargs {args} {
set argd [punk::args::get_dict {
*proc -name argtest4 -help "test of punk::args::get_dict comparative performance"
*opts -anyopts 0
@id -id ::argparsingtest::test1_punkargs
@cmd -name argtest4 -help "test of punk::args::get_dict comparative performance"
@opts -anyopts 0
-return -default string -type string
-frametype -default \uFFEF -type string
-show_edge -default \uFFEF -type string
@ -290,15 +291,15 @@ namespace eval argparsingtest {
-1 -default 1 -type boolean
-2 -default 2 -type integer
-3 -default 3 -type integer
*values
@values
} $args]
return [tcl::dict::get $argd opts]
}
punk::args::definition {
*id argparsingtest::test1_punkargs2
*proc -name argtest4 -help "test of punk::args::get_dict comparative performance"
*opts -anyopts 0
@id -id ::test1_punkargs_by_id
@cmd -name argtest4 -help "test of punk::args::get_dict comparative performance"
@opts -anyopts 0
-return -default string -type string
-frametype -default \uFFEF -type string
-show_edge -default \uFFEF -type string
@ -310,18 +311,41 @@ namespace eval argparsingtest {
-1 -default 1 -type boolean
-2 -default 2 -type integer
-3 -default 3 -type integer
*values
@values
}
proc test1_punkargs_by_id {args} {
set argd [punk::args::get_by_id ::test1_punkargs_by_id $args]
return [tcl::dict::get $argd opts]
}
punk::args::definition {
@id -id ::argparsingtest::test1_punkargs2
@cmd -name argtest4 -help "test of punk::args::get_dict comparative performance"
@opts -anyopts 0
-return -default string -type string
-frametype -default \uFFEF -type string
-show_edge -default \uFFEF -type string
-show_seps -default \uFFEF -type string
-join -type none -multiple 1
-x -default "" -type string
-y -default b -type string
-z -default c -type string
-1 -default 1 -type boolean
-2 -default 2 -type integer
-3 -default 3 -type integer
@values
}
proc test1_punkargs2 {args} {
set argd [punk::args::get_by_id argparsingtest::test1_punkargs2 $args]
set argd [punk::args::get_by_id ::argparsingtest::test1_punkargs2 $args]
return [tcl::dict::get $argd opts]
}
proc test1_punkargs_validate_ansistripped {args} {
set argd [punk::args::get_dict {
*proc -name argtest4 -help "test of punk::args::get_dict comparative performance"
*opts -anyopts 0
@id -id ::argparsingtest::test1_punkargs_validate_ansistripped
@cmd -name argtest4 -help "test of punk::args::get_dict comparative performance"
@opts -anyopts 0
-return -default string -type string -choices {string object} -help "return type"
-frametype -default \uFFEF -type string
-show_edge -default \uFFEF -type string
@ -333,7 +357,7 @@ namespace eval argparsingtest {
-1 -default 1 -type boolean -validate_ansistripped true
-2 -default 2 -type integer -validate_ansistripped true
-3 -default 3 -type integer -validate_ansistripped true
*values
@values
} $args]
return [tcl::dict::get $argd opts]
}

27
src/vfs/_vfscommon.vfs/modules/overtype-1.6.5.tm

@ -402,7 +402,10 @@ tcl::namespace::eval overtype {
set looplimit [expr {[tcl::string::length $overblock] + 10}]
}
set scheme 3
#overblock height/width isn't useful in the presence of an ansi input overlay with movements. The number of lines may bear little relationship to the output height
#lassign [blocksize $overblock] _w overblock_width _h overblock_height
set scheme 4
switch -- $scheme {
0 {
#one big chunk
@ -443,11 +446,18 @@ tcl::namespace::eval overtype {
set inputchunks [lindex [list $lflines [unset lflines]] 0]
}
4 {
set inputchunks [list]
foreach ln [split $overblock \n] {
lappend inputchunks [string cat $ln \n]
}
if {[llength $inputchunks]} {
lset inputchunks end [tcl::string::range [lindex $inputchunks end] 0 end-1]
}
}
}
#overblock height/width isn't useful in the presence of an ansi input overlay with movements. The number of lines may bear little relationship to the output height
#lassign [blocksize $overblock] _w overblock_width _h overblock_height
set replay_codes_underlay [tcl::dict::create 1 ""]
@ -495,7 +505,7 @@ tcl::namespace::eval overtype {
}
#review insert_mode. As an 'overtype' function whose main function is not interactive keystrokes - insert is secondary -
#but even if we didn't want it as an option to the function call - to process ansi adequately we need to support IRM (insertion-replacement mode) ESC [ 4 h|l
set renderargs [list -experimental $opt_experimental\
set renderopts [list -experimental $opt_experimental\
-cp437 $opt_cp437\
-info 1\
-crm_mode [tcl::dict::get $vtstate crm_mode]\
@ -510,11 +520,8 @@ tcl::namespace::eval overtype {
-expand_right $opt_expand_right\
-cursor_column $col\
-cursor_row $row\
$undertext\
$overtext\
]
set LASTCALL $renderargs
set rinfo [renderline {*}$renderargs]
set rinfo [renderline {*}$renderopts $undertext $overtext]
set instruction [tcl::dict::get $rinfo instruction]
tcl::dict::set vtstate crm_mode [tcl::dict::get $rinfo crm_mode]
@ -1237,8 +1244,8 @@ tcl::namespace::eval overtype {
append debugmsg "looplimit $looplimit reached\n"
append debugmsg "data_mode:$data_mode\n"
append debugmsg "opt_appendlines:$opt_appendlines\n"
append debugmsg "prev_row :[tcl::dict::get $LASTCALL -cursor_row]\n"
append debugmsg "prev_col :[tcl::dict::get $LASTCALL -cursor_column]\n"
append debugmsg "prev_row :[tcl::dict::get $renderopts -cursor_row]\n"
append debugmsg "prev_col :[tcl::dict::get $renderopts -cursor_column]\n"
tcl::dict::for {k v} $rinfo {
append debugmsg "${Y}$k [ansistring VIEW -lf 1 -vt 1 $v]$RST" \n
}

15
src/vfs/_vfscommon.vfs/modules/patternpunk-1.1.tm

@ -112,10 +112,10 @@ proc TCL {args} {
}
punk::args::definition {
*id ">punk . poses"
*proc -name ">punk . poses" -help "Show or list the poses for the Punk mascot"
-censored -default 1 -type boolean -help "Set true to include mild toilet humour poses"
-return -default table -choices {list table}
@id -id ">punk . poses"
@cmd -name ">punk . poses" -help "Show or list the poses for the Punk mascot"
-censored -default 1 -type boolean -help "Set true to include mild toilet humour poses"
-return -default table -choices {list table}
}
>punk .. Method poses {args} {
set argd [punk::args::get_by_id ">punk . poses" $args]
@ -344,7 +344,8 @@ v_ /|\/ /
package require punk::args
set standard_frame_types [textblock::frametypes]
set argd [punk::args::get_dict [tstr -return string {
*proc -name "deck" -help "Punk Deck mascot"
@id -id ">punk . deck"
@cmd -name "deck" -help "Punk Deck mascot"
-frame -default arc -choices "${$standard_frame_types}" -choicerestricted 0 -choiceprefix 1
-boxmap -default {} -type dict
-boxlimits -default {hl vl tlc blc trc brc} -help "Limit the border box to listed elements."
@ -353,7 +354,7 @@ v_ /|\/ /
}
-title -default "PATTERN" -type string
-subtitle -default "PUNK" -type string
*values -max 0
@values -max 0
}] $args]
set frame_type [dict get $argd opts -frame]
set box_map [dict get $argd opts -boxmap]
@ -367,7 +368,7 @@ v_ /|\/ /
#TODO - reuse textblock::gcross arguments - but reorder for error display
>punk .. Method gcross {{size 1} args} {
package require textblock
set argd [punk::args::get_by_id textblock::gcross [list {*}$args $size]]
set argd [punk::args::get_by_id ::textblock::gcross [list {*}$args $size]]
textblock::gcross {*}$args $size
}

20
src/vfs/_vfscommon.vfs/modules/poshinfo-0.1.0.tm

@ -199,19 +199,19 @@ tcl::namespace::eval poshinfo {
}
punk::args::definition {
*id poshinfo::themes
*proc -name poshinfo::themes
@id -id ::poshinfo::themes
@cmd -name poshinfo::themes
-format -default all -multiple 1 -choices {all yaml json}\
-help "File format of posh theme - based on file extension"
-type -default all -multiple 1\
-help "e.g omp"
-as -default "table" -choices {list showlist dict showdict table tableobject plaintext}\
-help "return type of result"
*values -min 0
globs -multiple 1 -default * -help ""
-help "File format of posh theme - based on file extension"
-type -default all -multiple 1\
-help "e.g omp"
-as -default "table" -choices {list showlist dict showdict table tableobject plaintext}\
-help "return type of result"
@values -min 0
globs -multiple 1 -default * -help ""
}
proc themes {args} {
set argd [punk::args::get_by_id poshinfo::themes $args]
set argd [punk::args::get_by_id ::poshinfo::themes $args]
set return_as [dict get $argd opts -as]
set formats [dict get $argd opts -format] ;#multiple
if {"yaml" in $formats} {

15
src/vfs/_vfscommon.vfs/modules/punk-0.1.tm

@ -306,10 +306,11 @@ namespace eval punk {
#get last command result that was run through the repl
proc ::punk::get_runchunk {args} {
set argd [punk::args::get_dict {
*opts
@id -id ::punk::get_runchunk
@opts
-1 -optional 1 -type none
-2 -optional 1 -type none
*values -min 0 -max 0
@values -min 0 -max 0
} $args]
#todo - make this command run without truncating previous runchunks
set runchunks [tsv::array names repl runchunks-*]
@ -7152,8 +7153,8 @@ namespace eval punk {
}
punk::args::definition {
*id punk::inspect
*proc -name punk::inspect -help\
@id -id ::punk::inspect
@cmd -name punk::inspect -help\
"Function to display values - used pimarily in a punk pipeline.
The raw value arguments (not options) are always returned to pass
forward in the pipeline.
@ -7227,9 +7228,9 @@ namespace eval punk {
Does not affect return value."
-- -type none -help\
"End of options marker.
It is advisable to use this, as data in a pipeline may often being with -"
It is advisable to use this, as data in a pipeline may often begin with -"
*values -min 0 -max -1
@values -min 0 -max -1
arg -type string -optional 1 -multiple 1 -help\
"value to display"
}
@ -7261,7 +7262,7 @@ namespace eval punk {
foreach {k v} $flags {
if {$k ni [dict keys $defaults]} {
#error "inspect: unknown option $k. Known options: [dict keys $defaults]. If data contains flaglike elements, consider calling with end-of-opts marker. e.g inspect --"
punk::args::get_by_id punk::inspect $args
punk::args::get_by_id ::punk::inspect $args
}
}
set opts [dict merge $defaults $flags]

145
src/vfs/_vfscommon.vfs/modules/punk/ansi-0.1.1.tm

@ -134,27 +134,27 @@ tcl::namespace::eval punk::ansi::class {
}
lappend ::punk::ansi::class::PUNKARGS [list {
*id "punk::ansi::class::class_ansi render_to_input_line"
*proc -name "punk::ansi::class::class_ansi render_to_input_line" -help\
@id -id "::punk::ansi::class::class_ansi render_to_input_line"
@cmd -name "punk::ansi::class::class_ansi render_to_input_line" -help\
"render string from line 0 to line
(experimental/debug)"
-dimensions -type string -help\
"WxH where W is integer width >= 1 and H is integer heigth >= 1"
-minus -type integer -help\
"number of chars to exclude from end"
*values -min 1 -max 1
@values -min 1 -max 1
line -type indexexpression
}]
method render_to_input_line {args} {
if {[llength $args] < 1} {
puts stderr "render_to_input_line usage: ?-dimensions WxH? ?-minus charcount? x"
punk::args::get_by_id "punk::ansi::class::class_ansi render_to_input_line" $args
punk::args::get_by_id "::punk::ansi::class::class_ansi render_to_input_line" $args
}
set x [lindex $args end]
set arglist [lrange $args 0 end-1]
if {[llength $arglist] %2 != 0} {
puts stderr "render_to_input_line usage: ?-dimensions WxH? ?-minus charcount? x"
punk::args::get_by_id "punk::ansi::class::class_ansi render_to_input_line" $args
punk::args::get_by_id "::punk::ansi::class::class_ansi render_to_input_line" $args
}
set opts [tcl::dict::create\
-dimensions 80x24\
@ -167,7 +167,7 @@ tcl::namespace::eval punk::ansi::class {
}
default {
puts stderr "render_to_input_line unexpected argument '$k' usage: ?-dimensions WxH? ?-minus charcount? x"
punk::args::get_by_id "punk::ansi::class::class_ansi render_to_input_line" $args
punk::args::get_by_id "::punk::ansi::class::class_ansi render_to_input_line" $args
}
}
}
@ -588,20 +588,20 @@ tcl::namespace::eval punk::ansi {
}
lappend PUNKARGS [list -dynamic 1 {
*id punk::ansi::example
*proc -name punk::ansi::example -help "Display .ans image files in a grid that will fit in console
@id -id ::punk::ansi::example
@cmd -name punk::ansi::example -help "Display .ans image files in a grid that will fit in console
"
-colwidth -default 82 -help "Width of each column - default of 82 will fit a standard 80wide ansi image (when framed)
You can specify a narrower width to truncate images on the right side"
-folder -default "${[punk::ansi::Get_ansifolder]}" -help "Base folder for files if relative paths are used.
Defaults to <projectbase>/src/testansi - where projectbase is determined from current directory.
"
*values -min 0 -max -1
@values -min 0 -max -1
files -default {belinda.ans bot.ans flower.ans fish.ans} -multiple true -help "List of filenames - leave empty to display 4 defaults"
} ""]
proc example {args} {
set argd [punk::args::get_by_id punk::ansi::example $args]
set argd [punk::args::get_by_id ::punk::ansi::example $args]
set colwidth [dict get $argd opts -colwidth]
set ansifolder [file normalize [dict get $argd opts -folder]]
set fnames [dict get $argd values files]
@ -2355,21 +2355,21 @@ Brightblack 100 Brightred 101 Brightgreen 102 Brightyellow 103 Brightblu
#sgr_cache clear called by punk::console::ansi when set to off
#punk::args depends on punk::ansi - REVIEW
lappend PUNKARGS [list {
@id -id ::punk::ansi::sgr_cache
@cmd -name punk::ansi::sgr_cache -help\
"Convenience function to view and optionally clear the ansi character attribute cache (ansi SGR codes)
"
-action -default "" -choices "clear" -help\
"-action clear will unset the keys in the punk::ansi::sgr_cache dict
This is called automatically when setting 'colour false' in the console"
-pretty -default 1 -type boolean -help\
"use 'pdict punk::ansi::sgr_cache */%str,%ansiview' output"
@values -min 0 -max 0
}]
proc sgr_cache {args} {
set argdef {
*id punk::ansi::sgr_cache
*proc -name punk::ansi::sgr_cache -help\
"Convenience function to view and optionally clear the ansi character attribute cache (ansi SGR codes)
"
-action -default "" -choices "clear" -help\
"-action clear will unset the keys in the punk::ansi::sgr_cache dict
This is called automatically when setting 'colour false' in the console"
-pretty -default 1 -type boolean -help\
"use 'pdict punk::ansi::sgr_cache */%str,%ansiview' output"
*values -min 0 -max 0
}
set argd [punk::args::get_dict $argdef $args]
set argd [punk::args::get_by_id ::punk::ansi::sgr_cache $args]
set action [dict get $argd opts -action]
set pretty [dict get $argd opts -pretty]
@ -2412,34 +2412,7 @@ Brightblack 100 Brightred 101 Brightgreen 102 Brightyellow 103 Brightblu
return [join $lines \n]
}
lappend PUNKARGS [list {
*id punk::ansi::a+
*proc -name "punk::ansi::a+" -help\
"Returns an ANSI sgr escape sequence based on the list of supplied codes.
Unlike punk::ansi::a - it is not prefixed with an ANSI reset.
"
*values -min 0 -max -1
} [string map [list <choices> [dict keys $SGR_map]] {
code -type string -optional 1 -multiple 1 -choices {<choices>} -choiceprefix 0 -choicerestricted 0 -help\
"SGR code from the list below, or an integer corresponding to the code e.g 31 = red.
A leading capital letter indicates a codename applies to the background colour.
Other accepted codes are:
term-<int> Term-<int> foreground/background where int is 0-255 terminal color
term-<termcolour> Term-<termcolour> foreground/background
rgb-<r>-<g>-<b> Rgb-<r>-<g>-<b> foreground/background where <r> <g> <b> are the
0-255 int values for red, green and blue.
rgb#<hexcode> Rgb#<hexcode> where <hexcode> is a 6 char hex colour e.g rgb#C71585
web-<webcolour> Web-<webcolour>
The acceptable values for <termcolour> and <webcolour> can be queried using
punk::ansi::a? term
and
punk::ansi::a? web
Example to set foreground red and background cyan followed by a reset:
set str \"[a+ red Cyan]sample text[a]\"
"
}]]
#PUNKARGS doc performed below, after we create the proc
proc a+ {args} {
#*** !doctools
#[call [fun a+] [opt {ansicode...}]]
@ -2907,6 +2880,41 @@ Brightblack 100 Brightred 101 Brightgreen 102 Brightyellow 103 Brightblu
return $result
}
set SGR_samples [dict create]
foreach k [dict keys $SGR_map] {
dict set SGR_samples $k "[punk::ansi::a+ $k]sample\x1b\[m"
}
lappend PUNKARGS [list {
@id -id ::punk::ansi::a+
@cmd -name "punk::ansi::a+" -help\
"Returns an ANSI sgr escape sequence based on the list of supplied codes.
Unlike punk::ansi::a - it is not prefixed with an ANSI reset.
"
@values -min 0 -max -1
} [string map [list <choices> [dict keys $SGR_map] <choicelabels> $SGR_samples] {
code -type string -optional 1 -multiple 1 -choices {<choices>}\
-choicelabels {<choicelabels>}\
-choicecolumns 5 -choiceprefix 0 -choicerestricted 0 -help\
"SGR code from the list below, or an integer corresponding to the code e.g 31 = red.
A leading capital letter indicates a codename applies to the background colour.
Other accepted codes are:
term-<int> Term-<int> foreground/background where int is 0-255 terminal color
term-<termcolour> Term-<termcolour> foreground/background
rgb-<r>-<g>-<b> Rgb-<r>-<g>-<b> foreground/background where <r> <g> <b> are the
0-255 int values for red, green and blue.
rgb#<hexcode> Rgb#<hexcode> where <hexcode> is a 6 char hex colour e.g rgb#C71585
web-<webcolour> Web-<webcolour>
The acceptable values for <termcolour> and <webcolour> can be queried using
punk::ansi::a? term
and
punk::ansi::a? web
Example to set foreground red and background cyan followed by a reset:
set str \"[a+ red Cyan]sample text[a]\"
"
}]]
proc a {args} {
#*** !doctools
#[call [fun a] [opt {ansicode...}]]
@ -4281,6 +4289,7 @@ tcl::namespace::eval punk::ansi {
}
4 {
#REVIEW - merging extended (e.g 4:4) underline attributes suppresses all other SGR attributes on at least some terminals which don't support extended underlines
#e.g hyper on windows
if {[llength $paramsplit] == 1} {
tcl::dict::set codestate underline 4
} else {
@ -4634,6 +4643,8 @@ tcl::namespace::eval punk::ansi::ta {
#[list_begin definitions]
tcl::namespace::path ::punk::ansi
variable PUNKARGS
#handle both 7-bit and 8-bit csi
#review - does codepage affect this? e.g ebcdic has 8bit csi in different position
@ -4706,15 +4717,31 @@ tcl::namespace::eval punk::ansi::ta {
#variable re_ansi_split "${re_csi_code}|${re_esc_osc1}|${re_esc_osc2}|${re_esc_osc3}|${re_standalones}|${re_ST}|${re_g0_open}|${re_g0_close}"
set re_ansi_split $re_ansi_detect
lappend PUNKARGS [list -dynamic 0 {
@id -id ::punk::ansi::ta::detect
@cmd -name punk::ansi::ta::detect -help\
"Return a boolean indicating whether Ansi codes were detected in text.
Important caveat:
When text is a tcl list made from splitting (or lappending) some ansi string
- individual elements may be braced or have certain chars escaped.
(one example is if a list element contains an unbalanced brace)
This can cause square brackets that form part of the ansi to be backslash escaped
- and the function can fail to match it as an Ansi code.
"
@values -min 1
text -type string
} ]
#*** !doctools
#[call [fun detect] [arg text]]
#[para]Return a boolean indicating whether Ansi codes were detected in text
#[para]Important caveat:
#[para] When text is a tcl list made from splitting (or lappending) some ansi string - individual elements may be braced or have certain chars escaped. (one example is if a list element contains an unbalanced brace)
#[para] This can cause square brackets that form part of the ansi being backslash escaped - and the regexp can fail to match
#detect any ansi escapes
#review - only detect 'complete' codes - or just use the opening escapes for performance?
proc detect {text} [string map [list <re> [list $re_ansi_detect]] {
#*** !doctools
#[call [fun detect] [arg text]]
#[para]Return a boolean indicating whether Ansi codes were detected in text
#[para]Important caveat:
#[para] When text is a tcl list made from splitting (or lappending) some ansi string - individual elements may be braced or have certain chars escaped. (one example is if a list element contains an unbalanced brace)
#[para] This can cause square brackets that form part of the ansi being backslash escaped - and the regexp can fail to match
regexp <re> $text
}]
@ -7405,7 +7432,7 @@ if {![info exists ::punk::args::register::NAMESPACES]} {
set NAMESPACES [list]
}
}
lappend ::punk::args::register::NAMESPACES ::punk::ansi ::punk::ansi::class
lappend ::punk::args::register::NAMESPACES ::punk::ansi ::punk::ansi::class ::punk::ansi::ta
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
## Ready

1114
src/vfs/_vfscommon.vfs/modules/punk/args-0.1.0.tm

File diff suppressed because it is too large Load Diff

494
src/vfs/_vfscommon.vfs/modules/punk/args/tclcore-0.1.0.tm

@ -141,29 +141,219 @@ tcl::namespace::eval punk::args::tclcore {
variable PUNKARGS
# -- --- --- --- ---
#non colour SGR codes
# we can use these directly via ${$I} etc without marking a definition with -dynamic
#This is because they don't need to change when colour switched on and off.
set I [a+ italic]
set NI [a+ noitalic]
set B [a+ bold]
set N [a+ normal]
# -- --- --- --- ---
# -- --- --- --- --- --- --- --- --- --- --- --- --- ---
# library commands loaded via auto_index
# -- --- --- --- --- --- --- --- --- --- --- --- --- ---
lappend PUNKARGS [list {
*id parray
*proc -name "Builtin: parray" -help\
@id -id ::parray
@cmd -name "Builtin: parray" -help\
"Prints on standard output the names and values of all the elements in the
array arrayName, or just the names that match pattern (using the matching
rules of string_match) and their values if pattern is given.
ArrayName must be an array accessible to the caller of parray. It may either
be local or global. The result of this command is the empty string.
(loaded via auto_index)"
*values -min 1 -max 2
@values -min 1 -max 2
arrayName -type string -help\
"variable name of an array"
pattern -type string -optional 1 -help\
"Match pattern possibly containing glob characters"
} "*doc -name Manpage: -url [manpage_tcl library]" ]
} "@doc -name Manpage: -url [manpage_tcl library]" ]
# -- --- --- --- --- --- --- --- --- --- --- --- --- ---
#categorise array subcommands based on currently known groupings.
#we do this dynamically because Tcl ensembles (even some core ones) can have subcommands added at runtime.
proc array_subcommands {} {
package require punk::ns
set subdict [punk::ns::ensemble_subcommands array]
set expected_searchcmds {startsearch anymore nextelement donesearch}
set searchcmds [list]
foreach sc $expected_searchcmds {
if {$sc in [dict keys $subdict]} {
lappend searchcmds $sc
}
}
set argdef ""
append argdef "subcommand -choicegroups \{" \n
append argdef " \"\" \{" \n
append argdef " [dict keys [dict remove $subdict {*}$searchcmds]]" \n
append argdef " \}" \n
append argdef " \"search\" \{" \n
append argdef " $searchcmds" \n
append argdef " \}" \n
append argdef " \} -choicecolumns 4 " \n
return $argdef
}
lappend PUNKARGS [list -dynamic 1 {
@id -id ::array
@cmd -name "Builtin: array" -help\
"Manipulate array variables"
@values
${[punk::args::tclcore::array_subcommands]}
} "@doc -name Manpage: -url [manpage_tcl array]" ]
#todo - make generic - take command and known_groups_dict
proc info_subcommands {} {
package require punk::ns
set subdict [punk::ns::ensemble_subcommands info]
set allsubs [dict keys $subdict]
dict set groups "system" {hostname library nameofexecutable patchlevel script sharedlibextension tclversion}
dict set groups "{proc introspection}" {args body default}
dict set groups "variables" {constant consts exists globals locals vars}
dict set groups "{oo object introspection}" {class object}
set allgrouped [list]
dict for {g members} $groups {
lappend allgrouped {*}$members
}
set others [list]
foreach sc $allsubs {
if {$sc ni $allgrouped} {
lappend others $sc
}
}
set argdef ""
append argdef "subcommand -choicegroups \{" \n
append argdef " \"\" \{$others\}" \n
dict for {g members} $groups {
append argdef " $g \{$members\}" \n
}
append argdef " \}" \n
return $argdef
}
lappend PUNKARGS [list -dynamic 1 {
@id -id ::info
@cmd -name "Builtin: info" -help\
"Information about the state of the Tcl interpreter"
@values
${[punk::args::tclcore::info_subcommands]}
} "@doc -name Manpage: -url [manpage_tcl array]" ]
#An idiom for sharing common features - incomplete - todo work out what happens with (default)::id that has leaders,opts,values
#todo @cmd -help+ text (append to existing help that came from a default?)
lappend PUNKARGS [list {
@id -id "(default)::tcl::binary::*::base64"
@cmd -help\
"The base64 binary encoding is commonly used in mail messages and XML documents,
and uses mostly upper and lower case letters and digits. It has the distinction
of being able to be rewrapped arbitrarily without losing information.
"
} "@doc -name Manpage: -url [manpage_tcl binary]" ]
lappend PUNKARGS [list {
@id -id "::tcl::binary::encode::base64"
@default -id (default)::tcl::binary::*::base64
@cmd -name "binary encode base64"
-maxlen -type integer -help\
"Indicates that the output should be split into lines of no more than length
characters. By default, lines are not split."
-wrapchar -type character -default \n -help\
"Indicates that, when lines are split because of the -maxlen option, character
should be used to separate lines. By default, this is a newline character, \"\\n\"."
@values -min 1 -max 1
data -type string
} ]
lappend PUNKARGS [list {
@id -id "::tcl::binary::decode::base64"
@cmd -name "binary decode base64"
-strict -type none -help\
"Instructs the decoder to throw an error if it encounters any characters that
are not strictly part of the encoding itself. Otherwise it ignores them.
RFC 2045 calls for base64 decoders to be non-strict."
@values -min 1 -max 1
data -type string
} ]
lappend PUNKARGS [list {
@id -id "(default)::tcl::binary::*::hex"
@cmd -help\
"The hex binary encoding converts each byte to a pair of hexadecimal digits
that represent the byte value as a hexadecimal integer. When encoding, lower
characters are used. When decoding, upper and lower characters are accepted."
} "@doc -name Manpage: -url [manpage_tcl binary]" ]
lappend PUNKARGS [list {
@id -id "::tcl::binary::encode::hex"
@default -id (default)::tcl::binary::*::hex
@cmd -name "binary encode hex"
@values -min 1 -max 1
data -type string
} ]
lappend PUNKARGS [list {
@id -id "::tcl::binary::decode::hex"
@default -id (default)::tcl::binary::*::hex
@cmd -name "binary encode hex"
-strict -type none -help\
"Instructs the decoder to throw an error if it encounters whitespace
characters. Otherwise it ignores them."
@values -min 1 -max 1
data -type string
} "@doc -name Manpage: -url [manpage_tcl binary]" ]
lappend PUNKARGS [list {
@id -id "(default)::tcl::binary::*::uuencode"
@cmd -help\
"The uuencode binary encoding used to be common for transfer of data between Unix
systems and on USENT, but is less common these days, having been largely
superseded by the base64 binary encoding.
Note that neither the encoder nor the decoder handle the header and footer of the
uuencode format."
} "@doc -name Manpage: -url [manpage_tcl binary]" ]
lappend PUNKARGS [list {
@id -id "::tcl::binary::encode::uuencode"
@default -id (default)::tcl::binary::*::uuencode
#todo @cmd -help+ "Changing the options may produce files that other implementations of decoders cannot process"
@cmd -name "binary encode uuencode"
-maxlen -type integer -default 61 -range {5 85} -help\
"Indicates the maximum number of characters to produce for each encoded line.
The valid range is 5 to 85. Line lengths outside that range cannot be
accommodated by the encoding format."
-wrapchar -type string -default \n -help\
"Indicates the character(s) to use to mark the end of each encoded line.
Acceptable values are a sequence of zero or more character from the set
{ \\x09 (TAB), \\x0B (VT), \\x0C (FF), \\x0D (CR) } followed by zero or
one newline \\x0A (LF). Any other values are rejected because they would
generate encoded text that could not be decoded. The default value is a
single newline.
"
@values -min 1 -max 1
data -type string
} ]
lappend PUNKARGS [list {
@id -id "::tcl::binary::decode::uuencode"
@default -id (default)::tcl::binary::*::uuencode
@cmd -name "binary decode uuencode"
-strict -type none -help\
"Instructs the decoder to throw an error if it encounters anything outside
of the standard encoding format. Without this option, the decoder tolerates
some deviations, mostly to forgive reflows of lines between the encoder and
decoder."
@values -min 1 -max 1
data -type string
} ]
lappend PUNKARGS [list {
*id time
*proc -name "Builtin: time" -help\
@id -id ::time
@cmd -name "Builtin: time" -help\
"Calls the Tcl interpreter count times to evaluate script
(or once if count is not specified). It will then return
a string of the form
@ -172,46 +362,129 @@ tcl::namespace::eval punk::args::tclcore {
iteration, in microseconds. Time is measured in elapsed
time, not CPU time.
(see also: timerate)"
*values -min 1 -max 2
@values -min 1 -max 2
script -type script
count -type integer -default 1 -optional 1
} "*doc -name Manpage: -url [manpage_tcl time]" ]
} "@doc -name Manpage: -url [manpage_tcl time]" ]
lappend PUNKARGS [list {
@id -id ::tcl::chan::tell
@cmd -name "Builtin: tcl::chan::tell" -help\
"Returns a number giving the current access position within the underlying
data stream for the channel named channel. This value returned is a byte
offset that can be passed to ${[a+ bold]}chan seek${[a normal]} in order
to set the channel to a particular position. Note that this value is in
terms of bytes, not characters like ${[a+ bold]}chan read${[a+ normal]}. The
value returned is -1 for channels that do not support seeking."
@values
channel -help \
""
} "@doc -name Manpage: -url [manpage_tcl chan]" ]
lappend PUNKARGS [list {
@id -id ::tcl::info::cmdtype
@cmd -name "Builtin: tcl::info::cmdtype" -help\
"Returns the type of the command named ${$I}commandName${$NI}.
Built-in types are:
${$B}alias${$N}
${$I}commandName${$NI} was created by 'interp alias'. In a safe interpreter an
alias is only visible if both the alias and the target are visible.
${$B}coroutine${$N}
${$I}commandName${$NI} was created by 'coroutine'.
${$B}ensemble${$N}
${$I}commandName${$NI} was created by 'namespace ensemble'.
${$B}import${$N}
${$I}commandName${$NI} was created by 'namespace import'.
${$B}native${$N}
${$I}commandName${$NI} was created by the 'Tcl_CreateObjCommand' interface
directly without further registration of the type of command.
${$B}object${$N}
${$I}commandName${$NI} is the public comand that represents an instance
of oo::object or one of its subclasses.
${$B}privateObject${$N}
${$I}commandName${$NI} is the private command, my by default,
that represents an instance of oo::object or one of its subclasses.
${$B}proc${$N}
${$I}commandName${$NI} was created by 'proc'.
${$B}interp${$N}
${$I}commandName${$NI} was created by 'interp create'.
${$B}zlibStream${$N}
${$I}commandName${$NI} was created by 'zlib stream'.
"
@values -min 1 -max 1
commandName -type string
} "@doc -name Manpage: -url [manpage_tcl info]" ]
lappend PUNKARGS [list {
@id -id ::tcl::namespace::origin
@cmd -name "Builtin: tcl::namespace::origin" -help\
"Returns the fully-qualified name of the original command to which the
imported command command refers. When a command is imported into a
namespace, a new command is created in that namespace that points to the
actual command in the exporting namespace. If a command is imported into
a sequence of namespaces a,b,...,n where each successive namespace just
imports the command from the previous namespace, this command returns
the fully-qualified name of the original command in the first namespace, a.
If command does not refer to an imported command, the command's own
fully-qualified name is returned
"
@values
command
} "@doc -name Manpage: -url [manpage_tcl namespace]" ]
lappend PUNKARGS [list {
*id tcl::namespace::path
*proc -name "Builtin: tcl::namespace::path" -help\
@id -id ::tcl::namespace::path
@cmd -name "Builtin: tcl::namespace::path" -help\
"Returns the command resolution path of the current namespace.
If namespaceList is specified as a list of named namespaces, the current
namespace's command resolution path is set to those namespaces and returns
the empty list. The default command resolution path is always empty.
See the section NAME_RESOLUTION in the manpage for an explanation of the
rules regarding name resolution."
*values -min 0 -max 1
@values -min 0 -max 1
namespaceList -type list -optional 1 -help\
"List of existing namespaces"
} "*doc -name Manpage: -url [manpage_tcl namespace]" ]
} "@doc -name Manpage: -url [manpage_tcl namespace]" ]
lappend PUNKARGS [list {
*id tcl::namespace::unknown
*proc -name "Builtin: tcl::namespace::unknown" -help\
@id -id ::tcl::namespace::unknown
@cmd -name "Builtin: tcl::namespace::unknown" -help\
"Sets or returns the unknown command handler for the current namespace.
The handler is invoked when a command called from within the namespace cannot
be found in the current namespace, the namespace's path nor in the global
namespace.
When the handler is invoiked, the full invocation line will be appended to
the script and the result evaluated in the context of the namespace.
The default handler for all namespaces is [a+ italic]::unknown[a].
The default handler for all namespaces is ${[a+ italic]}::unknown${[a+ noitalic]}.
If no argument is given, it returns the handler for the current namespace."
*values -min 0 -max 1
@values -min 0 -max 1
script -type script -optional 1 -help\
"A well formed list representing a command name and optional arguments."
} "*doc -name Manpage: -url [manpage_tcl namespace]" ]
} "@doc -name Manpage: -url [manpage_tcl namespace]" ]
lappend PUNKARGS [list {
@id -id ::tcl::namespace::which
@cmd -name "Builtin: tcl::namespace::which" -help\
"Looks up name as either a command or variable and returns its fully-qulified name.
For example, if name does not exist in the current namespace but does exist in the
global namespace, this command returns a fully-qualified name in the global namespace.
If the command or variable does not exist, this command returns an empty string. If
the variable has been created but not defined, such as with the variable command or
through a trace on the variable, this command will return the fully-qualified name
of the variable. If no flag is given, name is treated as a command name.
See the section NAME RESOLUTION in the manpage for an explanation of the rules
regarding name resolution.
"
@opts
-command
-variable
@values -min 1 -max 1
name
} "@doc -name Manpage: -url [manpage_tcl namespace]" ]
set I [a+ italic]
set NI [a+ noitalic]
lappend PUNKARGS [list {
*id tcl::process::status
*proc -name "Builtin: tcl::process::status" -help\
@id -id ::tcl::process::status
@cmd -name "Builtin: tcl::process::status" -help\
"Returns a dictionary mapping subprocess PIDs to their respective status.
if ${$I}pids${$NI} is specified as a list of PIDs then the command
only returns the status of the matching subprocesses if they exist, and
@ -243,43 +516,43 @@ tcl::namespace::eval punk::args::tclcore {
-- -type none -optional 1 -help\
"Marks the end of switches. The argument following this one will be
treated as the first arg even if it starts with a -."
*values -min 0 -max 1
@values -min 0 -max 1
pids -type list -optional 1 -help\
"A list of PIDs"
} "*doc -name Manpage: -url [manpage_tcl namespace]" ]
} "@doc -name Manpage: -url [manpage_tcl namespace]" ]
lappend PUNKARGS [list {
*id lappend
*proc -name "builtin: lappend" -help\
@id -id ::lappend
@cmd -name "builtin: lappend" -help\
"Append list elements onto a variable.
"
*values -min 1 -max -1
@values -min 1 -max -1
varName -type string -help\
"variable name"
value -type any -optional 1 -multiple 1
} "*doc -name Manpage: -url [manpage_tcl lappend]"]
} "@doc -name Manpage: -url [manpage_tcl lappend]"]
punk::args::definition {
*id ledit
*proc -name "builtin: ledit" -help\
@id -id ::ledit
@cmd -name "builtin: ledit" -help\
"Replace elements of a list stored in variable
"
*values -min 3 -max -1
@values -min 3 -max -1
listVar -type string -help\
"Existing list variable name"
first -type indexexpression
last -type indexexpression
value -type any -optional 1 -multiple 1
} "*doc -name Manpage: -url [manpage_tcl ledit]"
} "@doc -name Manpage: -url [manpage_tcl ledit]"
punk::args::definition {
*id lpop
*proc -name "builtin: lpop" -help\
@id -id ::lpop
@cmd -name "builtin: lpop" -help\
"Get and remove an element in a list
"
*values -min 1 -max -1
@values -min 1 -max -1
varName -type string -help\
"Existing list variable name"
index -type indexexpression -default end -optional 1 -multiple 1 -help\
@ -292,11 +565,11 @@ tcl::namespace::eval punk::args::tclcore {
in turn to address an element within a sublist designated by the
previous indexing operation, allowing the script to remove elements
in sublists, similar to lindex and lset."
} "*doc -name Manpage: -url [manpage_tcl lpop]"
} "@doc -name Manpage: -url [manpage_tcl lpop]"
punk::args::definition {
*id lrange
*proc -name "builtin: lrange" -help\
@id -id ::lrange
@cmd -name "builtin: lrange" -help\
"return one or more adjacent elements from a list.
The new list returned consists of elements first through last, inclusive.
The index values first and last are interpreted the same as index values
@ -304,20 +577,20 @@ tcl::namespace::eval punk::args::tclcore {
indices relative to the end of the list.
e.g lrange {a b c} 0 end-1
"
*values -min 3 -max 3
@values -min 3 -max 3
list -type list -help\
"tcl list as a value"
first -help\
"index expression for first element"
last -help\
"index expression for last element"
} "*doc -name Manpage: -url [manpage_tcl lrange]"
} "@doc -name Manpage: -url [manpage_tcl lrange]"
punk::args::definition {
*id tcl::string::cat
@id -id ::tcl::string::cat
*proc -name "builtin: tcl::string::cat" -help\
@cmd -name "builtin: tcl::string::cat" -help\
"Concatente the given strings just like placing them directly next to each other and
return the resulting compound string. If no strings are present, the result is an
empty string.
@ -326,14 +599,14 @@ tcl::namespace::eval punk::args::tclcore {
to return -level 0, and is more efficient than building a list of arguments and using
join with an empty join string."
*values -min 0 -max -1
@values -min 0 -max -1
string -type string -optional 1 -multiple 1
} "*doc -name Manpage: -url [manpage_tcl string]"
} "@doc -name Manpage: -url [manpage_tcl string]"
punk::args::definition {
*id tcl::string::compare
@id -id ::tcl::string::compare
*proc -name "builtin: tcl::string::compare" -help\
@cmd -name "builtin: tcl::string::compare" -help\
"Perform a character-by-character comparison of strings string1 and string2.
Returns -1, 0, or 1, dpending on whether string1 is lexicographically
lessthan, equal to, or greater than string2"
@ -345,15 +618,15 @@ tcl::namespace::eval punk::args::tclcore {
"If -length is specified, then only the first length characters are used in the comparison.
If -length is negative, it is ignored."
*values -min 2 -max 2
@values -min 2 -max 2
string1 -type string
string2 -type string
} "*doc -name Manpage: -url [manpage_tcl string]"
} "@doc -name Manpage: -url [manpage_tcl string]"
punk::args::definition {
*id tcl::string::equal
@id -id ::tcl::string::equal
*proc -name "builtin: tcl::string::equal" -help\
@cmd -name "builtin: tcl::string::equal" -help\
"Perform a character-by-character comparison of strings string1 and string2.
Returns 1 if string1 and string2 are identical, or 0 when not."
@ -364,30 +637,30 @@ tcl::namespace::eval punk::args::tclcore {
"If -length is specified, then only the first length characters are used in the comparison.
If -length is negative, it is ignored."
*values -min 2 -max 2
@values -min 2 -max 2
string1 -type string
string2 -type string
} "*doc -name Manpage: -url [manpage_tcl string]"
} "@doc -name Manpage: -url [manpage_tcl string]"
punk::args::definition {
*id tcl::string::first
*proc -name "builtin: tcl::string::first" -help\
@id -id ::tcl::string::first
@cmd -name "builtin: tcl::string::first" -help\
"Search haystackString for a sequence of characters that exactly match the characters
in needleString. If found, return the index of the first character in the first such
match within haystackString. If there is no match, then return -1. If startIndex is
specified (in any of the forms described in STRING_INDICES), then the search is
constrained to start with the character in haystackString specified by the index.
"
*values -min 2 -max 3
@values -min 2 -max 3
needleString -type string
haystackString -type string
startIndex -type indexexpression -optional 1 -help\
"integer or simple expression."
} "*doc -name Manpage: -url [manpage_tcl string]"
} "@doc -name Manpage: -url [manpage_tcl string]"
punk::args::definition {
*id tcl::string::insert
*proc -name "builtin: tcl::string::insert" -help\
@id -id ::tcl::string::insert
@cmd -name "builtin: tcl::string::insert" -help\
"Returns a copy of string with insertString inserted at the index'th character.
If index is start-relative, the first character inserted in the returned string will be
at the specified index.
@ -398,43 +671,43 @@ tcl::namespace::eval punk::args::tclcore {
If index is at or after the end of the string (e.g., index is end), insertString is
appended to string."
*values -min 3 -max 3
@values -min 3 -max 3
string -type string
index -type indexexpression -help\
"The index may be specified as described in the STRING_INDICES section"
insertString -type string
} "*doc -name Manpage: -url [manpage_tcl string]"
} "@doc -name Manpage: -url [manpage_tcl string]"
punk::args::definition {
*id tcl::string::last
*proc -name "builtin: tcl::string::last" -help\
@id -id ::tcl::string::last
@cmd -name "builtin: tcl::string::last" -help\
"Search haystackString for a sequence of characters that exactly match the characters
in needleString. If found, return the index of the first character in the last such
match within haystackString. If there is no match, then return -1. If lastIndex is
specified (in any of the forms described in STRING_INDICES), then only the characters
in haystackString at or before the specified lastIndex will be considered by the search
"
*values -min 2 -max 3
@values -min 2 -max 3
needleString -type string
haystackString -type string
lastIndex -type indexexpression -optional 1 -help\
"integer or simple expression."
} "*doc -name Manpage: -url [manpage_tcl string]"
} "@doc -name Manpage: -url [manpage_tcl string]"
punk::args::definition {
*id tcl::string::repeat
*proc -name "builtin: tcl::string::repeat" -help\
@id -id ::tcl::string::repeat
@cmd -name "builtin: tcl::string::repeat" -help\
"Returns a string consisting of string concatenated with itself count times."
*values -min 2 -max 2
@values -min 2 -max 2
string -type string
count -type int -help\
"If count is 0, the empty string will be returned."
} "*doc -name Manpage: -url [manpage_tcl string]"
} "@doc -name Manpage: -url [manpage_tcl string]"
punk::args::definition {
*id tcl::string::replace
*proc -name "builtin: tcl::string::replace" -help\
@id -id ::tcl::string::replace
@cmd -name "builtin: tcl::string::replace" -help\
"Removes a range of consecutive characters from string, starting with the character whose
index is first and ending with the character whose index is last
(Using the forms described in STRING_INDICES). An index of 0 refers to the first
@ -444,68 +717,68 @@ tcl::namespace::eval punk::args::tclcore {
end. The initial string is returned untouched, if first is greater than last, or if
first is equal to or greater than the length of the inital string, or last is less
than 0."
*values -min 3 -max 3
@values -min 3 -max 3
string -type string
first -type indexexpression
last -type indexexpression
newstring -type string -optional 1 -help\
"If newstring is specified, then it is placed in the removed character range."
} "*doc -name Manpage: -url [manpage_tcl string]"
} "@doc -name Manpage: -url [manpage_tcl string]"
punk::args::definition {
*id tcl::string::totitle
*proc -name "builtin: tcl::string::totitle" -help\
@id -id ::tcl::string::totitle
@cmd -name "builtin: tcl::string::totitle" -help\
"Returns a value equal to string except that the first character in string is converted to
it's Unicode title case variant (or upper case if there is no title case variant) and the
rest of the string is converted to lower case."
*values -min 1 -max 1
@values -min 1 -max 1
string -type string
first -type indexexpression -optional 1 -help\
"If first is specified, it refers to the first char index in the string to start modifying."
last -type indexexpression -optional 1 -help\
"If last is specified, it refers to the char index in the string to stop at (inclusive)."
} "*doc -name Manpage: -url [manpage_tcl string]"
} "@doc -name Manpage: -url [manpage_tcl string]"
punk::args::definition {
*id tcl::string::wordend
*proc -name "builtin: tcl::string::wordend" -help\
@id -id ::tcl::string::wordend
@cmd -name "builtin: tcl::string::wordend" -help\
"Returns the index of the character just after the last one in the word containing
character charIndex of string.
A word is considered to be any contiguous range of alphanumeric (Unicode letters or decimal digits)
or underscore (Unicode connector punctuation) characters, or any single character other than these."
*values -min 2 -max 2
@values -min 2 -max 2
string -type string
charIndex -type indexexpression -help\
"integer or simple expresssion.
e.g end
e.g end-1
e.g M+N"
} "*doc -name Manpage: -url [manpage_tcl string]"
} "@doc -name Manpage: -url [manpage_tcl string]"
punk::args::definition {
*id tcl::string::wordstart
*proc -name "builtin: tcl::string::wordstart" -help\
@id -id ::tcl::string::wordstart
@cmd -name "builtin: tcl::string::wordstart" -help\
"Returns the index of the first character in the word containing
character charIndex of string.
A word is considered to be any contiguous range of alphanumeric (Unicode letters or decimal digits)
or underscore (Unicode connector punctuation) characters, or any single character other than these.
"
*values -min 2 -max 2
@values -min 2 -max 2
string -type string
charIndex -type indexexpression -help\
"integer or simple expresssion.
e.g end
e.g end-1
e.g M+N"
} "*doc -name Manpage: -url [manpage_tcl string]"
} "@doc -name Manpage: -url [manpage_tcl string]"
punk::args::definition [punk::lib::tstr -return string {
*id tcl::string::is
*proc -name "builtin: tcl::string::is" -help\
@id -id ::tcl::string::is
@cmd -name "builtin: tcl::string::is" -help\
"Returns 1 if string is a valid member of the specified character class, otherwise returns 0.
"
*leaders -min 1 -max 1
@leaders -min 1 -max 1
class -type string\
-choices {
alnum
@ -649,15 +922,56 @@ tcl::namespace::eval punk::args::tclcore {
varname will always be set to 0, due to the varied nature of a valid boolean value"
-strict -type none -help\
"If -strictis specified, then an empty string returns 0,
"If -strict is specified, then an empty string returns 0,
otherwise an empty string will return 1 on any class"
-failindex -type variablename -help\
"If -failindex is specified, then if the function returns 0,
the index in the string where the class was no longer valid will be stored
in the variable named."
*values -min 1 -max 1
@values -min 1 -max 1
string -type string -optional 0
}] "*doc -name Manpage: -url [manpage_tcl string]"
}] "@doc -name Manpage: -url [manpage_tcl string]"
punk::args::definition {
@id -id ::zlib
@cmd -name "builtin: ::zlib" -help\
"zlib - compression and decompression operations
"
@leaders -min 1 -max 1
subcommand -type string\
-choicecolumns 2\
-choicegroups {
compression {compress decompress deflate gunzip gzip inflate}
channel {push}
streaming {stream}
checksumming {adler32 crc32}
}\
-choicelabels {
compress "zlib compress string ?level?"
decompress "zlib decompress string ?buffersize?"
deflate "zlib deflate string ?level?"
gunzip "zlib gunzip string ?-headerVar varName?"
gzip "zlib gzip string ?-level level? ?-header dict?"
inflate "zlib inflate string ?bufferSize?"
push "zlib push mode channel ?options ...?"
stream "zlib stream mode ?options?"
adler32 "zlib adler32 string ?initValue?"
crc32 "zlib crc32 string ?initValue?"
}
} "@doc -name Manpage: -url [manpage_tcl zlib]"
punk::args::definition {
@id -id "::zlib adler32"
@cmd -name "builtin: ::zlib adler32" -help\
"Compute a checksum of binary string ${$I}string${$NI} using the Adler32
algorithm. If given, ${$I}initValue${$NI} is used to initialize the checksum engine.
"
@values -min 1 -max 2
string -type string
initValue -type string -optional 1
} "@doc -name Manpage: -url [manpage_tcl zlib]"
#*** !doctools
#[subsection {Namespace punk::args::tclcore}]

18
src/vfs/_vfscommon.vfs/modules/punk/blockletter-0.1.0.tm

@ -120,17 +120,17 @@ tcl::namespace::eval punk::blockletter {
set logo_letter_colours [list Red Green Blue Purple Yellow]
punk::args::definition [tstr -return string {
*id punk::blockletter::logo
@id -id ::punk::blockletter::logo
-frametype -default {${$default_frametype}}
-outlinecolour -default "web-white"
-backgroundcolour -default {} -help "e.g Web-white
This argument is the name as accepted by punk::ansi::a+"
*values -min 0 -max 0
@values -min 0 -max 0
}]
proc logo {args} {
variable logo_letter_colours
variable default_frametype
set argd [punk::args::get_by_id punk::blockletter::logo $args]
set argd [punk::args::get_by_id ::punk::blockletter::logo $args]
set f [dict get $argd opts -frametype]
set bd [dict get $argd opts -outlinecolour]
set bgansi [dict get $argd opts -backgroundcolour] ;#we use ta::detect to see if already ansi and apply as necessary
@ -219,17 +219,17 @@ tcl::namespace::eval punk::blockletter {
}
punk::args::definition [tstr -return string {
*id punk::blockletter::text
@id -id ::punk::blockletter::text
-bgcolour -default "Web-red"
-bordercolour -default "web-white"
-frametype -default {${$default_frametype}}
*values -min 1 -max 1
@values -min 1 -max 1
str -help "Text to convert to blockletters
Requires terminal font to support relevant block characters"
"
}]
proc text {args} {
set argd [punk::args::get_by_id punk::blockletter::text $args]
set argd [punk::args::get_by_id ::punk::blockletter::text $args]
set opts [dict get $argd opts]
set str [dict get $argd values str]
set str [string map {\r\n \n} $str]
@ -281,17 +281,17 @@ tcl::namespace::eval punk::blockletter::lib {
punk::args::definition [tstr -return string {
*id punk::blockletter::block
@id -id ::punk::blockletter::block
-height -default 2
-width -default 4
-frametype -default {${$::punk::blockletter::default_frametype}}
-bgcolour -default "Web-red"
-bordercolour -default "web-white"
*values -min 0 -max 0
@values -min 0 -max 0
}]
proc block {args} {
upvar ::punk::blockletter::default_frametype ft
set argd [punk::args::get_by_id punk::blockletter::block $args]
set argd [punk::args::get_by_id ::punk::blockletter::block $args]
set bg [dict get $argd opts -bgcolour]
set bd [dict get $argd opts -bordercolour]
set h [dict get $argd opts -height]

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save