Browse Source

bring overtype module into project, punk::lib::is_main_script etc

master
Julian Noble 2 weeks ago
parent
commit
1dc8f038df
  1. 5012
      src/bootsupport/modules/punk/lib-0.1.5.tm
  2. 9
      src/bootsupport/modules/punk/ns-0.1.0.tm
  3. 249
      src/modules/overtype-999999.0a1.0.tm
  4. 3
      src/modules/overtype-buildversion.txt
  5. 3
      src/modules/punk/args-999999.0a1.0.tm
  6. 18
      src/modules/punk/args/moduledoc/tclcore-999999.0a1.0.tm
  7. 446
      src/modules/punk/layout-999999.0a1.0.tm
  8. 3
      src/modules/punk/layout-buildversion.txt
  9. 31
      src/modules/punk/lib-999999.0a1.0.tm
  10. 2
      src/modules/punk/lib-buildversion.txt
  11. 165
      src/modules/punk/netbox-999999.0a1.0.tm
  12. 5012
      src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/lib-0.1.5.tm
  13. 5012
      src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/lib-0.1.5.tm
  14. 4
      src/vendormodules/include_modules.config
  15. 9470
      src/vendormodules/tomlish-1.1.7.tm
  16. 121
      src/vfs/_vfscommon.vfs/modules/overtype-1.7.3.tm
  17. 3
      src/vfs/_vfscommon.vfs/modules/punk/args-0.2.1.tm
  18. 18
      src/vfs/_vfscommon.vfs/modules/punk/args/moduledoc/tclcore-0.1.0.tm
  19. 446
      src/vfs/_vfscommon.vfs/modules/punk/layout-0.1.0.tm
  20. 27
      src/vfs/_vfscommon.vfs/modules/punk/lib-0.1.4.tm
  21. 5012
      src/vfs/_vfscommon.vfs/modules/punk/lib-0.1.5.tm
  22. 165
      src/vfs/_vfscommon.vfs/modules/punk/netbox-0.1.0.tm
  23. 9470
      src/vfs/_vfscommon.vfs/modules/tomlish-1.1.7.tm

5012
src/bootsupport/modules/punk/lib-0.1.5.tm

File diff suppressed because it is too large Load Diff

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

@ -5077,9 +5077,12 @@ y" {return quirkykeyscript}
lpop queryargs_untested 0
lappend eparams $q
puts stderr "---> cmd_traverse ensembleparam $q ($lname)"
puts stderr "arginfo: $arginfo"
puts stderr "---> eparams: $eparams"
puts stderr "---> existing args: $args"
#puts stderr "arginfo: $arginfo"
#puts stderr "---> eparams: $eparams"
#puts stderr "---> existing args: $args"
#ledit queryargs_untested 0 0
#review - add tests

249
src/vendormodules/overtype-1.7.1.tm → src/modules/overtype-999999.0a1.0.tm

@ -7,7 +7,7 @@
# (C) Julian Noble 2003-2023
#
# @@ Meta Begin
# Application overtype 1.7.1
# Application overtype 999999.0a1.0
# Meta platform tcl
# Meta license BSD
# @@ Meta End
@ -17,7 +17,7 @@
# doctools header
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
#*** !doctools
#[manpage_begin overtype_module_overtype 0 1.7.1]
#[manpage_begin overtype_module_overtype 0 999999.0a1.0]
#[copyright "2024"]
#[titledesc {overtype text layout - ansi aware}] [comment {-- Name section and table of contents description --}]
#[moddesc {overtype text layout}] [comment {-- Description at end of page heading --}]
@ -117,7 +117,7 @@ tcl::namespace::eval overtype {
priv::_init
}
proc overtype::about {} {
return "Simple text formatting. Author JMN. BSD-License"
return "ANSI capable text formatting. Author JMN. BSD-License"
}
tcl::namespace::eval overtype {
@ -193,6 +193,78 @@ tcl::namespace::eval overtype {
#[para] Core API functions for overtype
#[list_begin definitions]
namespace eval argdoc {
variable PUNKARGS
#non-colour SGR codes
set I "\x1b\[3m" ;# [a+ italic]
set NI "\x1b\[23m" ;# [a+ noitalic]
set B "\x1b\[1m" ;# [a+ bold]
set N "\x1b\[22m" ;# [a+ normal]
set T "\x1b\[1\;4m" ;# [a+ bold underline]
set NT "\x1b\[22\;24m\x1b\[4:0m" ;# [a+ normal nounderline]
interp alias "" ::overtype::example "" ::punk::args::helpers::example
}
namespace eval argdoc {
variable PUNKARGS
lappend PUNKARGS [list {
@id -id ::overtype::renderspace
@cmd -name overtype::renderspace\
-summary\
{}\
-help\
{}
@opts
#because underblocks value is optional - restrict opts to flag pairs (no solos)
#We don't use punk::args::parse in the actual function to parse args - so keep it simpler.
-bias -default left -type string -choices {left right} -help ignored
-width -default \uFFEF -type integer
-height -default \uFFEF -type integer
-startcolumn -default 1 -type integer
-startrow -default 1 -type integer
-ellipsis -default 0 -type boolean
-ellipsistext -default ${$::overtype::default_ellipsis_horizontal} -type char
-ellipsiswhitespace -default 0 -type boolean
-expand_right -default 0 -type boolean
-appendlines -default 1 -type boolean
-transparent -default 0 -type {literal(0)|literal(1)|regexp} -help\
"0 to disable transparency processing
1 to enable space characters in the
overlay to be transparent, or a regex
to match the character(s) required to be
transparent in the overlay."
-exposed1 -default \uFFFD -type char -help\
{A character of single terminal column width to use
as replacement when first-half of an underlying char
is exposed due to overlay positioning/transparency
which obscures the second-half of the char. May be ANSI
coloured as this doesn't affect the display width.
Default is \uFFFD - the unicode replacement char.}
-exposed2 -default \uFFFD -type char -help\
{A character of single terminal column width to use
as replacement when second-half of an underlying char
is exposed due to overlay positioning/transparency
which obscures the first-half of the char. May be ANSI
coloured as this doesn't affect the display width.
Default is \uFFFD - the unicode replacement char.}
-experimental -default 0
-cp437 -default 0 -type boolean
-looplimit -default \uFFEF\ -type integer -help\
"internal failsafe - experimental"
-crm_mode -default 0 -type boolean
-reverse_mode -default 0 -type boolean
-insert_mode -default 1 -type boolean
-wrap -default 0 -type boolean
-info -default 0 -type boolean -help\
"When set to 1, return a dictionary (experimental)"
-console -default {stdin stdout stderr} -type list
@values -min 1 -max 2
underblock -type string -optional 1
overblock -type string -optional 0
}]
}
#tcl::string::range should generally be avoided for both undertext and overtext which contain ansi escapes and other cursor affecting chars such as \b and \r
@ -211,7 +283,7 @@ tcl::namespace::eval overtype {
# @c can/should we use something like this?: 'format "%-*s" $len $overtext
variable default_ellipsis_horizontal
if {[llength $args] < 2} {
if {[llength $args] < 1} {
error {usage: ?-width <int>? ?-startcolumn <int>? ?-transparent [0|1|<char>]? ?-expand_right [1|0]? ?-ellipsis [1|0]? ?-ellipsistext ...? undertext overtext}
}
set optargs [lrange $args 0 end-2]
@ -221,20 +293,26 @@ tcl::namespace::eval overtype {
#lassign [lrange $args end-1 end] underblock overblock
set argsflags [lrange $args 0 end-2]
} else {
set optargs [lrange $args 0 end-1]
if {[llength $optargs] %2 == 0} {
set overblock [lindex $args end]
set underblock ""
set argsflags [lrange $args 0 end-1]
} else {
error "renderspace expects opt-val pairs followed by: <underblock> <overblock> or just <overblock>"
}
#no solo flags - so we assume only an overblock was supplied
set overblock [lindex $args end]
set underblock ""
set argsflags [lrange $args 0 end-1]
#set optargs [lrange $args 0 end-1]
#if {[llength $optargs] %2 == 0} {
# set overblock [lindex $args end]
# set underblock ""
# set argsflags [lrange $args 0 end-1]
#} else {
# error "renderspace expects opt-val pairs followed by: <underblock> <overblock> or just <overblock>"
#}
}
set opts [tcl::dict::create\
-bias ignored\
-width \uFFEF\
-height \uFFEF\
-startcolumn 1\
-startrow 1\
-ellipsis 0\
-ellipsistext $default_ellipsis_horizontal\
-ellipsiswhitespace 0\
@ -266,7 +344,7 @@ tcl::namespace::eval overtype {
#-ellipsis args not used if -wrap is true
foreach {k v} $argsflags {
switch -- $k {
-looplimit - -width - -height - -startcolumn - -bias - -ellipsis - -ellipsistext - -ellipsiswhitespace
-looplimit - -width - -height - -startcolumn - -startrow - -bias - -ellipsis - -ellipsistext - -ellipsiswhitespace
- -transparent - -exposed1 - -exposed2 - -experimental
- -expand_right - -appendlines
- -reverse_mode - -crm_mode - -insert_mode
@ -292,6 +370,7 @@ tcl::namespace::eval overtype {
set opt_width [tcl::dict::get $opts -width]
set opt_height [tcl::dict::get $opts -height]
set opt_startcolumn [tcl::dict::get $opts -startcolumn]
set opt_startrow [tcl::dict::get $opts -startrow]
set opt_appendlines [tcl::dict::get $opts -appendlines]
set opt_transparent [tcl::dict::get $opts -transparent]
set opt_ellipsistext [tcl::dict::get $opts -ellipsistext]
@ -333,6 +412,10 @@ tcl::namespace::eval overtype {
set underblock [tcl::string::map {\r\n \n} $underblock]
set overblock [tcl::string::map {\r\n \n} $overblock]
if {$opt_startrow > 1} {
set down [expr {$opt_startrow -1}]
set overblock [punk::ansi::move_down $down]$overblock
}
#set underlines [split $underblock \n]
@ -1773,20 +1856,123 @@ tcl::namespace::eval overtype {
variable optimise_ptruns 10 ;# can be set to zero to disable the ptruns branches
# ## ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ###
# renderline written from a left-right line orientation perspective as a first-shot at getting something useful.
# ultimately right-to-left, top-to-bottom and bottom-to-top are probably needed.
# ## ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ###
#
#
#-returnextra enables returning of overflow and length
#review - use punk::ansi::ta::detect to short-circuit processing and do simpler string calcs as an optimisation?
#review - DECSWL/DECDWL double width line codes - very difficult/impossible to align and compose with other elements
#(could render it by faking it with sixels and a lot of work - find/make a sixel font and ensure it's exactly 2 cols per char?
# This would probably be impractical to support for different fonts)
#todo - review transparency issues with single/double width characters
#bidi - need a base direction and concept of directional runs for RTL vs LTR - may be best handled at another layer?
namespace eval argdoc {
variable PUNKARGS
lappend PUNKARGS [list {
@id -id ::overtype::renderline
@cmd -name overtype::renderline\
-summary\
{Render a line of text/ANSI input over a line of text.}\
-help\
{renderline is the core engine for overtype string processing (frames & textblocks), and the raw mode
commandline repl for the Tcl Punk Shell.
It is also a central part of an ansi (micro) virtual terminal-emulator of sorts.
This system does a half decent job at rendering 90's ANSI art to manipulable colour text blocks that
can be joined & framed for layout display within a unix or windows terminal.
Renderline helps maintain ANSI text styling reset/replay codes so that the styling of one block doesn't
affect another.
Calling on the punk::ansi library - it can coalesce codes to keep the size down.
It is a giant mess of doing exactly what common wisdom says not to do... lots at once.
Renderline is part of the Unicode and ANSI aware Overtype system which 'renders' a block of text onto a
static underlay.
The underlay is generally expected to be an ordered set of lines or a rectangular text block analogous
to a terminal screen - but it can also be ragged in line length, or just blank.
The overlay couuld be similar - in which case it may often be used to overwrite a column or section of
the underlay.
The overlay could however be a sequence of ANSI-laden text that jumps all over the place.
Renderline itself only deals with a single line - or sometimes a single character. It is generally
called from a loop that does further terminal-like or textblock processing.
By suppyling the ${$B}-info${$N} 1 option - it can return various fields indicating the state of the render.
The main 3 are: result, overflow_right, and unapplied.
Renderline handles cursor movements from either keystrokes or ANSI sequences but for a full system the
aforementioned loop will need to be in place to manage the set of lines under manipulation.
}
@opts
-etabs -default 0 -type boolean
-width -default \uFFEF -type integer
-expand_right -default 0 -type boolean
-transparent -default 0 -type {literal(0)|literal(1)|regexp} -help\
"0 to disable transparency processing
1 to enable space characters in the
overlay to be transparent, or a regex
to match the character(s) required to be
transparent in the overlay."
-startcolumn -default 1 -type integer
-cursor_column -default 1 -type integer -help\
{First column is 1. Cursor column can be zero or negative}
-cursor_row -default "" -type integer
-insert_mode -default 1 -type boolean
-crm_mode -default 0 -type boolean
-autowrap_mode -default 1 -type boolean
-reverse_mode -default 0 -type boolean
-info -default 0 -type boolean -help\
"When set to 1, return a dictionary of settings useful for
processing ANSI input in a loop. When zero, the resulting
string will contain the updated line, but not all the
overtext may have been applied."
-exposed1 -default \uFFFD -help\
{A character of single terminal column width to use
as replacement when first-half of an underlying char
is exposed due to overlay positioning/transparency
which obscures the second-half of the char. May be ANSI
coloured as this doesn't affect the display width.
Default is \uFFFD - the unicode replacement char.}
-exposed2 -default \uFFFD -help\
{A character of single terminal column width to use
as replacement when second-half of an underlying char
is exposed due to overlay positioning/transparency
which obscures the first-half of the char. May be ANSI
coloured as this doesn't affect the display width.
Default is \uFFFD - the unicode replacement char.}
-cursor_restore_attributes -default ""
-cp437 -default 0 -type boolean
-experimental -default {}
@values -min 2 -max 2
undertext -type string -help\
"A single line of text which may contain pre-rendered ANSI.
'pre-rendered' in this context means that it may contain
various static ANSI codes such as SGR colours and attributes
but not motion-control or more complex ANSI sequences.
It is an error to supply a newline (lf) character in the
undertext."
overtext -type string -help\
"ANSI (or plain text) to overlay onto the undertext.
May contain ANSI movement codes even if they would move the
cursor to another line. If -info is zero, the output will
only display up to the point where the cursor moved off-line.
If -info is 1, the line moved to may be reflected in the
cursor_row element of the result. Overtext may contain an lf
which is effectively a form of 'movement control' to increment
the row.
Other ANSI codes may perform operations such as changing the
insert_mode or reverse_mode - and these are reflected in the
result dictionary when '-info 1' is used, so that the state
can then be applied to subsequent lines."
}]
}
proc renderline {args} {
# ## ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ###
# renderline written from a left-right line orientation perspective as a first-shot at getting something useful.
# ultimately right-to-left, top-to-bottom and bottom-to-top are probably needed.
# ## ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ###
#
#
#-returnextra enables returning of overflow and length
#review - use punk::ansi::ta::detect to short-circuit processing and do simpler string calcs as an optimisation?
#review - DECSWL/DECDWL double width line codes - very difficult/impossible to align and compose with other elements
#(could render it by faking it with sixels and a lot of work - find/make a sixel font and ensure it's exactly 2 cols per char?
# This would probably be impractical to support for different fonts)
#todo - review transparency issues with single/double width characters
#bidi - need a base direction and concept of directional runs for RTL vs LTR - may be best handled at another layer?
#*** !doctools
#[call [fun overtype::renderline] [arg args] ]
#[para] renderline is the core engine for overtype string processing (frames & textblocks), and the raw mode commandline repl for the Tcl Punk Shell
@ -4430,7 +4616,7 @@ tcl::namespace::eval overtype::piper {
# -- --- --- --- --- --- --- --- --- --- ---
proc overtype::transparentline {args} {
proc overtype::renderline_transparent {args} {
foreach {under over} [lrange $args end-1 end] break
set argsflags [lrange $args 0 end-2]
set defaults [tcl::dict::create\
@ -4760,11 +4946,18 @@ tcl::namespace::eval overtype {
interp alias {} ::overtype::center {} ::overtype::centre
}
namespace eval ::punk::args::register {
#use fully qualified so 8.6 doesn't find existing var in global namespace
lappend ::punk::args::register::NAMESPACES ::overtype ::overtype::argdoc
}
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
## Ready
package provide overtype [tcl::namespace::eval overtype {
variable version
set version 1.7.1
set version 999999.0a1.0
}]
return

3
src/modules/overtype-buildversion.txt

@ -0,0 +1,3 @@
1.7.3
#First line must be a semantic version number
#all other lines are ignored.

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

@ -6345,7 +6345,8 @@ tcl::namespace::eval punk::args {
}
}
indexexpression {
if {[catch {lindex {} $e_check}]} {
#tcl 9.1+? tip 615 'string is index'
if {$echeck eq "" || [catch {lindex {} $e_check}]} {
set msg "$argclass $argname for %caller% requires type indexexpression. An index as used in Tcl list commands. Received: '$e_check'"
#return -options [list -code error -errorcode [list PUNKARGS VALIDATION [list typemismatch $type] -badarg $argname -argspecs $argspecs]] $msg
lset clause_results $c_idx $a_idx [list errorcode [list PUNKARGS VALIDATION [list typemismatch $type] -badarg $argname -argspecs $argspecs] msg $msg]

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

@ -6020,6 +6020,13 @@ tcl::namespace::eval punk::args::moduledoc::tclcore {
@values -min 3 -max -1
listVar -type string -help\
"Existing list variable name"
#note if tip 615 implemented for 9.1 'first' and 'last' need to accept empty string too
#same for lrange, lreplace, string range, string replace
#if {[package vsatisfies [package provide Tcl] 9.1-]} {
# first -type {indexexpression|literal()}
#} else {
# first -type indexexpression
#}
first -type indexexpression
last -type indexexpression
value -type any -optional 1 -multiple 1
@ -6086,10 +6093,21 @@ tcl::namespace::eval punk::args::moduledoc::tclcore {
If additional index arguments are supplied, then each argument is used in turn
to select an element from the previous indexing operation, allowing the script
to select elements from sublists."
@form -form separate
@values -min 1 -max -1
list -type list -help\
"tcl list as a value"
index -type indexexpression -multiple 1 -optional 1
@form -form combined
@values -min 2 -max 2
list -type list -help\
"tcl list as a value"
#list of indexexpression
indexlist -type list -optional 0 -help\
"list of indexexpressions"
} "@doc -name Manpage: -url [manpage_tcl lindex]"\
{
@examples -help {

446
src/modules/punk/layout-999999.0a1.0.tm

@ -0,0 +1,446 @@
# -*- tcl -*-
# Maintenance Instruction: leave the 999999.xxx.x as is and use punkshell 'dev make' or bin/punkmake to update from <pkg>-buildversion.txt
# module template: shellspy/src/decktemplates/vendor/punk/modules/template_module-0.0.4.tm
#
# Please consider using a BSD or MIT style license for greatest compatibility with the Tcl ecosystem.
# Code using preferred Tcl licenses can be eligible for inclusion in Tcllib, Tklib and the punk package repository.
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
# (C) 2025
#
# @@ Meta Begin
# Application punk::layout 999999.0a1.0
# Meta platform tcl
# Meta license MIT
# @@ Meta End
#EXPERIMENTAL
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
## Requirements
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
package require Tcl 8.6-
package require punk::args
#experimental layout library based on Nic Barker's Clay
# CLAY(CLAY_ID("parent"), { .layout = { .padding = CLAY_PADDING_ALL(8) } }) {
# // Child element 1
# CLAY_TEXT(CLAY_STRING("Hello World"), CLAY_TEXT_CONFIG({ .fontSize = 16 }));
# // Child element 2 with red background
# CLAY(CLAY_ID("child"), { .backgroundColor = COLOR_RED }) {
# // etc
# }
# }
#Tcl translation?
#CLAY ?-opt <val>..? ?childblock?
#eg
#CLAY -id <string> -layout <dict> -rectangle <dict> { childblock }
#where childblock is curly braced code block
# clay -id "parent" -layout [dict create .padding [padding_all 8]] {
# clay_text "Hello World" [clay_textconfig {.fontsize 16}]
# clay -id "child" -config {.backgroundColor red} {
# # etc
# }
# }
#for padding on a terminal - we are limited by cell_size - which is not square. (and may vary on terminals??)
# e.g punk::console::cell_size returns cell wxh
# -> 10x20
# (either queried from terminal - or defaults to 10x20 if can't be queried)
#so the minimum 'even' padding we can have is 2 space for horizontal, 1 line vertical
#we can pad a minimum of 1 space horizontall (10 units) and a minimum of 1 line vertically (20 units)
# CLAY_PADDING {<l> <r> <t> <b>}
#how then should we handle .padding {16 16 8 8} - quantize by roundup to h 10 and v 20?
# -> {20 20 20 20} ?
# or round to nearest vertical and horizontal quanta?
# -> {20 20 0 0}
#either way - {16 16 16 16} goes to {20 20 20 20} - which is *close* to equal v h padding
# - but not perfect visually because fonts within a cell have baseline, topline etc internal padding too?
#building a ui ?
#clay_begin_layout
# // build UI here
#set rendercommands [clay_end_layout]
#some_render_command $rendercommands
#eg2 (from introducing clay video https://www.youtube.com/watch?v=DYWTw19_8r4&t=2s)
#something like the following?
# (stopped at around the scroll point - need to work out console mouse features. punk::console::mouse_enable ...)
#extracted out common layout 'sizing' for grow in both directions
#set layoutExpand {
# width CLAY_SIZING_GROW
# heigth CLAY_SIZING GROW
# }
#extracted out common background panel
#set contentBackgroundConfig {
# colour Term-grey
# frametype arc
# }
#proc RenderHeaderButton {} {} ;#??
#set documents [dict create\
# Squirrels "The secret life of Squirrels"\
# "Lorem Ipsum" "Orem ipsum dolor sit ..\netc blah"\
# "Vacuum instructions" "Chapter 3: Getting Started"\
# "Article 4" "Article 4"\
# "Article 5" "Article 5"\
# ]
#set selectedDocumentIndex 0
#clay_begin_layout
#clay -id "OuterContainer"\
# -item [clay_rectangle {colour web-red}]
# -layout [clay_layout [dict create\
# layoutDirection CLAY_TOP_TO_BOTTOM\
# sizing $layoutExpand\
# padding {16 16}\
# childGap 16\
# ]]\
# {
# # Child elements
# clay -id "HeaderBar"\
# -item [clay_rectangle $contentBackgroundConfig]\
# -layout [clay_layout {
# sizing {
# height 60
# width CLAY_SIZING_GROW
# }
# padding {8 8}
# childGap 8
# childAlignment {
# y CLAY_ALIGN_Y_CENTER
# }
# }]\
# {
# # Header buttons go here
# RenderheaderButton [clay_string "File"]
# RenderheaderButton [clay_string "Edit"]
# #push last 3 buttons to rhs by using a layout in between to take up the middle space
# CLAY -layout {sizing {width CLAY_SIZING_GROW}} {}
# RenderheaderButton [clay_string "Upload"]
# RenderheaderButton [clay_string "Media"]
# RenderheaderButton [clay_string "Support"]
# }
# clay -id "LowerContent"\
# -layout [dict create sizing $layoutExpand childGap 16]\
# {
# clay -id "Sidebar"\
# -item [clay_rectangle $contentBackgroundConfig]\
# -layout {
# layoutDirection CLAY_TOP_TO_BOTTOM
# padding {8 8}
# childgap {20}
# sizing {
# width = 60
# height = CLAY_SIZING_GROW
# }\
# }\
# {
# #render dynamic data
# dict for {title data} $documents {
# clay -layout {padding {8 8}\
# {
# #fontId, fontSize not really practical on terminal
# clay_text $title [clay_text_config {
# textColor cyan
# }]
# }
# }
# }
# clay -id "MainContent"\
# -item [clay_rectangle $contentBackgroundConfig]\
# -scroll {vertical true}\
# -layout [dict create\
# layoutDirection = CLAY_TOP_TO_BOTTOM\
# childGap 20\
# padding {16 16 20 20}\
# sizing $layoutExpand\
# ]\
# {
# set selectedTitle [lindex [dict keys $documents] $selectedDocumentIndex]
# clay_text $selectedTitle [clay_text_config {
# textcolour {web-white bold}
# }]
# clay_text [dict get $documents $selectedTitle] [clay_text_config {
# textcolour {web-white}
# }]
# }
# }
# }
#set rendercommands [clay_end_layout]
#CLAY_SIZING_GROW
#CLAY_SIZING_FIT ;#default
tcl::namespace::eval punk::layout {
variable PUNKARGS
namespace eval argdoc {
variable PUNKARGS
namespace eval argdoc {
#non-colour SGR codes
set I "\x1b\[3m" ;# [a+ italic]
set NI "\x1b\[23m" ;# [a+ noitalic]
set B "\x1b\[1m" ;# [a+ bold]
set N "\x1b\[22m" ;# [a+ normal]
set T "\x1b\[1\;4m" ;# [a+ bold underline]
set NT "\x1b\[22\;24m\x1b\[4:0m" ;# [a+ normal nounderline]
}
}
#elementDeclaration
#data structure (CLAY UIElement struct equivalent)
#set eg_element [dict create\
# position {1 1}\
# size {80 24}\
# children [list]\
#]
#elementConfig
#set eg_item [dict create\
# type rectangle\
# color {red bold}\
# borderColor {yellow}
# frametype {}\
#]
# etc
proc DrawRectangle {element} {
set position [dict get $element position] ;#x y
set size [dict get $element size] ;#width height
lassign $size w h
set bg [dict get $element color]
set borderColor [dict get $element borderColor]
set frametype [dict get $element frametype]
if {$frametype eq ""} {
#much faster than textblock::frame
set content [textblock::block $w $h "[a+ $bg] [a]"]
} else {
#slow - and frame background colours will always overlap the borders so we can never get a nicely filled arc frame for example
#The best bordered
set content [textblock::frame -type $frametype -ansibase [a+ $bg] -ansiborder [a+ $borderColor] -width $w -height $h " "]
}
}
proc RenderElement {element} {
}
#TODO
#The clay_begin_layout - clay_end_layout structure suggests the main API may be better represented as an oo object maintaining state
#we may need to have multiple instances running concurrently
#Clay conceptually runs in 'immediate' mode - ie recalculating each full layout each time we need to render
variable rendercommands
proc clay_begin_layout {} {
variable rendercommands
set rendercommands [dict create]
#...?
}
proc clay_end_layout {} {
variable rendercommands
#...?
return $rendercommands
}
namespace eval argdoc {
variable PUNKARGS
lappend PUNKARGS [list {
@id -id ::punk::layout::clay
@cmd -name punk::layout::clay
@opts
-id -type string
-item -type dict
-layout -type dict
-backgroundColor -type list -help\
"ANSI colour codes as documented in punk::ansi::a?"
@values -min 0 -max 1
childscript -type script
}]
}
#For initial proof of concept - we will use punk::args for *parsing* as well as documenting
#For final version - the extra overhead of punk::args::parse may not be suitable for large numbers of
#calls in 'immediate' mode - so punk::args::parse should be used on 'unhappy' paths only,
#with a fast switch statement used for actual option parsing.
#As performance is likely to be an issue - we should also avoid allowing 'prefixes' for arguments
proc clay {args} {
set argd [punk::args::parse $args withid ::punk::layout::clay] ;#temporary during concept development - todo: change to manual parsing for performance.
}
#
}
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
# Secondary API namespace
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
tcl::namespace::eval punk::layout::lib {
tcl::namespace::export {[a-z]*} ;# Convention: export all lowercase
tcl::namespace::path [tcl::namespace::parent]
#STEPS
#Fit Sizing -> Grow Sizing -> Positions -> Draw
#tree traversal
#(reverse breadth first) (breadth first)
# via OpenElement/CloseElement? (expand our grow containers
# into any available space)
proc OpenElement {element} {
#pseudo...
#set layoutDirection $layoutconfig.layoutDirection
#if {$layoutDirection eq "CLAY_LEFT_TO_RIGHT"} {
#} else {
# #CLAY_TOP_TO_BOTTOM
#}
}
proc CloseElement {element} {
#element.parent.width += element.width
#element.parent.height += element.height
}
proc SizeContainersAlongAxis {is_x_axis totalSizeToDistribute} {
}
proc CalculateFinalLayout {} {
}
}
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
#tcl::namespace::eval punk::layout::system {
#}
# == === === === === === === === === === === === === === ===
# Sample 'about' function with punk::args documentation
# == === === === === === === === === === === === === === ===
tcl::namespace::eval punk::layout {
tcl::namespace::export {[a-z]*} ;# Convention: export all lowercase
variable PUNKARGS
variable PUNKARGS_aliases
lappend PUNKARGS [list {
@id -id "(package)punk::layout"
@package -name "punk::layout" -help\
"EXPERIMENTAL - not done"
}]
namespace eval argdoc {
#namespace for custom argument documentation
proc package_name {} {
return punk::layout
}
proc about_topics {} {
#info commands results are returned in an arbitrary order (like array keys)
set topic_funs [info commands [namespace current]::get_topic_*]
set about_topics [list]
foreach f $topic_funs {
set tail [namespace tail $f]
lappend about_topics [string range $tail [string length get_topic_] end]
}
#Adjust this function or 'default_topics' if a different order is required
return [lsort $about_topics]
}
proc default_topics {} {return [list Description *]}
# -------------------------------------------------------------
# get_topic_ functions add more to auto-include in about topics
# -------------------------------------------------------------
proc get_topic_Description {} {
punk::args::lib::tstr [string trim {
package punk::layout
An experiment in using CLAY UI style layout on the terminal
INCOMPLETE...
status: notes and started framework only - nothing usable.
} \n]
}
proc get_topic_License {} {
return "MIT"
}
proc get_topic_Version {} {
return "$::punk::layout::version"
}
proc get_topic_Contributors {} {
set authors {{Julian Noble <julian@precisium.com.au}}
set contributors ""
foreach a $authors {
append contributors $a \n
}
if {[string index $contributors end] eq "\n"} {
set contributors [string range $contributors 0 end-1]
}
return $contributors
}
proc get_topic_concepts {} {
punk::args::lib::tstr -return string {
see Nic Barker's youtube video: How Clay's UI Layout Algorithm Works
https://www.youtube.com/watch?v=by9lQvpvMIc
}
}
# -------------------------------------------------------------
}
# we re-use the argument definition from punk::args::standard_about and override some items
set overrides [dict create]
dict set overrides @id -id "::punk::layout::about"
dict set overrides @cmd -name "punk::layout::about"
dict set overrides @cmd -help [string trim [punk::args::lib::tstr {
About punk::layout
}] \n]
dict set overrides topic -choices [list {*}[punk::layout::argdoc::about_topics] *]
dict set overrides topic -choicerestricted 1
dict set overrides topic -default [punk::layout::argdoc::default_topics] ;#if -default is present 'topic' will always appear in parsed 'values' dict
set newdef [punk::args::resolved_def -antiglobs -package_about_namespace -override $overrides ::punk::args::package::standard_about *]
lappend PUNKARGS [list $newdef]
proc about {args} {
package require punk::args
#standard_about accepts additional choices for topic - but we need to normalize any abbreviations to full topic name before passing on
set argd [punk::args::parse $args withid ::punk::layout::about]
lassign [dict values $argd] _leaders opts values _received
punk::args::package::standard_about -package_about_namespace ::punk::layout::argdoc {*}$opts {*}[dict get $values topic]
}
}
# end of sample 'about' function
# == === === === === === === === === === === === === === ===
# -----------------------------------------------------------------------------
# register namespace(s) to have PUNKARGS,PUNKARGS_aliases variables checked
# -----------------------------------------------------------------------------
# variable PUNKARGS
# variable PUNKARGS_aliases
namespace eval ::punk::args::register {
#use fully qualified so 8.6 doesn't find existing var in global namespace
lappend ::punk::args::register::NAMESPACES ::punk::layout
}
# -----------------------------------------------------------------------------
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
## Ready
package provide punk::layout [tcl::namespace::eval punk::layout {
variable pkg punk::layout
variable version
set version 999999.0a1.0
}]
return

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

@ -0,0 +1,3 @@
0.1.0
#First line must be a semantic version number
#all other lines are ignored.

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

@ -539,6 +539,37 @@ namespace eval punk::lib {
set NT "\x1b\[22\;24m\x1b\[4:0m" ;# [a+ normal nounderline]
}
namespace eval argdoc {
variable PUNKARGS
lappend PUNKARGS [list {
@id -id ::punk::lib::is_main_script
@cmd -name punk::lib::is_main_script\
-summary\
"Test if current script was launched directly."\
-help\
"The ${$B}main script${$N} is the primary script that is executed
by the interpreter, e.g. tclsh or wish.
(as opposed to being loaded by the 'source' command)
see https://wiki.tcl-lang.org/page/main+script"
@values -min 0 -max 0
}]
}
proc is_main_script {} {
#see https://wiki.tcl-lang.org/page/main+script
if {[info script] ne "" && [info exists ::argv0]
&&
[file dirname [file normalize [file join [info script] ...]]]
eq
[file dirname [file normalize [file join $::argv0 ...]]]
} {
return true
} else {
return false
}
}
# == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == ==
# Maintenance - This is the primary source for tm_version... functions

2
src/modules/punk/lib-buildversion.txt

@ -1,3 +1,3 @@
0.1.4
0.1.5
#First line must be a semantic version number
#all other lines are ignored.

165
src/modules/punk/netbox-999999.0a1.0.tm

@ -809,34 +809,46 @@ tcl::namespace::eval punk::netbox {
#get api handle(s) for a netbox server (with url and token) to pass to the punk::netbox api functions
lappend PUNKARGS [list {
@id -id ::punk::netbox::api_context_load
@cmd -name punk::netbox::api_context_load -help\
"Load API context information (url token)
from a .toml file in the data directory
or from a specified file.
To create an initial file, use api_context
to create one or more named configurations
specifying the url and authentication token.
Then use api_context_save to persist them."
@opts
-contextname -default * -help\
"Name of an API context or a pattern for
which contexts to load from the file."
@values
filepath -default "" -type file
}]
namespace eval argdoc {
lappend PUNKARGS [list {
@id -id ::punk::netbox::api_context_load
@cmd -name punk::netbox::api_context_load\
-summary\
"Load API token contexts from storage."\
-help\
"Load API context information (url token)
from a .toml file in the data directory
or from a specified file.
To create an initial file, use api_context
to create one or more named configurations
specifying the url and authentication token.
Then use api_context_save to persist them.
Returns the names of the loaded contexts."
@opts
-contextname -default * -help\
"Name of an API context or a pattern for
which contexts to load from the file."
-nowarnings -type none -help\
"Suppress warnings emitted to stderr.
Will not stop error if datafile is not found"
@values
filepath -default "" -type file
}]
}
proc api_context_load {args} {
set argd [punk::args::parse $args withid ::punk::netbox::api_context_load]
lassign [dict values $argd] leaders opts values received
set contextglob [dict get $opts -contextname]
set filepath [dict get $values filepath]
set nowarnings [dict exists $received -nowarnings]
if {$filepath eq ""} {
set filepath [_datafile]
}
if {![file exists $filepath]} {
error "No existing datafile at '$filepath'\nUse api_context_create to configure a context and save it with api_context_save"
error "No existing datafile at '$filepath'\nUse api_context_create/api_context_save to configure and save contexts"
}
package require tomlish
set tomldata [readFile $filepath]
@ -847,11 +859,13 @@ tcl::namespace::eval punk::netbox {
set loaded [list]
dict for {contextid contextinfo} $tomldict {
if {[string match $contextglob $contextid]} {
if {![dict exists $contextinfo url]} {
puts "api_context_load warning: Loaded context $contextid is missing 'url' key"
}
if {![dict exists $contextinfo token]} {
puts "api_context_load warning: Loaded context $contextid is missing 'token' key"
if {!$nowarnings} {
if {![dict exists $contextinfo url]} {
puts stderr "api_context_load warning: Loaded context $contextid is missing 'url' key"
}
if {![dict exists $contextinfo token]} {
puts stderr "api_context_load warning: Loaded context $contextid is missing 'token' key"
}
}
dict set contexts $contextid $contextinfo
lappend loaded $contextid
@ -860,6 +874,57 @@ tcl::namespace::eval punk::netbox {
return $loaded
}
namespace eval argdoc {
lappend PUNKARGS [list {
@id -id ::punk::netbox::init
@cmd -name punk::netbox::init\
-summary\
"Load all api token contexts."\
-help\
"This is a convenience function to call api_context_load
to load all available API token contexts with the default
data-file path being determined with the _datafile function."
@leaders
@opts
-quiet -type none -help\
"Suppress status messages emitted to stdout.
Will not suppress the error raised if no datafile is available"
-nowarnings -type none -help\
"Suppress warnings related to missing urls/tokens that are emitted
to stderr"
@values -min 0 -max 0
}]
}
proc init {args} {
set argd [punk::args::parse $args withid ::punk::netbox::init]
set received [dict get $argd received]
set be_quiet [dict exists $received -quiet]
set nowarnings [dict exists $received -nowarnings]
set filepath [_datafile]
if {![file exists $filepath]} {
error "No existing datafile at '$filepath'\nCall api_context_load with a path to a .toml file with context records\nor use api_context_create/api_context_save."
}
if {!$be_quiet} {
puts stdout "Loading API token contexts from [_datafile]"
}
if {$nowarnings} {
api_context_load -nowarnings
} else {
api_context_load
}
if {!$be_quiet} {
puts stdout "Table produced by api_contexts"
puts stdout [api_contexts]
}
variable contexts
if {!$be_quiet} {
puts stdout "The contextid value is used as the 1st argument of most punk::netbox api functions"
puts stdout "If a raw token is required it can be retrieved with: api_context_get <contextid> token"
puts stdout "[dict size $contexts] contexts loaded"
}
return [dict size $contexts]
}
lappend PUNKARGS [list {
@id -id ::punk::netbox::api_context_create
@cmd -name punk::netbox::api_context_create -help\
@ -925,6 +990,60 @@ tcl::namespace::eval punk::netbox {
dict set contexts $contextid $allprops
return $contextid
}
namespace eval argdoc {
lappend PUNKARGS [list {
@id -id ::punk::netbox::api_context_get
@cmd -name punk::netbox::api_context_get -help\
"Get api context fields for a single context.
A unique prefix of any loaded context may be
used."
@leaders -min 1 -max 1
apicontextid -help\
"The name of the stored api context to use.
Contextids can be created in-memory using
api_context_create, or loaded from a .toml
file using api_context_load."\
-choices {${[punk::netbox::api_context_names]}}
@values -min 0 -max -1
field -type string -multiple 1 -optional 1 -help\
"If no field arguments are supplied, all will
be retrieved.
Note that a non-existant field name will produce
an empty string element in the result list for
that position. This is indistinguishable from an
existent field with an empty string as the value.
As an alternative, the api_contexts function with
the -return dict argument can be used instead to
access multiple fields for multiple apicontextids.
"
}]
}
proc api_context_get {args} {
set argd [punk::args::parse $args withid ::punk::netbox::api_context_get]
lassign [dict values $argd] leaders opts values received
set contextid [dict get $leaders apicontextid]
if {[dict exists $received field]} {
set fields [dict get $values field] ;#-multiple true - so always a list
} else {
set fields [list]
}
variable contexts
set cdata [dict get $contexts $contextid]
set result [list]
if {![llength $fields]} {
set fields [dict keys $cdata]
}
foreach f $fields {
if {[dict exists $cdata $f]} {
lappend result [dict get $cdata $f value]
} else {
lappend result ""
}
}
return $result
}
lappend PUNKARGS [list {
@id -id ::punk::netbox::get_status

5012
src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/lib-0.1.5.tm

File diff suppressed because it is too large Load Diff

5012
src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/lib-0.1.5.tm

File diff suppressed because it is too large Load Diff

4
src/vendormodules/include_modules.config

@ -6,7 +6,6 @@ set local_modules [list\
c:/repo/jn/tclmodules/fauxlink/modules fauxlink\
c:/repo/jn/tclmodules/gridplus/modules gridplus\
c:/repo/jn/tclmodules/modpod/modules modpod\
c:/repo/jn/tclmodules/overtype/modules overtype\
c:/repo/jn/tclmodules/packageTest/modules packageTest\
c:/repo/jn/tclmodules/tablelist/modules tablelist\
c:/repo/jn/tclmodules/tablelist/modules tablelist_tile\
@ -26,6 +25,9 @@ set local_modules [list\
c:/repo/jn/tarjar/modules tarjar\
]
#moved overtype into punkshell project
# c:/repo/jn/tclmodules/overtype/modules overtype
set fossil_modules [dict create\
]

9470
src/vendormodules/tomlish-1.1.7.tm

File diff suppressed because it is too large Load Diff

121
src/vendormodules/overtype-1.7.2.tm → src/vfs/_vfscommon.vfs/modules/overtype-1.7.3.tm

@ -7,7 +7,7 @@
# (C) Julian Noble 2003-2023
#
# @@ Meta Begin
# Application overtype 1.7.2
# Application overtype 1.7.3
# Meta platform tcl
# Meta license BSD
# @@ Meta End
@ -17,7 +17,7 @@
# doctools header
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
#*** !doctools
#[manpage_begin overtype_module_overtype 0 1.7.2]
#[manpage_begin overtype_module_overtype 0 1.7.3]
#[copyright "2024"]
#[titledesc {overtype text layout - ansi aware}] [comment {-- Name section and table of contents description --}]
#[moddesc {overtype text layout}] [comment {-- Description at end of page heading --}]
@ -193,6 +193,78 @@ tcl::namespace::eval overtype {
#[para] Core API functions for overtype
#[list_begin definitions]
namespace eval argdoc {
variable PUNKARGS
#non-colour SGR codes
set I "\x1b\[3m" ;# [a+ italic]
set NI "\x1b\[23m" ;# [a+ noitalic]
set B "\x1b\[1m" ;# [a+ bold]
set N "\x1b\[22m" ;# [a+ normal]
set T "\x1b\[1\;4m" ;# [a+ bold underline]
set NT "\x1b\[22\;24m\x1b\[4:0m" ;# [a+ normal nounderline]
interp alias "" ::overtype::example "" ::punk::args::helpers::example
}
namespace eval argdoc {
variable PUNKARGS
lappend PUNKARGS [list {
@id -id ::overtype::renderspace
@cmd -name overtype::renderspace\
-summary\
{}\
-help\
{}
@opts
#because underblocks value is optional - restrict opts to flag pairs (no solos)
#We don't use punk::args::parse in the actual function to parse args - so keep it simpler.
-bias -default left -type string -choices {left right} -help ignored
-width -default \uFFEF -type integer
-height -default \uFFEF -type integer
-startcolumn -default 1 -type integer
-startrow -default 1 -type integer
-ellipsis -default 0 -type boolean
-ellipsistext -default ${$::overtype::default_ellipsis_horizontal} -type char
-ellipsiswhitespace -default 0 -type boolean
-expand_right -default 0 -type boolean
-appendlines -default 1 -type boolean
-transparent -default 0 -type {literal(0)|literal(1)|regexp} -help\
"0 to disable transparency processing
1 to enable space characters in the
overlay to be transparent, or a regex
to match the character(s) required to be
transparent in the overlay."
-exposed1 -default \uFFFD -type char -help\
{A character of single terminal column width to use
as replacement when first-half of an underlying char
is exposed due to overlay positioning/transparency
which obscures the second-half of the char. May be ANSI
coloured as this doesn't affect the display width.
Default is \uFFFD - the unicode replacement char.}
-exposed2 -default \uFFFD -type char -help\
{A character of single terminal column width to use
as replacement when second-half of an underlying char
is exposed due to overlay positioning/transparency
which obscures the first-half of the char. May be ANSI
coloured as this doesn't affect the display width.
Default is \uFFFD - the unicode replacement char.}
-experimental -default 0
-cp437 -default 0 -type boolean
-looplimit -default \uFFEF\ -type integer -help\
"internal failsafe - experimental"
-crm_mode -default 0 -type boolean
-reverse_mode -default 0 -type boolean
-insert_mode -default 1 -type boolean
-wrap -default 0 -type boolean
-info -default 0 -type boolean -help\
"When set to 1, return a dictionary (experimental)"
-console -default {stdin stdout stderr} -type list
@values -min 1 -max 2
underblock -type string -optional 1
overblock -type string -optional 0
}]
}
#tcl::string::range should generally be avoided for both undertext and overtext which contain ansi escapes and other cursor affecting chars such as \b and \r
@ -211,7 +283,7 @@ tcl::namespace::eval overtype {
# @c can/should we use something like this?: 'format "%-*s" $len $overtext
variable default_ellipsis_horizontal
if {[llength $args] < 2} {
if {[llength $args] < 1} {
error {usage: ?-width <int>? ?-startcolumn <int>? ?-transparent [0|1|<char>]? ?-expand_right [1|0]? ?-ellipsis [1|0]? ?-ellipsistext ...? undertext overtext}
}
set optargs [lrange $args 0 end-2]
@ -221,20 +293,26 @@ tcl::namespace::eval overtype {
#lassign [lrange $args end-1 end] underblock overblock
set argsflags [lrange $args 0 end-2]
} else {
set optargs [lrange $args 0 end-1]
if {[llength $optargs] %2 == 0} {
set overblock [lindex $args end]
set underblock ""
set argsflags [lrange $args 0 end-1]
} else {
error "renderspace expects opt-val pairs followed by: <underblock> <overblock> or just <overblock>"
}
#no solo flags - so we assume only an overblock was supplied
set overblock [lindex $args end]
set underblock ""
set argsflags [lrange $args 0 end-1]
#set optargs [lrange $args 0 end-1]
#if {[llength $optargs] %2 == 0} {
# set overblock [lindex $args end]
# set underblock ""
# set argsflags [lrange $args 0 end-1]
#} else {
# error "renderspace expects opt-val pairs followed by: <underblock> <overblock> or just <overblock>"
#}
}
set opts [tcl::dict::create\
-bias ignored\
-width \uFFEF\
-height \uFFEF\
-startcolumn 1\
-startrow 1\
-ellipsis 0\
-ellipsistext $default_ellipsis_horizontal\
-ellipsiswhitespace 0\
@ -266,7 +344,7 @@ tcl::namespace::eval overtype {
#-ellipsis args not used if -wrap is true
foreach {k v} $argsflags {
switch -- $k {
-looplimit - -width - -height - -startcolumn - -bias - -ellipsis - -ellipsistext - -ellipsiswhitespace
-looplimit - -width - -height - -startcolumn - -startrow - -bias - -ellipsis - -ellipsistext - -ellipsiswhitespace
- -transparent - -exposed1 - -exposed2 - -experimental
- -expand_right - -appendlines
- -reverse_mode - -crm_mode - -insert_mode
@ -292,6 +370,7 @@ tcl::namespace::eval overtype {
set opt_width [tcl::dict::get $opts -width]
set opt_height [tcl::dict::get $opts -height]
set opt_startcolumn [tcl::dict::get $opts -startcolumn]
set opt_startrow [tcl::dict::get $opts -startrow]
set opt_appendlines [tcl::dict::get $opts -appendlines]
set opt_transparent [tcl::dict::get $opts -transparent]
set opt_ellipsistext [tcl::dict::get $opts -ellipsistext]
@ -333,6 +412,10 @@ tcl::namespace::eval overtype {
set underblock [tcl::string::map {\r\n \n} $underblock]
set overblock [tcl::string::map {\r\n \n} $overblock]
if {$opt_startrow > 1} {
set down [expr {$opt_startrow -1}]
set overblock [punk::ansi::move_down $down]$overblock
}
#set underlines [split $underblock \n]
@ -1773,20 +1856,10 @@ tcl::namespace::eval overtype {
variable optimise_ptruns 10 ;# can be set to zero to disable the ptruns branches
namespace eval argdoc {
variable PUNKARGS
set I "\x1b\[3m" ;# [a+ italic]
set NI "\x1b\[23m" ;# [a+ noitalic]
set B "\x1b\[1m" ;# [a+ bold]
set N "\x1b\[22m" ;# [a+ normal]
set T "\x1b\[1\;4m" ;# [a+ bold underline]
set NT "\x1b\[22\;24m\x1b\[4:0m" ;# [a+ normal nounderline]
interp alias "" ::overtype::example "" ::punk::args::helpers::example
}
namespace eval argdoc {
variable PUNKARGS
lappend PUNKARGS [list {
@id -id ::overtype::renderline
@cmd -name overtype::renderline\
@ -4884,7 +4957,7 @@ namespace eval ::punk::args::register {
## Ready
package provide overtype [tcl::namespace::eval overtype {
variable version
set version 1.7.2
set version 1.7.3
}]
return

3
src/vfs/_vfscommon.vfs/modules/punk/args-0.2.1.tm

@ -6345,7 +6345,8 @@ tcl::namespace::eval punk::args {
}
}
indexexpression {
if {[catch {lindex {} $e_check}]} {
#tcl 9.1+? tip 615 'string is index'
if {$echeck eq "" || [catch {lindex {} $e_check}]} {
set msg "$argclass $argname for %caller% requires type indexexpression. An index as used in Tcl list commands. Received: '$e_check'"
#return -options [list -code error -errorcode [list PUNKARGS VALIDATION [list typemismatch $type] -badarg $argname -argspecs $argspecs]] $msg
lset clause_results $c_idx $a_idx [list errorcode [list PUNKARGS VALIDATION [list typemismatch $type] -badarg $argname -argspecs $argspecs] msg $msg]

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

@ -6020,6 +6020,13 @@ tcl::namespace::eval punk::args::moduledoc::tclcore {
@values -min 3 -max -1
listVar -type string -help\
"Existing list variable name"
#note if tip 615 implemented for 9.1 'first' and 'last' need to accept empty string too
#same for lrange, lreplace, string range, string replace
#if {[package vsatisfies [package provide Tcl] 9.1-]} {
# first -type {indexexpression|literal()}
#} else {
# first -type indexexpression
#}
first -type indexexpression
last -type indexexpression
value -type any -optional 1 -multiple 1
@ -6086,10 +6093,21 @@ tcl::namespace::eval punk::args::moduledoc::tclcore {
If additional index arguments are supplied, then each argument is used in turn
to select an element from the previous indexing operation, allowing the script
to select elements from sublists."
@form -form separate
@values -min 1 -max -1
list -type list -help\
"tcl list as a value"
index -type indexexpression -multiple 1 -optional 1
@form -form combined
@values -min 2 -max 2
list -type list -help\
"tcl list as a value"
#list of indexexpression
indexlist -type list -optional 0 -help\
"list of indexexpressions"
} "@doc -name Manpage: -url [manpage_tcl lindex]"\
{
@examples -help {

446
src/vfs/_vfscommon.vfs/modules/punk/layout-0.1.0.tm

@ -0,0 +1,446 @@
# -*- tcl -*-
# Maintenance Instruction: leave the 999999.xxx.x as is and use punkshell 'dev make' or bin/punkmake to update from <pkg>-buildversion.txt
# module template: shellspy/src/decktemplates/vendor/punk/modules/template_module-0.0.4.tm
#
# Please consider using a BSD or MIT style license for greatest compatibility with the Tcl ecosystem.
# Code using preferred Tcl licenses can be eligible for inclusion in Tcllib, Tklib and the punk package repository.
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
# (C) 2025
#
# @@ Meta Begin
# Application punk::layout 0.1.0
# Meta platform tcl
# Meta license MIT
# @@ Meta End
#EXPERIMENTAL
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
## Requirements
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
package require Tcl 8.6-
package require punk::args
#experimental layout library based on Nic Barker's Clay
# CLAY(CLAY_ID("parent"), { .layout = { .padding = CLAY_PADDING_ALL(8) } }) {
# // Child element 1
# CLAY_TEXT(CLAY_STRING("Hello World"), CLAY_TEXT_CONFIG({ .fontSize = 16 }));
# // Child element 2 with red background
# CLAY(CLAY_ID("child"), { .backgroundColor = COLOR_RED }) {
# // etc
# }
# }
#Tcl translation?
#CLAY ?-opt <val>..? ?childblock?
#eg
#CLAY -id <string> -layout <dict> -rectangle <dict> { childblock }
#where childblock is curly braced code block
# clay -id "parent" -layout [dict create .padding [padding_all 8]] {
# clay_text "Hello World" [clay_textconfig {.fontsize 16}]
# clay -id "child" -config {.backgroundColor red} {
# # etc
# }
# }
#for padding on a terminal - we are limited by cell_size - which is not square. (and may vary on terminals??)
# e.g punk::console::cell_size returns cell wxh
# -> 10x20
# (either queried from terminal - or defaults to 10x20 if can't be queried)
#so the minimum 'even' padding we can have is 2 space for horizontal, 1 line vertical
#we can pad a minimum of 1 space horizontall (10 units) and a minimum of 1 line vertically (20 units)
# CLAY_PADDING {<l> <r> <t> <b>}
#how then should we handle .padding {16 16 8 8} - quantize by roundup to h 10 and v 20?
# -> {20 20 20 20} ?
# or round to nearest vertical and horizontal quanta?
# -> {20 20 0 0}
#either way - {16 16 16 16} goes to {20 20 20 20} - which is *close* to equal v h padding
# - but not perfect visually because fonts within a cell have baseline, topline etc internal padding too?
#building a ui ?
#clay_begin_layout
# // build UI here
#set rendercommands [clay_end_layout]
#some_render_command $rendercommands
#eg2 (from introducing clay video https://www.youtube.com/watch?v=DYWTw19_8r4&t=2s)
#something like the following?
# (stopped at around the scroll point - need to work out console mouse features. punk::console::mouse_enable ...)
#extracted out common layout 'sizing' for grow in both directions
#set layoutExpand {
# width CLAY_SIZING_GROW
# heigth CLAY_SIZING GROW
# }
#extracted out common background panel
#set contentBackgroundConfig {
# colour Term-grey
# frametype arc
# }
#proc RenderHeaderButton {} {} ;#??
#set documents [dict create\
# Squirrels "The secret life of Squirrels"\
# "Lorem Ipsum" "Orem ipsum dolor sit ..\netc blah"\
# "Vacuum instructions" "Chapter 3: Getting Started"\
# "Article 4" "Article 4"\
# "Article 5" "Article 5"\
# ]
#set selectedDocumentIndex 0
#clay_begin_layout
#clay -id "OuterContainer"\
# -item [clay_rectangle {colour web-red}]
# -layout [clay_layout [dict create\
# layoutDirection CLAY_TOP_TO_BOTTOM\
# sizing $layoutExpand\
# padding {16 16}\
# childGap 16\
# ]]\
# {
# # Child elements
# clay -id "HeaderBar"\
# -item [clay_rectangle $contentBackgroundConfig]\
# -layout [clay_layout {
# sizing {
# height 60
# width CLAY_SIZING_GROW
# }
# padding {8 8}
# childGap 8
# childAlignment {
# y CLAY_ALIGN_Y_CENTER
# }
# }]\
# {
# # Header buttons go here
# RenderheaderButton [clay_string "File"]
# RenderheaderButton [clay_string "Edit"]
# #push last 3 buttons to rhs by using a layout in between to take up the middle space
# CLAY -layout {sizing {width CLAY_SIZING_GROW}} {}
# RenderheaderButton [clay_string "Upload"]
# RenderheaderButton [clay_string "Media"]
# RenderheaderButton [clay_string "Support"]
# }
# clay -id "LowerContent"\
# -layout [dict create sizing $layoutExpand childGap 16]\
# {
# clay -id "Sidebar"\
# -item [clay_rectangle $contentBackgroundConfig]\
# -layout {
# layoutDirection CLAY_TOP_TO_BOTTOM
# padding {8 8}
# childgap {20}
# sizing {
# width = 60
# height = CLAY_SIZING_GROW
# }\
# }\
# {
# #render dynamic data
# dict for {title data} $documents {
# clay -layout {padding {8 8}\
# {
# #fontId, fontSize not really practical on terminal
# clay_text $title [clay_text_config {
# textColor cyan
# }]
# }
# }
# }
# clay -id "MainContent"\
# -item [clay_rectangle $contentBackgroundConfig]\
# -scroll {vertical true}\
# -layout [dict create\
# layoutDirection = CLAY_TOP_TO_BOTTOM\
# childGap 20\
# padding {16 16 20 20}\
# sizing $layoutExpand\
# ]\
# {
# set selectedTitle [lindex [dict keys $documents] $selectedDocumentIndex]
# clay_text $selectedTitle [clay_text_config {
# textcolour {web-white bold}
# }]
# clay_text [dict get $documents $selectedTitle] [clay_text_config {
# textcolour {web-white}
# }]
# }
# }
# }
#set rendercommands [clay_end_layout]
#CLAY_SIZING_GROW
#CLAY_SIZING_FIT ;#default
tcl::namespace::eval punk::layout {
variable PUNKARGS
namespace eval argdoc {
variable PUNKARGS
namespace eval argdoc {
#non-colour SGR codes
set I "\x1b\[3m" ;# [a+ italic]
set NI "\x1b\[23m" ;# [a+ noitalic]
set B "\x1b\[1m" ;# [a+ bold]
set N "\x1b\[22m" ;# [a+ normal]
set T "\x1b\[1\;4m" ;# [a+ bold underline]
set NT "\x1b\[22\;24m\x1b\[4:0m" ;# [a+ normal nounderline]
}
}
#elementDeclaration
#data structure (CLAY UIElement struct equivalent)
#set eg_element [dict create\
# position {1 1}\
# size {80 24}\
# children [list]\
#]
#elementConfig
#set eg_item [dict create\
# type rectangle\
# color {red bold}\
# borderColor {yellow}
# frametype {}\
#]
# etc
proc DrawRectangle {element} {
set position [dict get $element position] ;#x y
set size [dict get $element size] ;#width height
lassign $size w h
set bg [dict get $element color]
set borderColor [dict get $element borderColor]
set frametype [dict get $element frametype]
if {$frametype eq ""} {
#much faster than textblock::frame
set content [textblock::block $w $h "[a+ $bg] [a]"]
} else {
#slow - and frame background colours will always overlap the borders so we can never get a nicely filled arc frame for example
#The best bordered
set content [textblock::frame -type $frametype -ansibase [a+ $bg] -ansiborder [a+ $borderColor] -width $w -height $h " "]
}
}
proc RenderElement {element} {
}
#TODO
#The clay_begin_layout - clay_end_layout structure suggests the main API may be better represented as an oo object maintaining state
#we may need to have multiple instances running concurrently
#Clay conceptually runs in 'immediate' mode - ie recalculating each full layout each time we need to render
variable rendercommands
proc clay_begin_layout {} {
variable rendercommands
set rendercommands [dict create]
#...?
}
proc clay_end_layout {} {
variable rendercommands
#...?
return $rendercommands
}
namespace eval argdoc {
variable PUNKARGS
lappend PUNKARGS [list {
@id -id ::punk::layout::clay
@cmd -name punk::layout::clay
@opts
-id -type string
-item -type dict
-layout -type dict
-backgroundColor -type list -help\
"ANSI colour codes as documented in punk::ansi::a?"
@values -min 0 -max 1
childscript -type script
}]
}
#For initial proof of concept - we will use punk::args for *parsing* as well as documenting
#For final version - the extra overhead of punk::args::parse may not be suitable for large numbers of
#calls in 'immediate' mode - so punk::args::parse should be used on 'unhappy' paths only,
#with a fast switch statement used for actual option parsing.
#As performance is likely to be an issue - we should also avoid allowing 'prefixes' for arguments
proc clay {args} {
set argd [punk::args::parse $args withid ::punk::layout::clay] ;#temporary during concept development - todo: change to manual parsing for performance.
}
#
}
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
# Secondary API namespace
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
tcl::namespace::eval punk::layout::lib {
tcl::namespace::export {[a-z]*} ;# Convention: export all lowercase
tcl::namespace::path [tcl::namespace::parent]
#STEPS
#Fit Sizing -> Grow Sizing -> Positions -> Draw
#tree traversal
#(reverse breadth first) (breadth first)
# via OpenElement/CloseElement? (expand our grow containers
# into any available space)
proc OpenElement {element} {
#pseudo...
#set layoutDirection $layoutconfig.layoutDirection
#if {$layoutDirection eq "CLAY_LEFT_TO_RIGHT"} {
#} else {
# #CLAY_TOP_TO_BOTTOM
#}
}
proc CloseElement {element} {
#element.parent.width += element.width
#element.parent.height += element.height
}
proc SizeContainersAlongAxis {is_x_axis totalSizeToDistribute} {
}
proc CalculateFinalLayout {} {
}
}
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
#tcl::namespace::eval punk::layout::system {
#}
# == === === === === === === === === === === === === === ===
# Sample 'about' function with punk::args documentation
# == === === === === === === === === === === === === === ===
tcl::namespace::eval punk::layout {
tcl::namespace::export {[a-z]*} ;# Convention: export all lowercase
variable PUNKARGS
variable PUNKARGS_aliases
lappend PUNKARGS [list {
@id -id "(package)punk::layout"
@package -name "punk::layout" -help\
"EXPERIMENTAL - not done"
}]
namespace eval argdoc {
#namespace for custom argument documentation
proc package_name {} {
return punk::layout
}
proc about_topics {} {
#info commands results are returned in an arbitrary order (like array keys)
set topic_funs [info commands [namespace current]::get_topic_*]
set about_topics [list]
foreach f $topic_funs {
set tail [namespace tail $f]
lappend about_topics [string range $tail [string length get_topic_] end]
}
#Adjust this function or 'default_topics' if a different order is required
return [lsort $about_topics]
}
proc default_topics {} {return [list Description *]}
# -------------------------------------------------------------
# get_topic_ functions add more to auto-include in about topics
# -------------------------------------------------------------
proc get_topic_Description {} {
punk::args::lib::tstr [string trim {
package punk::layout
An experiment in using CLAY UI style layout on the terminal
INCOMPLETE...
status: notes and started framework only - nothing usable.
} \n]
}
proc get_topic_License {} {
return "MIT"
}
proc get_topic_Version {} {
return "$::punk::layout::version"
}
proc get_topic_Contributors {} {
set authors {{Julian Noble <julian@precisium.com.au}}
set contributors ""
foreach a $authors {
append contributors $a \n
}
if {[string index $contributors end] eq "\n"} {
set contributors [string range $contributors 0 end-1]
}
return $contributors
}
proc get_topic_concepts {} {
punk::args::lib::tstr -return string {
see Nic Barker's youtube video: How Clay's UI Layout Algorithm Works
https://www.youtube.com/watch?v=by9lQvpvMIc
}
}
# -------------------------------------------------------------
}
# we re-use the argument definition from punk::args::standard_about and override some items
set overrides [dict create]
dict set overrides @id -id "::punk::layout::about"
dict set overrides @cmd -name "punk::layout::about"
dict set overrides @cmd -help [string trim [punk::args::lib::tstr {
About punk::layout
}] \n]
dict set overrides topic -choices [list {*}[punk::layout::argdoc::about_topics] *]
dict set overrides topic -choicerestricted 1
dict set overrides topic -default [punk::layout::argdoc::default_topics] ;#if -default is present 'topic' will always appear in parsed 'values' dict
set newdef [punk::args::resolved_def -antiglobs -package_about_namespace -override $overrides ::punk::args::package::standard_about *]
lappend PUNKARGS [list $newdef]
proc about {args} {
package require punk::args
#standard_about accepts additional choices for topic - but we need to normalize any abbreviations to full topic name before passing on
set argd [punk::args::parse $args withid ::punk::layout::about]
lassign [dict values $argd] _leaders opts values _received
punk::args::package::standard_about -package_about_namespace ::punk::layout::argdoc {*}$opts {*}[dict get $values topic]
}
}
# end of sample 'about' function
# == === === === === === === === === === === === === === ===
# -----------------------------------------------------------------------------
# register namespace(s) to have PUNKARGS,PUNKARGS_aliases variables checked
# -----------------------------------------------------------------------------
# variable PUNKARGS
# variable PUNKARGS_aliases
namespace eval ::punk::args::register {
#use fully qualified so 8.6 doesn't find existing var in global namespace
lappend ::punk::args::register::NAMESPACES ::punk::layout
}
# -----------------------------------------------------------------------------
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
## Ready
package provide punk::layout [tcl::namespace::eval punk::layout {
variable pkg punk::layout
variable version
set version 0.1.0
}]
return

27
src/vfs/_vfscommon.vfs/modules/punk/lib-0.1.4.tm

@ -539,6 +539,33 @@ namespace eval punk::lib {
set NT "\x1b\[22\;24m\x1b\[4:0m" ;# [a+ normal nounderline]
}
namespace eval argdoc {
variable PUNKARGS
lappend PUNKARGS [list {
@id -id ::punk::lib::is_main_script
@cmd -name punk::lib::is_main_script\
-summary\
"Test if current script is primary script being executed."\
-help\
""
@values -min 0 -max 0
}]
}
proc is_main_script {} {
#see https://wiki.tcl-lang.org/page/main+script
if {[info script] ne "" && [info exists ::argv0]
&&
[file dirname [file normalize [file join [info script] ...]]]
eq
[file dirname [file normalize [file join $::argv0 ...]]]
} {
return true
} else {
return false
}
}
# == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == ==
# Maintenance - This is the primary source for tm_version... functions

5012
src/vfs/_vfscommon.vfs/modules/punk/lib-0.1.5.tm

File diff suppressed because it is too large Load Diff

165
src/vfs/_vfscommon.vfs/modules/punk/netbox-0.1.0.tm

@ -809,34 +809,46 @@ tcl::namespace::eval punk::netbox {
#get api handle(s) for a netbox server (with url and token) to pass to the punk::netbox api functions
lappend PUNKARGS [list {
@id -id ::punk::netbox::api_context_load
@cmd -name punk::netbox::api_context_load -help\
"Load API context information (url token)
from a .toml file in the data directory
or from a specified file.
To create an initial file, use api_context
to create one or more named configurations
specifying the url and authentication token.
Then use api_context_save to persist them."
@opts
-contextname -default * -help\
"Name of an API context or a pattern for
which contexts to load from the file."
@values
filepath -default "" -type file
}]
namespace eval argdoc {
lappend PUNKARGS [list {
@id -id ::punk::netbox::api_context_load
@cmd -name punk::netbox::api_context_load\
-summary\
"Load API token contexts from storage."\
-help\
"Load API context information (url token)
from a .toml file in the data directory
or from a specified file.
To create an initial file, use api_context
to create one or more named configurations
specifying the url and authentication token.
Then use api_context_save to persist them.
Returns the names of the loaded contexts."
@opts
-contextname -default * -help\
"Name of an API context or a pattern for
which contexts to load from the file."
-nowarnings -type none -help\
"Suppress warnings emitted to stderr.
Will not stop error if datafile is not found"
@values
filepath -default "" -type file
}]
}
proc api_context_load {args} {
set argd [punk::args::parse $args withid ::punk::netbox::api_context_load]
lassign [dict values $argd] leaders opts values received
set contextglob [dict get $opts -contextname]
set filepath [dict get $values filepath]
set nowarnings [dict exists $received -nowarnings]
if {$filepath eq ""} {
set filepath [_datafile]
}
if {![file exists $filepath]} {
error "No existing datafile at '$filepath'\nUse api_context_create to configure a context and save it with api_context_save"
error "No existing datafile at '$filepath'\nUse api_context_create/api_context_save to configure and save contexts"
}
package require tomlish
set tomldata [readFile $filepath]
@ -847,11 +859,13 @@ tcl::namespace::eval punk::netbox {
set loaded [list]
dict for {contextid contextinfo} $tomldict {
if {[string match $contextglob $contextid]} {
if {![dict exists $contextinfo url]} {
puts "api_context_load warning: Loaded context $contextid is missing 'url' key"
}
if {![dict exists $contextinfo token]} {
puts "api_context_load warning: Loaded context $contextid is missing 'token' key"
if {!$nowarnings} {
if {![dict exists $contextinfo url]} {
puts stderr "api_context_load warning: Loaded context $contextid is missing 'url' key"
}
if {![dict exists $contextinfo token]} {
puts stderr "api_context_load warning: Loaded context $contextid is missing 'token' key"
}
}
dict set contexts $contextid $contextinfo
lappend loaded $contextid
@ -860,6 +874,57 @@ tcl::namespace::eval punk::netbox {
return $loaded
}
namespace eval argdoc {
lappend PUNKARGS [list {
@id -id ::punk::netbox::init
@cmd -name punk::netbox::init\
-summary\
"Load all api token contexts."\
-help\
"This is a convenience function to call api_context_load
to load all available API token contexts with the default
data-file path being determined with the _datafile function."
@leaders
@opts
-quiet -type none -help\
"Suppress status messages emitted to stdout.
Will not suppress the error raised if no datafile is available"
-nowarnings -type none -help\
"Suppress warnings related to missing urls/tokens that are emitted
to stderr"
@values -min 0 -max 0
}]
}
proc init {args} {
set argd [punk::args::parse $args withid ::punk::netbox::init]
set received [dict get $argd received]
set be_quiet [dict exists $received -quiet]
set nowarnings [dict exists $received -nowarnings]
set filepath [_datafile]
if {![file exists $filepath]} {
error "No existing datafile at '$filepath'\nCall api_context_load with a path to a .toml file with context records\nor use api_context_create/api_context_save."
}
if {!$be_quiet} {
puts stdout "Loading API token contexts from [_datafile]"
}
if {$nowarnings} {
api_context_load -nowarnings
} else {
api_context_load
}
if {!$be_quiet} {
puts stdout "Table produced by api_contexts"
puts stdout [api_contexts]
}
variable contexts
if {!$be_quiet} {
puts stdout "The contextid value is used as the 1st argument of most punk::netbox api functions"
puts stdout "If a raw token is required it can be retrieved with: api_context_get <contextid> token"
puts stdout "[dict size $contexts] contexts loaded"
}
return [dict size $contexts]
}
lappend PUNKARGS [list {
@id -id ::punk::netbox::api_context_create
@cmd -name punk::netbox::api_context_create -help\
@ -925,6 +990,60 @@ tcl::namespace::eval punk::netbox {
dict set contexts $contextid $allprops
return $contextid
}
namespace eval argdoc {
lappend PUNKARGS [list {
@id -id ::punk::netbox::api_context_get
@cmd -name punk::netbox::api_context_get -help\
"Get api context fields for a single context.
A unique prefix of any loaded context may be
used."
@leaders -min 1 -max 1
apicontextid -help\
"The name of the stored api context to use.
Contextids can be created in-memory using
api_context_create, or loaded from a .toml
file using api_context_load."\
-choices {${[punk::netbox::api_context_names]}}
@values -min 0 -max -1
field -type string -multiple 1 -optional 1 -help\
"If no field arguments are supplied, all will
be retrieved.
Note that a non-existant field name will produce
an empty string element in the result list for
that position. This is indistinguishable from an
existent field with an empty string as the value.
As an alternative, the api_contexts function with
the -return dict argument can be used instead to
access multiple fields for multiple apicontextids.
"
}]
}
proc api_context_get {args} {
set argd [punk::args::parse $args withid ::punk::netbox::api_context_get]
lassign [dict values $argd] leaders opts values received
set contextid [dict get $leaders apicontextid]
if {[dict exists $received field]} {
set fields [dict get $values field] ;#-multiple true - so always a list
} else {
set fields [list]
}
variable contexts
set cdata [dict get $contexts $contextid]
set result [list]
if {![llength $fields]} {
set fields [dict keys $cdata]
}
foreach f $fields {
if {[dict exists $cdata $f]} {
lappend result [dict get $cdata $f value]
} else {
lappend result ""
}
}
return $result
}
lappend PUNKARGS [list {
@id -id ::punk::netbox::get_status

9470
src/vfs/_vfscommon.vfs/modules/tomlish-1.1.7.tm

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save