diff --git a/src/bootsupport/modules/overtype-1.7.4.tm b/src/bootsupport/modules/overtype-1.7.4.tm index 1b71be1f..403e971c 100644 --- a/src/bootsupport/modules/overtype-1.7.4.tm +++ b/src/bootsupport/modules/overtype-1.7.4.tm @@ -3280,6 +3280,7 @@ tcl::namespace::eval overtype { set next_stop [lindex $tstops $prev_stop_idx+1] ;#if our tab_column is exactly on a stop, we still want to move to the next stop. set this_tab_width [expr {$next_stop - $tab_column}] ;#diff between two adjacent columns is one. + #insert the tab and the correct number of null columns for the tab expansion. set graphemes [list \t {*}[lrepeat [expr {$this_tab_width -1}] "\u0000"]] priv::render_insertgraphemes $idx $graphemes [lindex $overstacks $idx_over] [lindex $overstacks_gx $idx_over] incr idx $this_tab_width @@ -3594,8 +3595,6 @@ tcl::namespace::eval overtype { #This reflows for each grapheme inserted - but for now this is simpler than trying to handle multiple graphemes at once. priv::render_insertgraphemes $idx [list $ch] [lindex $overstacks $idx_over] [lindex $overstacks_gx $idx_over] incr idx - #don't incr cursor_column - review. - } else { priv::render_addchar $idx $ch [lindex $overstacks $idx_over] [lindex $overstacks_gx $idx_over] $insert_mode incr idx @@ -5598,9 +5597,9 @@ tcl::namespace::eval overtype { #} #-info values 2,3,4 for view modes - if {($opt_returnextra | 3) == $opt_returnextra} { + if {$opt_returnextra & 3} { set viewop VIEWCODES - } elseif {($opt_returnextra | 4) == $opt_returnextra} { + } elseif {$opt_returnextra & 4} { set viewop VIEWSTYLE } @@ -5622,7 +5621,7 @@ tcl::namespace::eval overtype { } #-info values 9,10,11,12 - if {($opt_returnextra | 8) == $opt_returnextra} { + if {$opt_returnextra & 8} { return [pdict -channel none result] } else { return $result diff --git a/src/bootsupport/modules/punk/ansi-0.1.1.tm b/src/bootsupport/modules/punk/ansi-0.1.1.tm index 7e7bc823..f9997649 100644 --- a/src/bootsupport/modules/punk/ansi-0.1.1.tm +++ b/src/bootsupport/modules/punk/ansi-0.1.1.tm @@ -5170,6 +5170,13 @@ Brightblack 100 Brightred 101 Brightgreen 102 Brightyellow 103 Brightblu set c [format %c [expr {$col + 31}]] return \x1bY${r}${c} } + + + #standard vt52 doesn't support color (monochrome displays only) + #Atari and some vt52 emulators may support limited colors - review + #todo - vt52color background vs foreground + #\x1bb foreground. + #\x1bc background. proc vt52color {int} { if {[string is integer -strict $int]} { if {$int < 0 || $int > 15} { @@ -5177,6 +5184,7 @@ Brightblack 100 Brightred 101 Brightgreen 102 Brightyellow 103 Brightblu } } set char [format %c [expr {$int + 31}]] + #foreground and background are the same char - but vt52 has separate modes for fg/bg - so we could just return the char and let caller decide which mode to be in return \x1bb${char} } @@ -6800,12 +6808,14 @@ be as if this was off - ie lone CR. return [dict create textcells $textcells scopes $scopes cellblocks $cellblocks blockwidths $blockwidths] } proc expand_elastic_tabs {textblock {with {" " " "}}} { + lassign $with tabchar spacechar + #temp set tstops [lrange [punk::lib::range 1 200 8] 1 end] + #REVIEW + set computed [_compute_plastic_tabstops $textblock 4] - lassign $with tabchar spacechar - set computed [_compute_plastic_tabstops $textblock 4] set numrows [llength [dict get $computed textcells]] #set numcols [expr {[dict get $computed scopes 0 columncount] - 1}] set cellblocks [dict get $computed cellblocks] diff --git a/src/bootsupport/modules/punk/args-0.2.1.tm b/src/bootsupport/modules/punk/args-0.2.1.tm index 0056e9d0..1ff7fd37 100644 --- a/src/bootsupport/modules/punk/args-0.2.1.tm +++ b/src/bootsupport/modules/punk/args-0.2.1.tm @@ -10459,7 +10459,12 @@ tcl::namespace::eval punk::args { set ts [Dict_getdef $arginfo -typesynopsis ""] set n [expr {[llength $typelist]-1}] - set name_tail [lrange $argname end-$n end];#if there are enough tail words in the argname to match -types + if {![catch {llength $argname}]} { + set name_tail [lrange $argname end-$n end];#if there are enough tail words in the argname to match -types + } else { + #argname is not a valid Tcl list - so we can't take tail words from it for display hints + set name_tail [list $argname] + } set clause "" if {$ts ne ""} { set tp_displaylist $ts @@ -10468,7 +10473,7 @@ tcl::namespace::eval punk::args { } foreach typespec $typelist td $tp_displaylist elementname $name_tail { - #elementname will commonly be empty + #elementname will commonly be empty after first iteration if {[string match {\?*\?} $typespec]} { set tp [string range $typespec 1 end-1] set member_optional 1 diff --git a/src/bootsupport/modules/punk/console-0.1.1.tm b/src/bootsupport/modules/punk/console-0.1.1.tm index 9c378b1a..5271bbfb 100644 --- a/src/bootsupport/modules/punk/console-0.1.1.tm +++ b/src/bootsupport/modules/punk/console-0.1.1.tm @@ -784,50 +784,34 @@ namespace eval punk::console { tailcall ::punk::ansi::a? {*}$args } } - #proc a? {args} { - # #stdout - # variable ansi_wanted - # if {$ansi_wanted <= 0} { - # puts -nonewline [punk::ansi::ansistripraw [::punk::ansi::a?]] - # } else { - # tailcall ansi::a? {*}$args - # } - #} #REVIEW! this needs reworking. #It needs to be clarified as to what ansi off is supposed to do. #Turning ansi off only stops new ansi being generated - but what about codes stored in configurations of existing elements such as tables/frames? #It will stop underlines/bold/reverse as well as SGR colours + #colour off is more specific - it only stops SGR colour codes from being generated - but underlines/bold/reverse will still be generated. #what about ansi movement codes etc? #we already have colour on|off which disables SGR codes in a+ etc as well as stderr/stdout channel transforms proc ansi {{onoff {}}} { variable ansi_wanted if {[string length $onoff]} { - set onoff [string tolower $onoff] - switch -- $onoff { - 1 - - on - - true - - yes { - set ansi_wanted 1 - } - 0 - - off - - false - - no { - set ansi_wanted 0 - punk::ansi::sgr_cache -action clear - } - default { - set ansi_wanted 2 - } - default { - error "punk::console::ansi expected 0|1|on|off|true|false|yes|no|default" - } + if {$onoff eq "default"} { + set ansi_wanted 2 + catch {punk::repl::reset_prompt} + return + } + if {![string is boolean -strict $onoff]} { + error "punk::console::ansi expected a boolean e.g 0|1|on|off|true|false|yes|no" + } + if {$onoff} { + set ansi_wanted 1 + } else { + set ansi_wanted 0 + punk::ansi::sgr_cache -action clear } + catch {punk::repl::reset_prompt} } - catch {punk::repl::reset_prompt} - puts stderr "::punk::console::ansi - use 'colour' command to turn SGR codes on/off" + puts stderr "::punk::console::ansi - use 'colour' command to turn SGR codes on/off (except bold/underline/reverse which are controlled by 'ansi' command)" return [expr {$ansi_wanted}] } @@ -863,8 +847,8 @@ namespace eval punk::console { #test - find a better place to set terminal type variable is_vt52 0 proc vt52 {{onoff {}}} { - #todo - return to colour state beforehand?. support 0-15 vt52 colours? - #we shouldn't have to trun off colour to enter vt52 - we should make punk::console emit correct codes + #todo - return to colour state beforehand?. support 0-15 vt52 colours? (ATARI and some emulators - not original vt52) + #we shouldn't have to turn off colour to enter vt52 - we should make punk::console emit correct codes variable is_vt52 if {$onoff eq ""} { return $is_vt52 @@ -2873,7 +2857,7 @@ namespace eval punk::console { return 0 } set existing_mode [twapi::GetConsoleMode $h_out] - if {[expr {$existing_mode & 4}]} { + if {$existing_mode & 4} { #virtual terminal processing happens to be enabled - so it's supported return 1 } diff --git a/src/bootsupport/modules/punk/ns-0.1.0.tm b/src/bootsupport/modules/punk/ns-0.1.0.tm index 6fcb3aa3..dc8c765c 100644 --- a/src/bootsupport/modules/punk/ns-0.1.0.tm +++ b/src/bootsupport/modules/punk/ns-0.1.0.tm @@ -2671,16 +2671,20 @@ y" {return quirkykeyscript} foreach {tgt_cmd ns nscmd} $resolved_targets { puts "tracing target: $tgt_cmd whilst running: $origin $arglist" - ::tcl::namespace::eval $ns [list ::trace add execution $nscmd enter [list ::punk::ns::_cmdtrace_enter ::punk::ns::linedict $tgt_cmd]] - ::tcl::namespace::eval $ns [list ::trace add execution $nscmd enterstep [list ::punk::ns::_cmdtrace_enterstep ::punk::ns::linedict $tgt_cmd]] - ::tcl::namespace::eval $ns [list ::trace add execution $nscmd leave [list ::punk::ns::_cmdtrace_leave ::punk::ns::linedict $tgt_cmd]] + #::tcl::namespace::eval $ns [list ::trace add execution $nscmd enter [list ::punk::ns::_cmdtrace_enter ::punk::ns::linedict $tgt_cmd]] + #::tcl::namespace::eval $ns [list ::trace add execution $nscmd enterstep [list ::punk::ns::_cmdtrace_enterstep ::punk::ns::linedict $tgt_cmd]] + #::tcl::namespace::eval $ns [list ::trace add execution $nscmd leave [list ::punk::ns::_cmdtrace_leave ::punk::ns::linedict $tgt_cmd]] + nseval $ns [list ::trace add execution $nscmd enter [list ::punk::ns::_cmdtrace_enter ::punk::ns::linedict $tgt_cmd]] + nseval $ns [list ::trace add execution $nscmd enterstep [list ::punk::ns::_cmdtrace_enterstep ::punk::ns::linedict $tgt_cmd]] + nseval $ns [list ::trace add execution $nscmd leave [list ::punk::ns::_cmdtrace_leave ::punk::ns::linedict $tgt_cmd]] } try { #uplevel 1 [list $origin {*}$arglist] set _cmdtrace_disabled false - ::tcl::namespace::eval $origin_ns [list $origin_nscmd {*}$arglist] + #::tcl::namespace::eval $origin_ns [list $origin_nscmd {*}$arglist] + nseval $origin_ns [list $origin_nscmd {*}$arglist] } trap {} {errMsg errOptions} { set _cmdtrace_disabled true #(even a puts can involve function calls - e.g in contexts where there are stacked channels) @@ -2689,9 +2693,12 @@ y" {return quirkykeyscript} } finally { set _cmdtrace_disabled true foreach {tgt_cmd ns nscmd} $resolved_targets { - ::tcl::namespace::eval $ns [list ::trace remove execution $nscmd enterstep [list ::punk::ns::_cmdtrace_enterstep ::punk::ns::linedict $tgt_cmd]] - ::tcl::namespace::eval $ns [list ::trace remove execution $nscmd enter [list ::punk::ns::_cmdtrace_enter ::punk::ns::linedict $tgt_cmd]] - ::tcl::namespace::eval $ns [list ::trace remove execution $nscmd leave [list ::punk::ns::_cmdtrace_leave ::punk::ns::linedict $tgt_cmd]] + #::tcl::namespace::eval $ns [list ::trace remove execution $nscmd enterstep [list ::punk::ns::_cmdtrace_enterstep ::punk::ns::linedict $tgt_cmd]] + #::tcl::namespace::eval $ns [list ::trace remove execution $nscmd enter [list ::punk::ns::_cmdtrace_enter ::punk::ns::linedict $tgt_cmd]] + #::tcl::namespace::eval $ns [list ::trace remove execution $nscmd leave [list ::punk::ns::_cmdtrace_leave ::punk::ns::linedict $tgt_cmd]] + nseval $ns [list ::trace remove execution $nscmd enterstep [list ::punk::ns::_cmdtrace_enterstep ::punk::ns::linedict $tgt_cmd]] + nseval $ns [list ::trace remove execution $nscmd enter [list ::punk::ns::_cmdtrace_enter ::punk::ns::linedict $tgt_cmd]] + nseval $ns [list ::trace remove execution $nscmd leave [list ::punk::ns::_cmdtrace_leave ::punk::ns::linedict $tgt_cmd]] } } @@ -4168,6 +4175,21 @@ y" {return quirkykeyscript} return [dict create origin $origin origintype $origintype which $resolved whichtype $whichtype] } + proc info_default {targetns targetproc targetarg} { + #this *very odd* construct is to avoid using the namespace argument of apply. (handling of *weird/inadvisable* namespaces) + #we use an uplevel from within the apply which runs in the global namespace, (but called via nseval from within targetns) and a result var for 'info default' in the current punk::ns namespace. + nseval $targetns [list apply [list {procname argname} { + set has_default [uplevel 1 [list info default $procname $argname ::punk::ns::corp_defvar]] + if {$has_default} { + set answer [dict create exists 1 default $::punk::ns::corp_defvar] + } else { + set answer [dict create exists 0 default {}] + } + unset ::punk::ns::corp_defvar + return $answer + } ] $targetproc $targetarg] + } + #review - should be in punk::args? proc generate_autodef {args} { set cmd [lindex $args 0] @@ -4659,7 +4681,10 @@ y" {return quirkykeyscript} #we can't use 'info args :::' - tcl won't find it set ns [nsprefix $origin] set nscmd [nstail $origin] - set infoargs [namespace eval $ns [list ::tcl::info::args $nscmd]] + #set infoargs [namespace eval $ns [list ::tcl::info::args $nscmd]] + set infoargs [nseval $ns [list ::tcl::info::args $nscmd]] + + set argdef [punk::lib::tstr -return string { @id -id "${$autoid}" @cmd -help\ @@ -4673,15 +4698,33 @@ y" {return quirkykeyscript} incr i #we need a varname for ::tcl::info::default - but as we need to run it in the ns we have to be careful, #or we risk variable collisions/pollution of the target ns. - set default_info [apply [list {procname argname} { - if {[::tcl::info::default $procname $argname defaultval]} { - return [dict create exists 1 default $defaultval] - } else { - return [dict create exists 0 default ""] - } - } $ns] $nscmd $a] + + #odd + #set default_info [apply [list {procname argname} { + # if {[::tcl::info::default $procname $argname defaultval]} { + # return [dict create exists 1 default $defaultval] + # } else { + # return [dict create exists 0 default ""] + # } + #} $ns] $nscmd $a] + set default_info [info_default $ns $nscmd $a] + + if {[dict get $default_info exists]} { - append argdef \n "$a -type unknown -default \"[dict get $default_info default]\"" + #We have to be careful if default value is something like a single double-quote. + #e.g proc ::csv::join {values {sepChar ,} {delChar {"}} {delMode auto}} {...} + + #building it as a string is tricky, we need to quote it, but not if already quoted + #- this attempt is broken + # #append argdef \n "$a -type unknown -default \"[dict get $default_info default]\"" + # #set default_info [string map [list \{ \\{ \} \\}] $default_info] + # #append argdef \n "$a -type unknown -default {" [dict get $default_info default] "}" + + #building it as a list seems likely to be more robust. + #(we parse each line as a list in punk::args) + #REVIEW + set line [list $a -type unknown -default [dict get $default_info default]] + append argdef \n $line } else { if {$i == [llength $infoargs]-1 && $a eq "args"} { #we need to use a name that doesn't collide with any previous arguments @@ -4705,7 +4748,9 @@ y" {return quirkykeyscript} } append argdef \n "$args_element -type unknown -multiple 1 -optional 1" } else { - append argdef \n "$a -type unknown" + set line [list $a -type unknown] ;#list protect for odd names of arguments + append argdef \n $line + #append argdef \n "$a -type unknown" } } } @@ -6635,7 +6680,8 @@ y" {return quirkykeyscript} set untabify [dict get $opts -untabify] set do_ln [expr {[dict exists $received --line-number]}] #thanks to Richard Suchenwirth for the original - wiki.tcl-lang.org/page/corp - #Note: modified here to support aliases and relative/absolute name (with respect to namespace .ie ::name vs name) + #Note: modified and much-extended here to support aliases and relative/absolute name (with respect to namespace .ie ::name vs name) + if {[info exists punk::console::tabwidth]} { set tw $::punk::console::tabwidth } else { @@ -6722,10 +6768,19 @@ y" {return quirkykeyscript} #set bodytext [punk::lib::undent [textutil::untabify2 $bodytext $tw]] if {$untabify ne "none"} { - set bodytext [punk::lib::undent [punk::ansi::untabify -with $untabify -stops $tw $bodytext]] + #set bodytext [punk::lib::undent [punk::ansi::untabify -with $untabify -stops $tw $bodytext]] + set bodytext [punk::ansi::untabify -with $untabify -stops $tw $bodytext] } - append body [punk::lib::indent $bodytext $indent] + set opt_indent 0 + if {$opt_indent} { + #we generally don't want to indent the body. + #Some text strings are constructed based on specific indentation. + append body [punk::lib::indent $bodytext $indent] + } else { + #no indent - more likely we could run the result (if -syntax none) to regenerate the proc with strings intact regarding their spacing relative to the left margin. + append body $bodytext + } set argl {} @@ -6734,24 +6789,47 @@ y" {return quirkykeyscript} #if {[info default $origin $a defvar]} { # lappend a $defvar #} - set result [nseval $targetns [string map [list %n% $name %a% $a] { - #qualify all command names when running in arbitrary namespace - ::if {[::info default "%n%" "%a%" punk_ns_corp_defvar]} { - ::return [::list default $punk_ns_corp_defvar][::unset punk_ns_corp_defvar] ;#keep the targetns tidy - } else { - ::return [::list none] - } - }]] - if {[lindex $result 0] eq "default"} { - lappend a [lindex $result 1] + + #string map is risky for strange values of $a + #set result [nseval $targetns [string map [list %n% $name %a% $a] { + # #qualify all command names when running in arbitrary namespace + # ::if {[::info default "%n%" "%a%" punk_ns_corp_defvar]} { + # #::return [::list default [::tcl::string::map [::list {"} {\"} \[ {\[]} \] {\]} ] $punk_ns_corp_defvar]][::unset punk_ns_corp_defvar] ;#keep the targetns tidy + # ::return [::list default $punk_ns_corp_defvar][::unset punk_ns_corp_defvar] ;#keep the targetns tidy + # } else { + # ::return [::list none] + # } + #}]] + + #this very odd construct is to avoid using the namespace argument of apply. (handling of *weird/inadvisable* namespaces) + #we use an uplevel from within the apply which runs in the global namespace, (but called via nseval from within targetns) and a result var for 'info default' in the current punk::ns namespace. + #set result [nseval $targetns [list apply [list {procname argname} { + # set has_default [uplevel 1 [list info default $procname $argname ::punk::ns::corp_defvar]] + # if {$has_default} { + # set answer [list default $::punk::ns::corp_defvar] + # } else { + # set answer [list none] + # } + # unset ::punk::ns::corp_defvar + # return $answer + #} ] $name $a]] + #if {[lindex $result 0] eq "default"} { + # lappend a [lindex $result 1] + #} + + set default_info [info_default $targetns $name $a] + if {[dict get $default_info exists]} { + lappend a [dict get $default_info default] } + lappend argl $a } #list proc [nsjoin ${targetns} $name] $argl $body #todo - load highlighters as functions from somewhere set is_highlighted 1 ;# default assumption set lnc [punk::ansi::a+ term-73] - set lnr "\x1b\[m" + #set lnr "\x1b\[m" + set lnr [punk::console::code_a] switch -- $syntax { basic { #rudimentary colourising only diff --git a/src/bootsupport/modules/punkcheck-0.1.0.tm b/src/bootsupport/modules/punkcheck-0.1.0.tm index 31403512..2d80abcb 100644 --- a/src/bootsupport/modules/punkcheck-0.1.0.tm +++ b/src/bootsupport/modules/punkcheck-0.1.0.tm @@ -306,9 +306,11 @@ namespace eval punkcheck { set record_list [punkcheck::load_records_from_file $punkcheck_file] + #--------------------------------------------------------------------------- #load as dict to test for dupes - #set targetdict [my targetset_dict] - set targetdict [punkcheck::recordlist::records_as_target_dict $record_list] + #set _targetdict [my targetset_dict] + set _targetdict [punkcheck::recordlist::records_as_target_dict $record_list] + #--------------------------------------------------------------------------- set extractioninfo [punkcheck::recordlist::extract_or_create_fileset_record $o_targets $record_list] set o_fileset_record [dict get $extractioninfo record] diff --git a/src/bootsupport/modules/shellrun-0.1.1.tm b/src/bootsupport/modules/shellrun-0.1.1.tm index c3f7ab10..96c578cd 100644 --- a/src/bootsupport/modules/shellrun-0.1.1.tm +++ b/src/bootsupport/modules/shellrun-0.1.1.tm @@ -362,6 +362,7 @@ namespace eval shellrun { } lappend chunklist [list "info" "$c$exitinfo$n"] } elseif {[dict exists $exitinfo error]} { + # -tcl (with error) set c [a+ yellow bold] lappend chunklist [list "info" "${c}error [dict get $exitinfo error]$n"] lappend chunklist [list "info" "errorCode [dict get $exitinfo errorCode]"] @@ -369,7 +370,8 @@ namespace eval shellrun { lappend chunklist [list "info" errorInfo] lappend chunklist [list "stderr" [dict get $exitinfo errorInfo]] } else { - set c [a+ Yellow red bold] + # -tcl (without error) + set c [a+ Green white bold] #lappend chunklist [list "info" "$c$exitinfo$n"] lappend chunklist [list "info" [punk::ansi::ansiwrap_raw $c \x1b\[m "" $exitinfo]] } @@ -511,12 +513,14 @@ namespace eval shellrun { } lappend chunklist [list "info" "$c$exitinfo$n"] } elseif {[dict exists $exitinfo error]} { + # -tcl (with error) set c [a+ yellow bold] lappend chunklist [list "info" "error [dict get $exitinfo error]"] lappend chunklist [list "info" "errorCode [dict get $exitinfo errorCode]"] lappend chunklist [list "info" "errorInfo [list [dict get $exitinfo errorInfo]]"] } else { - set c [a+ Yellow red bold] + # -tcl (without error) + set c [a+ Green white bold] #lappend chunklist [list "info" "$c$exitinfo$n"] lappend chunklist [list "info" [punk::ansi::ansiwrap_raw $c "\x1b\[m" "" $exitinfo]] } diff --git a/src/modules/overtype-999999.0a1.0.tm b/src/modules/overtype-999999.0a1.0.tm index 7285af6e..b89d6c40 100644 --- a/src/modules/overtype-999999.0a1.0.tm +++ b/src/modules/overtype-999999.0a1.0.tm @@ -3280,6 +3280,7 @@ tcl::namespace::eval overtype { set next_stop [lindex $tstops $prev_stop_idx+1] ;#if our tab_column is exactly on a stop, we still want to move to the next stop. set this_tab_width [expr {$next_stop - $tab_column}] ;#diff between two adjacent columns is one. + #insert the tab and the correct number of null columns for the tab expansion. set graphemes [list \t {*}[lrepeat [expr {$this_tab_width -1}] "\u0000"]] priv::render_insertgraphemes $idx $graphemes [lindex $overstacks $idx_over] [lindex $overstacks_gx $idx_over] incr idx $this_tab_width @@ -3594,8 +3595,6 @@ tcl::namespace::eval overtype { #This reflows for each grapheme inserted - but for now this is simpler than trying to handle multiple graphemes at once. priv::render_insertgraphemes $idx [list $ch] [lindex $overstacks $idx_over] [lindex $overstacks_gx $idx_over] incr idx - #don't incr cursor_column - review. - } else { priv::render_addchar $idx $ch [lindex $overstacks $idx_over] [lindex $overstacks_gx $idx_over] $insert_mode incr idx @@ -5598,9 +5597,9 @@ tcl::namespace::eval overtype { #} #-info values 2,3,4 for view modes - if {($opt_returnextra | 3) == $opt_returnextra} { + if {$opt_returnextra & 3} { set viewop VIEWCODES - } elseif {($opt_returnextra | 4) == $opt_returnextra} { + } elseif {$opt_returnextra & 4} { set viewop VIEWSTYLE } @@ -5622,7 +5621,7 @@ tcl::namespace::eval overtype { } #-info values 9,10,11,12 - if {($opt_returnextra | 8) == $opt_returnextra} { + if {$opt_returnextra & 8} { return [pdict -channel none result] } else { return $result diff --git a/src/modules/punk/ansi-999999.0a1.0.tm b/src/modules/punk/ansi-999999.0a1.0.tm index 7dcec20f..2c66fc10 100644 --- a/src/modules/punk/ansi-999999.0a1.0.tm +++ b/src/modules/punk/ansi-999999.0a1.0.tm @@ -5170,6 +5170,13 @@ Brightblack 100 Brightred 101 Brightgreen 102 Brightyellow 103 Brightblu set c [format %c [expr {$col + 31}]] return \x1bY${r}${c} } + + + #standard vt52 doesn't support color (monochrome displays only) + #Atari and some vt52 emulators may support limited colors - review + #todo - vt52color background vs foreground + #\x1bb foreground. + #\x1bc background. proc vt52color {int} { if {[string is integer -strict $int]} { if {$int < 0 || $int > 15} { @@ -5177,6 +5184,7 @@ Brightblack 100 Brightred 101 Brightgreen 102 Brightyellow 103 Brightblu } } set char [format %c [expr {$int + 31}]] + #foreground and background are the same char - but vt52 has separate modes for fg/bg - so we could just return the char and let caller decide which mode to be in return \x1bb${char} } @@ -6800,12 +6808,14 @@ be as if this was off - ie lone CR. return [dict create textcells $textcells scopes $scopes cellblocks $cellblocks blockwidths $blockwidths] } proc expand_elastic_tabs {textblock {with {" " " "}}} { + lassign $with tabchar spacechar + #temp set tstops [lrange [punk::lib::range 1 200 8] 1 end] + #REVIEW + set computed [_compute_plastic_tabstops $textblock 4] - lassign $with tabchar spacechar - set computed [_compute_plastic_tabstops $textblock 4] set numrows [llength [dict get $computed textcells]] #set numcols [expr {[dict get $computed scopes 0 columncount] - 1}] set cellblocks [dict get $computed cellblocks] diff --git a/src/modules/punk/args-999999.0a1.0.tm b/src/modules/punk/args-999999.0a1.0.tm index a56deba3..9f6e329a 100644 --- a/src/modules/punk/args-999999.0a1.0.tm +++ b/src/modules/punk/args-999999.0a1.0.tm @@ -10459,7 +10459,12 @@ tcl::namespace::eval punk::args { set ts [Dict_getdef $arginfo -typesynopsis ""] set n [expr {[llength $typelist]-1}] - set name_tail [lrange $argname end-$n end];#if there are enough tail words in the argname to match -types + if {![catch {llength $argname}]} { + set name_tail [lrange $argname end-$n end];#if there are enough tail words in the argname to match -types + } else { + #argname is not a valid Tcl list - so we can't take tail words from it for display hints + set name_tail [list $argname] + } set clause "" if {$ts ne ""} { set tp_displaylist $ts @@ -10468,7 +10473,7 @@ tcl::namespace::eval punk::args { } foreach typespec $typelist td $tp_displaylist elementname $name_tail { - #elementname will commonly be empty + #elementname will commonly be empty after first iteration if {[string match {\?*\?} $typespec]} { set tp [string range $typespec 1 end-1] set member_optional 1 diff --git a/src/modules/punk/console-999999.0a1.0.tm b/src/modules/punk/console-999999.0a1.0.tm index 39eef718..090e3ec8 100644 --- a/src/modules/punk/console-999999.0a1.0.tm +++ b/src/modules/punk/console-999999.0a1.0.tm @@ -784,50 +784,34 @@ namespace eval punk::console { tailcall ::punk::ansi::a? {*}$args } } - #proc a? {args} { - # #stdout - # variable ansi_wanted - # if {$ansi_wanted <= 0} { - # puts -nonewline [punk::ansi::ansistripraw [::punk::ansi::a?]] - # } else { - # tailcall ansi::a? {*}$args - # } - #} #REVIEW! this needs reworking. #It needs to be clarified as to what ansi off is supposed to do. #Turning ansi off only stops new ansi being generated - but what about codes stored in configurations of existing elements such as tables/frames? #It will stop underlines/bold/reverse as well as SGR colours + #colour off is more specific - it only stops SGR colour codes from being generated - but underlines/bold/reverse will still be generated. #what about ansi movement codes etc? #we already have colour on|off which disables SGR codes in a+ etc as well as stderr/stdout channel transforms proc ansi {{onoff {}}} { variable ansi_wanted if {[string length $onoff]} { - set onoff [string tolower $onoff] - switch -- $onoff { - 1 - - on - - true - - yes { - set ansi_wanted 1 - } - 0 - - off - - false - - no { - set ansi_wanted 0 - punk::ansi::sgr_cache -action clear - } - default { - set ansi_wanted 2 - } - default { - error "punk::console::ansi expected 0|1|on|off|true|false|yes|no|default" - } + if {$onoff eq "default"} { + set ansi_wanted 2 + catch {punk::repl::reset_prompt} + return + } + if {![string is boolean -strict $onoff]} { + error "punk::console::ansi expected a boolean e.g 0|1|on|off|true|false|yes|no" + } + if {$onoff} { + set ansi_wanted 1 + } else { + set ansi_wanted 0 + punk::ansi::sgr_cache -action clear } + catch {punk::repl::reset_prompt} } - catch {punk::repl::reset_prompt} - puts stderr "::punk::console::ansi - use 'colour' command to turn SGR codes on/off" + puts stderr "::punk::console::ansi - use 'colour' command to turn SGR codes on/off (except bold/underline/reverse which are controlled by 'ansi' command)" return [expr {$ansi_wanted}] } @@ -863,8 +847,8 @@ namespace eval punk::console { #test - find a better place to set terminal type variable is_vt52 0 proc vt52 {{onoff {}}} { - #todo - return to colour state beforehand?. support 0-15 vt52 colours? - #we shouldn't have to trun off colour to enter vt52 - we should make punk::console emit correct codes + #todo - return to colour state beforehand?. support 0-15 vt52 colours? (ATARI and some emulators - not original vt52) + #we shouldn't have to turn off colour to enter vt52 - we should make punk::console emit correct codes variable is_vt52 if {$onoff eq ""} { return $is_vt52 @@ -2873,7 +2857,7 @@ namespace eval punk::console { return 0 } set existing_mode [twapi::GetConsoleMode $h_out] - if {[expr {$existing_mode & 4}]} { + if {$existing_mode & 4} { #virtual terminal processing happens to be enabled - so it's supported return 1 } diff --git a/src/modules/punk/ns-999999.0a1.0.tm b/src/modules/punk/ns-999999.0a1.0.tm index 62078f0d..82ba6d75 100644 --- a/src/modules/punk/ns-999999.0a1.0.tm +++ b/src/modules/punk/ns-999999.0a1.0.tm @@ -2671,16 +2671,20 @@ y" {return quirkykeyscript} foreach {tgt_cmd ns nscmd} $resolved_targets { puts "tracing target: $tgt_cmd whilst running: $origin $arglist" - ::tcl::namespace::eval $ns [list ::trace add execution $nscmd enter [list ::punk::ns::_cmdtrace_enter ::punk::ns::linedict $tgt_cmd]] - ::tcl::namespace::eval $ns [list ::trace add execution $nscmd enterstep [list ::punk::ns::_cmdtrace_enterstep ::punk::ns::linedict $tgt_cmd]] - ::tcl::namespace::eval $ns [list ::trace add execution $nscmd leave [list ::punk::ns::_cmdtrace_leave ::punk::ns::linedict $tgt_cmd]] + #::tcl::namespace::eval $ns [list ::trace add execution $nscmd enter [list ::punk::ns::_cmdtrace_enter ::punk::ns::linedict $tgt_cmd]] + #::tcl::namespace::eval $ns [list ::trace add execution $nscmd enterstep [list ::punk::ns::_cmdtrace_enterstep ::punk::ns::linedict $tgt_cmd]] + #::tcl::namespace::eval $ns [list ::trace add execution $nscmd leave [list ::punk::ns::_cmdtrace_leave ::punk::ns::linedict $tgt_cmd]] + nseval $ns [list ::trace add execution $nscmd enter [list ::punk::ns::_cmdtrace_enter ::punk::ns::linedict $tgt_cmd]] + nseval $ns [list ::trace add execution $nscmd enterstep [list ::punk::ns::_cmdtrace_enterstep ::punk::ns::linedict $tgt_cmd]] + nseval $ns [list ::trace add execution $nscmd leave [list ::punk::ns::_cmdtrace_leave ::punk::ns::linedict $tgt_cmd]] } try { #uplevel 1 [list $origin {*}$arglist] set _cmdtrace_disabled false - ::tcl::namespace::eval $origin_ns [list $origin_nscmd {*}$arglist] + #::tcl::namespace::eval $origin_ns [list $origin_nscmd {*}$arglist] + nseval $origin_ns [list $origin_nscmd {*}$arglist] } trap {} {errMsg errOptions} { set _cmdtrace_disabled true #(even a puts can involve function calls - e.g in contexts where there are stacked channels) @@ -2689,9 +2693,12 @@ y" {return quirkykeyscript} } finally { set _cmdtrace_disabled true foreach {tgt_cmd ns nscmd} $resolved_targets { - ::tcl::namespace::eval $ns [list ::trace remove execution $nscmd enterstep [list ::punk::ns::_cmdtrace_enterstep ::punk::ns::linedict $tgt_cmd]] - ::tcl::namespace::eval $ns [list ::trace remove execution $nscmd enter [list ::punk::ns::_cmdtrace_enter ::punk::ns::linedict $tgt_cmd]] - ::tcl::namespace::eval $ns [list ::trace remove execution $nscmd leave [list ::punk::ns::_cmdtrace_leave ::punk::ns::linedict $tgt_cmd]] + #::tcl::namespace::eval $ns [list ::trace remove execution $nscmd enterstep [list ::punk::ns::_cmdtrace_enterstep ::punk::ns::linedict $tgt_cmd]] + #::tcl::namespace::eval $ns [list ::trace remove execution $nscmd enter [list ::punk::ns::_cmdtrace_enter ::punk::ns::linedict $tgt_cmd]] + #::tcl::namespace::eval $ns [list ::trace remove execution $nscmd leave [list ::punk::ns::_cmdtrace_leave ::punk::ns::linedict $tgt_cmd]] + nseval $ns [list ::trace remove execution $nscmd enterstep [list ::punk::ns::_cmdtrace_enterstep ::punk::ns::linedict $tgt_cmd]] + nseval $ns [list ::trace remove execution $nscmd enter [list ::punk::ns::_cmdtrace_enter ::punk::ns::linedict $tgt_cmd]] + nseval $ns [list ::trace remove execution $nscmd leave [list ::punk::ns::_cmdtrace_leave ::punk::ns::linedict $tgt_cmd]] } } @@ -4168,6 +4175,21 @@ y" {return quirkykeyscript} return [dict create origin $origin origintype $origintype which $resolved whichtype $whichtype] } + proc info_default {targetns targetproc targetarg} { + #this *very odd* construct is to avoid using the namespace argument of apply. (handling of *weird/inadvisable* namespaces) + #we use an uplevel from within the apply which runs in the global namespace, (but called via nseval from within targetns) and a result var for 'info default' in the current punk::ns namespace. + nseval $targetns [list apply [list {procname argname} { + set has_default [uplevel 1 [list info default $procname $argname ::punk::ns::corp_defvar]] + if {$has_default} { + set answer [dict create exists 1 default $::punk::ns::corp_defvar] + } else { + set answer [dict create exists 0 default {}] + } + unset ::punk::ns::corp_defvar + return $answer + } ] $targetproc $targetarg] + } + #review - should be in punk::args? proc generate_autodef {args} { set cmd [lindex $args 0] @@ -4659,7 +4681,10 @@ y" {return quirkykeyscript} #we can't use 'info args :::' - tcl won't find it set ns [nsprefix $origin] set nscmd [nstail $origin] - set infoargs [namespace eval $ns [list ::tcl::info::args $nscmd]] + #set infoargs [namespace eval $ns [list ::tcl::info::args $nscmd]] + set infoargs [nseval $ns [list ::tcl::info::args $nscmd]] + + set argdef [punk::lib::tstr -return string { @id -id "${$autoid}" @cmd -help\ @@ -4673,15 +4698,33 @@ y" {return quirkykeyscript} incr i #we need a varname for ::tcl::info::default - but as we need to run it in the ns we have to be careful, #or we risk variable collisions/pollution of the target ns. - set default_info [apply [list {procname argname} { - if {[::tcl::info::default $procname $argname defaultval]} { - return [dict create exists 1 default $defaultval] - } else { - return [dict create exists 0 default ""] - } - } $ns] $nscmd $a] + + #odd + #set default_info [apply [list {procname argname} { + # if {[::tcl::info::default $procname $argname defaultval]} { + # return [dict create exists 1 default $defaultval] + # } else { + # return [dict create exists 0 default ""] + # } + #} $ns] $nscmd $a] + set default_info [info_default $ns $nscmd $a] + + if {[dict get $default_info exists]} { - append argdef \n "$a -type unknown -default \"[dict get $default_info default]\"" + #We have to be careful if default value is something like a single double-quote. + #e.g proc ::csv::join {values {sepChar ,} {delChar {"}} {delMode auto}} {...} + + #building it as a string is tricky, we need to quote it, but not if already quoted + #- this attempt is broken + # #append argdef \n "$a -type unknown -default \"[dict get $default_info default]\"" + # #set default_info [string map [list \{ \\{ \} \\}] $default_info] + # #append argdef \n "$a -type unknown -default {" [dict get $default_info default] "}" + + #building it as a list seems likely to be more robust. + #(we parse each line as a list in punk::args) + #REVIEW + set line [list $a -type unknown -default [dict get $default_info default]] + append argdef \n $line } else { if {$i == [llength $infoargs]-1 && $a eq "args"} { #we need to use a name that doesn't collide with any previous arguments @@ -4705,7 +4748,9 @@ y" {return quirkykeyscript} } append argdef \n "$args_element -type unknown -multiple 1 -optional 1" } else { - append argdef \n "$a -type unknown" + set line [list $a -type unknown] ;#list protect for odd names of arguments + append argdef \n $line + #append argdef \n "$a -type unknown" } } } @@ -6635,7 +6680,8 @@ y" {return quirkykeyscript} set untabify [dict get $opts -untabify] set do_ln [expr {[dict exists $received --line-number]}] #thanks to Richard Suchenwirth for the original - wiki.tcl-lang.org/page/corp - #Note: modified here to support aliases and relative/absolute name (with respect to namespace .ie ::name vs name) + #Note: modified and much-extended here to support aliases and relative/absolute name (with respect to namespace .ie ::name vs name) + if {[info exists punk::console::tabwidth]} { set tw $::punk::console::tabwidth } else { @@ -6722,10 +6768,19 @@ y" {return quirkykeyscript} #set bodytext [punk::lib::undent [textutil::untabify2 $bodytext $tw]] if {$untabify ne "none"} { - set bodytext [punk::lib::undent [punk::ansi::untabify -with $untabify -stops $tw $bodytext]] + #set bodytext [punk::lib::undent [punk::ansi::untabify -with $untabify -stops $tw $bodytext]] + set bodytext [punk::ansi::untabify -with $untabify -stops $tw $bodytext] } - append body [punk::lib::indent $bodytext $indent] + set opt_indent 0 + if {$opt_indent} { + #we generally don't want to indent the body. + #Some text strings are constructed based on specific indentation. + append body [punk::lib::indent $bodytext $indent] + } else { + #no indent - more likely we could run the result (if -syntax none) to regenerate the proc with strings intact regarding their spacing relative to the left margin. + append body $bodytext + } set argl {} @@ -6734,24 +6789,47 @@ y" {return quirkykeyscript} #if {[info default $origin $a defvar]} { # lappend a $defvar #} - set result [nseval $targetns [string map [list %n% $name %a% $a] { - #qualify all command names when running in arbitrary namespace - ::if {[::info default "%n%" "%a%" punk_ns_corp_defvar]} { - ::return [::list default $punk_ns_corp_defvar][::unset punk_ns_corp_defvar] ;#keep the targetns tidy - } else { - ::return [::list none] - } - }]] - if {[lindex $result 0] eq "default"} { - lappend a [lindex $result 1] + + #string map is risky for strange values of $a + #set result [nseval $targetns [string map [list %n% $name %a% $a] { + # #qualify all command names when running in arbitrary namespace + # ::if {[::info default "%n%" "%a%" punk_ns_corp_defvar]} { + # #::return [::list default [::tcl::string::map [::list {"} {\"} \[ {\[]} \] {\]} ] $punk_ns_corp_defvar]][::unset punk_ns_corp_defvar] ;#keep the targetns tidy + # ::return [::list default $punk_ns_corp_defvar][::unset punk_ns_corp_defvar] ;#keep the targetns tidy + # } else { + # ::return [::list none] + # } + #}]] + + #this very odd construct is to avoid using the namespace argument of apply. (handling of *weird/inadvisable* namespaces) + #we use an uplevel from within the apply which runs in the global namespace, (but called via nseval from within targetns) and a result var for 'info default' in the current punk::ns namespace. + #set result [nseval $targetns [list apply [list {procname argname} { + # set has_default [uplevel 1 [list info default $procname $argname ::punk::ns::corp_defvar]] + # if {$has_default} { + # set answer [list default $::punk::ns::corp_defvar] + # } else { + # set answer [list none] + # } + # unset ::punk::ns::corp_defvar + # return $answer + #} ] $name $a]] + #if {[lindex $result 0] eq "default"} { + # lappend a [lindex $result 1] + #} + + set default_info [info_default $targetns $name $a] + if {[dict get $default_info exists]} { + lappend a [dict get $default_info default] } + lappend argl $a } #list proc [nsjoin ${targetns} $name] $argl $body #todo - load highlighters as functions from somewhere set is_highlighted 1 ;# default assumption set lnc [punk::ansi::a+ term-73] - set lnr "\x1b\[m" + #set lnr "\x1b\[m" + set lnr [punk::console::code_a] switch -- $syntax { basic { #rudimentary colourising only diff --git a/src/modules/punkcheck-0.1.0.tm b/src/modules/punkcheck-0.1.0.tm index 31403512..2d80abcb 100644 --- a/src/modules/punkcheck-0.1.0.tm +++ b/src/modules/punkcheck-0.1.0.tm @@ -306,9 +306,11 @@ namespace eval punkcheck { set record_list [punkcheck::load_records_from_file $punkcheck_file] + #--------------------------------------------------------------------------- #load as dict to test for dupes - #set targetdict [my targetset_dict] - set targetdict [punkcheck::recordlist::records_as_target_dict $record_list] + #set _targetdict [my targetset_dict] + set _targetdict [punkcheck::recordlist::records_as_target_dict $record_list] + #--------------------------------------------------------------------------- set extractioninfo [punkcheck::recordlist::extract_or_create_fileset_record $o_targets $record_list] set o_fileset_record [dict get $extractioninfo record] diff --git a/src/modules/shellrun-0.1.1.tm b/src/modules/shellrun-0.1.1.tm index c3f7ab10..96c578cd 100644 --- a/src/modules/shellrun-0.1.1.tm +++ b/src/modules/shellrun-0.1.1.tm @@ -362,6 +362,7 @@ namespace eval shellrun { } lappend chunklist [list "info" "$c$exitinfo$n"] } elseif {[dict exists $exitinfo error]} { + # -tcl (with error) set c [a+ yellow bold] lappend chunklist [list "info" "${c}error [dict get $exitinfo error]$n"] lappend chunklist [list "info" "errorCode [dict get $exitinfo errorCode]"] @@ -369,7 +370,8 @@ namespace eval shellrun { lappend chunklist [list "info" errorInfo] lappend chunklist [list "stderr" [dict get $exitinfo errorInfo]] } else { - set c [a+ Yellow red bold] + # -tcl (without error) + set c [a+ Green white bold] #lappend chunklist [list "info" "$c$exitinfo$n"] lappend chunklist [list "info" [punk::ansi::ansiwrap_raw $c \x1b\[m "" $exitinfo]] } @@ -511,12 +513,14 @@ namespace eval shellrun { } lappend chunklist [list "info" "$c$exitinfo$n"] } elseif {[dict exists $exitinfo error]} { + # -tcl (with error) set c [a+ yellow bold] lappend chunklist [list "info" "error [dict get $exitinfo error]"] lappend chunklist [list "info" "errorCode [dict get $exitinfo errorCode]"] lappend chunklist [list "info" "errorInfo [list [dict get $exitinfo errorInfo]]"] } else { - set c [a+ Yellow red bold] + # -tcl (without error) + set c [a+ Green white bold] #lappend chunklist [list "info" "$c$exitinfo$n"] lappend chunklist [list "info" [punk::ansi::ansiwrap_raw $c "\x1b\[m" "" $exitinfo]] } diff --git a/src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/overtype-1.7.4.tm b/src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/overtype-1.7.4.tm index 1b71be1f..403e971c 100644 --- a/src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/overtype-1.7.4.tm +++ b/src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/overtype-1.7.4.tm @@ -3280,6 +3280,7 @@ tcl::namespace::eval overtype { set next_stop [lindex $tstops $prev_stop_idx+1] ;#if our tab_column is exactly on a stop, we still want to move to the next stop. set this_tab_width [expr {$next_stop - $tab_column}] ;#diff between two adjacent columns is one. + #insert the tab and the correct number of null columns for the tab expansion. set graphemes [list \t {*}[lrepeat [expr {$this_tab_width -1}] "\u0000"]] priv::render_insertgraphemes $idx $graphemes [lindex $overstacks $idx_over] [lindex $overstacks_gx $idx_over] incr idx $this_tab_width @@ -3594,8 +3595,6 @@ tcl::namespace::eval overtype { #This reflows for each grapheme inserted - but for now this is simpler than trying to handle multiple graphemes at once. priv::render_insertgraphemes $idx [list $ch] [lindex $overstacks $idx_over] [lindex $overstacks_gx $idx_over] incr idx - #don't incr cursor_column - review. - } else { priv::render_addchar $idx $ch [lindex $overstacks $idx_over] [lindex $overstacks_gx $idx_over] $insert_mode incr idx @@ -5598,9 +5597,9 @@ tcl::namespace::eval overtype { #} #-info values 2,3,4 for view modes - if {($opt_returnextra | 3) == $opt_returnextra} { + if {$opt_returnextra & 3} { set viewop VIEWCODES - } elseif {($opt_returnextra | 4) == $opt_returnextra} { + } elseif {$opt_returnextra & 4} { set viewop VIEWSTYLE } @@ -5622,7 +5621,7 @@ tcl::namespace::eval overtype { } #-info values 9,10,11,12 - if {($opt_returnextra | 8) == $opt_returnextra} { + if {$opt_returnextra & 8} { return [pdict -channel none result] } else { return $result diff --git a/src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/ansi-0.1.1.tm b/src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/ansi-0.1.1.tm index 7e7bc823..f9997649 100644 --- a/src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/ansi-0.1.1.tm +++ b/src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/ansi-0.1.1.tm @@ -5170,6 +5170,13 @@ Brightblack 100 Brightred 101 Brightgreen 102 Brightyellow 103 Brightblu set c [format %c [expr {$col + 31}]] return \x1bY${r}${c} } + + + #standard vt52 doesn't support color (monochrome displays only) + #Atari and some vt52 emulators may support limited colors - review + #todo - vt52color background vs foreground + #\x1bb foreground. + #\x1bc background. proc vt52color {int} { if {[string is integer -strict $int]} { if {$int < 0 || $int > 15} { @@ -5177,6 +5184,7 @@ Brightblack 100 Brightred 101 Brightgreen 102 Brightyellow 103 Brightblu } } set char [format %c [expr {$int + 31}]] + #foreground and background are the same char - but vt52 has separate modes for fg/bg - so we could just return the char and let caller decide which mode to be in return \x1bb${char} } @@ -6800,12 +6808,14 @@ be as if this was off - ie lone CR. return [dict create textcells $textcells scopes $scopes cellblocks $cellblocks blockwidths $blockwidths] } proc expand_elastic_tabs {textblock {with {" " " "}}} { + lassign $with tabchar spacechar + #temp set tstops [lrange [punk::lib::range 1 200 8] 1 end] + #REVIEW + set computed [_compute_plastic_tabstops $textblock 4] - lassign $with tabchar spacechar - set computed [_compute_plastic_tabstops $textblock 4] set numrows [llength [dict get $computed textcells]] #set numcols [expr {[dict get $computed scopes 0 columncount] - 1}] set cellblocks [dict get $computed cellblocks] diff --git a/src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/args-0.2.1.tm b/src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/args-0.2.1.tm index 0056e9d0..1ff7fd37 100644 --- a/src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/args-0.2.1.tm +++ b/src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/args-0.2.1.tm @@ -10459,7 +10459,12 @@ tcl::namespace::eval punk::args { set ts [Dict_getdef $arginfo -typesynopsis ""] set n [expr {[llength $typelist]-1}] - set name_tail [lrange $argname end-$n end];#if there are enough tail words in the argname to match -types + if {![catch {llength $argname}]} { + set name_tail [lrange $argname end-$n end];#if there are enough tail words in the argname to match -types + } else { + #argname is not a valid Tcl list - so we can't take tail words from it for display hints + set name_tail [list $argname] + } set clause "" if {$ts ne ""} { set tp_displaylist $ts @@ -10468,7 +10473,7 @@ tcl::namespace::eval punk::args { } foreach typespec $typelist td $tp_displaylist elementname $name_tail { - #elementname will commonly be empty + #elementname will commonly be empty after first iteration if {[string match {\?*\?} $typespec]} { set tp [string range $typespec 1 end-1] set member_optional 1 diff --git a/src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/console-0.1.1.tm b/src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/console-0.1.1.tm index 9c378b1a..5271bbfb 100644 --- a/src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/console-0.1.1.tm +++ b/src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/console-0.1.1.tm @@ -784,50 +784,34 @@ namespace eval punk::console { tailcall ::punk::ansi::a? {*}$args } } - #proc a? {args} { - # #stdout - # variable ansi_wanted - # if {$ansi_wanted <= 0} { - # puts -nonewline [punk::ansi::ansistripraw [::punk::ansi::a?]] - # } else { - # tailcall ansi::a? {*}$args - # } - #} #REVIEW! this needs reworking. #It needs to be clarified as to what ansi off is supposed to do. #Turning ansi off only stops new ansi being generated - but what about codes stored in configurations of existing elements such as tables/frames? #It will stop underlines/bold/reverse as well as SGR colours + #colour off is more specific - it only stops SGR colour codes from being generated - but underlines/bold/reverse will still be generated. #what about ansi movement codes etc? #we already have colour on|off which disables SGR codes in a+ etc as well as stderr/stdout channel transforms proc ansi {{onoff {}}} { variable ansi_wanted if {[string length $onoff]} { - set onoff [string tolower $onoff] - switch -- $onoff { - 1 - - on - - true - - yes { - set ansi_wanted 1 - } - 0 - - off - - false - - no { - set ansi_wanted 0 - punk::ansi::sgr_cache -action clear - } - default { - set ansi_wanted 2 - } - default { - error "punk::console::ansi expected 0|1|on|off|true|false|yes|no|default" - } + if {$onoff eq "default"} { + set ansi_wanted 2 + catch {punk::repl::reset_prompt} + return + } + if {![string is boolean -strict $onoff]} { + error "punk::console::ansi expected a boolean e.g 0|1|on|off|true|false|yes|no" + } + if {$onoff} { + set ansi_wanted 1 + } else { + set ansi_wanted 0 + punk::ansi::sgr_cache -action clear } + catch {punk::repl::reset_prompt} } - catch {punk::repl::reset_prompt} - puts stderr "::punk::console::ansi - use 'colour' command to turn SGR codes on/off" + puts stderr "::punk::console::ansi - use 'colour' command to turn SGR codes on/off (except bold/underline/reverse which are controlled by 'ansi' command)" return [expr {$ansi_wanted}] } @@ -863,8 +847,8 @@ namespace eval punk::console { #test - find a better place to set terminal type variable is_vt52 0 proc vt52 {{onoff {}}} { - #todo - return to colour state beforehand?. support 0-15 vt52 colours? - #we shouldn't have to trun off colour to enter vt52 - we should make punk::console emit correct codes + #todo - return to colour state beforehand?. support 0-15 vt52 colours? (ATARI and some emulators - not original vt52) + #we shouldn't have to turn off colour to enter vt52 - we should make punk::console emit correct codes variable is_vt52 if {$onoff eq ""} { return $is_vt52 @@ -2873,7 +2857,7 @@ namespace eval punk::console { return 0 } set existing_mode [twapi::GetConsoleMode $h_out] - if {[expr {$existing_mode & 4}]} { + if {$existing_mode & 4} { #virtual terminal processing happens to be enabled - so it's supported return 1 } diff --git a/src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/mix/base-0.1.tm b/src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/mix/base-0.1.tm index ea9fc85f..eb1e1c5e 100644 --- a/src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/mix/base-0.1.tm +++ b/src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/mix/base-0.1.tm @@ -682,7 +682,7 @@ namespace eval punk::mix::base { cd $base ;#cd is process-wide.. keep cd in effect for as small a scope as possible. (review for thread issues) #temp emission to stdout.. todo - repl telemetry channel - puts stdout "cksum_path: creating temporary tar archive for $path" + puts stdout "\ncksum_path: creating temporary tar archive for $path" puts -nonewline stdout " at: $archivename ..." set tsstart [clock millis] if {[set tarpath [auto_execok tar]] ne ""} { @@ -709,7 +709,7 @@ namespace eval punk::mix::base { set sizeinfo "(file type $ftype - tarred size [punk::lib::format_number [file size $archivename]] bytes)" } set tsstart [clock millis] - puts -nonewline stdout "cksum_path: calculating cksum using $opt_cksum_algorithm for $target $sizeinfo ... " + puts -nonewline stdout "\ncksum_path: calculating cksum using $opt_cksum_algorithm for $target $sizeinfo ... " set cksum [{*}$cksum_command $archivename] set tsend [clock millis] set ms [expr {$tsend - $tsstart}] diff --git a/src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/mix/cli-0.3.1.tm b/src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/mix/cli-0.3.1.tm index dd2f5abd..05e8724f 100644 --- a/src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/mix/cli-0.3.1.tm +++ b/src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/mix/cli-0.3.1.tm @@ -599,6 +599,12 @@ namespace eval punk::mix::cli { if {[string match "foobar" $current_source_dir]} { set is_interesting 1 } + + #debug for issues on non-windows platforms. + if {$::tcl_platform(platform) ne "windows"} { + set is_interesting 1 + } + if {$is_interesting} { puts "build_modules_from_source_to_base >>> module $current_source_dir/$modpath" } @@ -609,10 +615,13 @@ namespace eval punk::mix::cli { #split_modulename_version version part will be empty if not valid tcl version #last segment doesn't look even slightly versiony - fail. puts stderr "ERROR: Unable to confirm file $current_source_dir/$modpath is a reasonably versioned .tm module - ABORTING." + flush stderr + after 1000 exit 1 } switch -- $modtype { pod { + puts -nonewline stderr "p-" #basename still contains leading #modpod- if {[string match #modpod-* $basename]} { set basename [string range $basename 8 end] @@ -689,6 +698,7 @@ namespace eval punk::mix::cli { puts stdout "$current_source_dir/$modpath" puts stdout "to:" puts stdout "$podtree_copy" + flush stdout file copy $current_source_dir/$modpath $podtree_copy if {$tmfile_versionsegment eq $magicversion} { set tmfile $buildfolder/#modpod-$basename-$module_build_version/$basename-$magicversion.tm @@ -809,6 +819,7 @@ namespace eval punk::mix::cli { } } tarjar { + puts -nonewline stderr "t-" #maint - overall code structure same as pod - refactor? #basename may still contain #tarjar- #to be obsoleted - update modpod to (optionally) use vfs::tar ? @@ -992,6 +1003,7 @@ namespace eval punk::mix::cli { } file { + puts -nonewline stderr "f-" set m $modpath if {$tmfile_versionsegment eq $magicversion} { #set basename [join [lrange $fileparts 0 end-1] -] diff --git a/src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/ns-0.1.0.tm b/src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/ns-0.1.0.tm index 6fcb3aa3..dc8c765c 100644 --- a/src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/ns-0.1.0.tm +++ b/src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/ns-0.1.0.tm @@ -2671,16 +2671,20 @@ y" {return quirkykeyscript} foreach {tgt_cmd ns nscmd} $resolved_targets { puts "tracing target: $tgt_cmd whilst running: $origin $arglist" - ::tcl::namespace::eval $ns [list ::trace add execution $nscmd enter [list ::punk::ns::_cmdtrace_enter ::punk::ns::linedict $tgt_cmd]] - ::tcl::namespace::eval $ns [list ::trace add execution $nscmd enterstep [list ::punk::ns::_cmdtrace_enterstep ::punk::ns::linedict $tgt_cmd]] - ::tcl::namespace::eval $ns [list ::trace add execution $nscmd leave [list ::punk::ns::_cmdtrace_leave ::punk::ns::linedict $tgt_cmd]] + #::tcl::namespace::eval $ns [list ::trace add execution $nscmd enter [list ::punk::ns::_cmdtrace_enter ::punk::ns::linedict $tgt_cmd]] + #::tcl::namespace::eval $ns [list ::trace add execution $nscmd enterstep [list ::punk::ns::_cmdtrace_enterstep ::punk::ns::linedict $tgt_cmd]] + #::tcl::namespace::eval $ns [list ::trace add execution $nscmd leave [list ::punk::ns::_cmdtrace_leave ::punk::ns::linedict $tgt_cmd]] + nseval $ns [list ::trace add execution $nscmd enter [list ::punk::ns::_cmdtrace_enter ::punk::ns::linedict $tgt_cmd]] + nseval $ns [list ::trace add execution $nscmd enterstep [list ::punk::ns::_cmdtrace_enterstep ::punk::ns::linedict $tgt_cmd]] + nseval $ns [list ::trace add execution $nscmd leave [list ::punk::ns::_cmdtrace_leave ::punk::ns::linedict $tgt_cmd]] } try { #uplevel 1 [list $origin {*}$arglist] set _cmdtrace_disabled false - ::tcl::namespace::eval $origin_ns [list $origin_nscmd {*}$arglist] + #::tcl::namespace::eval $origin_ns [list $origin_nscmd {*}$arglist] + nseval $origin_ns [list $origin_nscmd {*}$arglist] } trap {} {errMsg errOptions} { set _cmdtrace_disabled true #(even a puts can involve function calls - e.g in contexts where there are stacked channels) @@ -2689,9 +2693,12 @@ y" {return quirkykeyscript} } finally { set _cmdtrace_disabled true foreach {tgt_cmd ns nscmd} $resolved_targets { - ::tcl::namespace::eval $ns [list ::trace remove execution $nscmd enterstep [list ::punk::ns::_cmdtrace_enterstep ::punk::ns::linedict $tgt_cmd]] - ::tcl::namespace::eval $ns [list ::trace remove execution $nscmd enter [list ::punk::ns::_cmdtrace_enter ::punk::ns::linedict $tgt_cmd]] - ::tcl::namespace::eval $ns [list ::trace remove execution $nscmd leave [list ::punk::ns::_cmdtrace_leave ::punk::ns::linedict $tgt_cmd]] + #::tcl::namespace::eval $ns [list ::trace remove execution $nscmd enterstep [list ::punk::ns::_cmdtrace_enterstep ::punk::ns::linedict $tgt_cmd]] + #::tcl::namespace::eval $ns [list ::trace remove execution $nscmd enter [list ::punk::ns::_cmdtrace_enter ::punk::ns::linedict $tgt_cmd]] + #::tcl::namespace::eval $ns [list ::trace remove execution $nscmd leave [list ::punk::ns::_cmdtrace_leave ::punk::ns::linedict $tgt_cmd]] + nseval $ns [list ::trace remove execution $nscmd enterstep [list ::punk::ns::_cmdtrace_enterstep ::punk::ns::linedict $tgt_cmd]] + nseval $ns [list ::trace remove execution $nscmd enter [list ::punk::ns::_cmdtrace_enter ::punk::ns::linedict $tgt_cmd]] + nseval $ns [list ::trace remove execution $nscmd leave [list ::punk::ns::_cmdtrace_leave ::punk::ns::linedict $tgt_cmd]] } } @@ -4168,6 +4175,21 @@ y" {return quirkykeyscript} return [dict create origin $origin origintype $origintype which $resolved whichtype $whichtype] } + proc info_default {targetns targetproc targetarg} { + #this *very odd* construct is to avoid using the namespace argument of apply. (handling of *weird/inadvisable* namespaces) + #we use an uplevel from within the apply which runs in the global namespace, (but called via nseval from within targetns) and a result var for 'info default' in the current punk::ns namespace. + nseval $targetns [list apply [list {procname argname} { + set has_default [uplevel 1 [list info default $procname $argname ::punk::ns::corp_defvar]] + if {$has_default} { + set answer [dict create exists 1 default $::punk::ns::corp_defvar] + } else { + set answer [dict create exists 0 default {}] + } + unset ::punk::ns::corp_defvar + return $answer + } ] $targetproc $targetarg] + } + #review - should be in punk::args? proc generate_autodef {args} { set cmd [lindex $args 0] @@ -4659,7 +4681,10 @@ y" {return quirkykeyscript} #we can't use 'info args :::' - tcl won't find it set ns [nsprefix $origin] set nscmd [nstail $origin] - set infoargs [namespace eval $ns [list ::tcl::info::args $nscmd]] + #set infoargs [namespace eval $ns [list ::tcl::info::args $nscmd]] + set infoargs [nseval $ns [list ::tcl::info::args $nscmd]] + + set argdef [punk::lib::tstr -return string { @id -id "${$autoid}" @cmd -help\ @@ -4673,15 +4698,33 @@ y" {return quirkykeyscript} incr i #we need a varname for ::tcl::info::default - but as we need to run it in the ns we have to be careful, #or we risk variable collisions/pollution of the target ns. - set default_info [apply [list {procname argname} { - if {[::tcl::info::default $procname $argname defaultval]} { - return [dict create exists 1 default $defaultval] - } else { - return [dict create exists 0 default ""] - } - } $ns] $nscmd $a] + + #odd + #set default_info [apply [list {procname argname} { + # if {[::tcl::info::default $procname $argname defaultval]} { + # return [dict create exists 1 default $defaultval] + # } else { + # return [dict create exists 0 default ""] + # } + #} $ns] $nscmd $a] + set default_info [info_default $ns $nscmd $a] + + if {[dict get $default_info exists]} { - append argdef \n "$a -type unknown -default \"[dict get $default_info default]\"" + #We have to be careful if default value is something like a single double-quote. + #e.g proc ::csv::join {values {sepChar ,} {delChar {"}} {delMode auto}} {...} + + #building it as a string is tricky, we need to quote it, but not if already quoted + #- this attempt is broken + # #append argdef \n "$a -type unknown -default \"[dict get $default_info default]\"" + # #set default_info [string map [list \{ \\{ \} \\}] $default_info] + # #append argdef \n "$a -type unknown -default {" [dict get $default_info default] "}" + + #building it as a list seems likely to be more robust. + #(we parse each line as a list in punk::args) + #REVIEW + set line [list $a -type unknown -default [dict get $default_info default]] + append argdef \n $line } else { if {$i == [llength $infoargs]-1 && $a eq "args"} { #we need to use a name that doesn't collide with any previous arguments @@ -4705,7 +4748,9 @@ y" {return quirkykeyscript} } append argdef \n "$args_element -type unknown -multiple 1 -optional 1" } else { - append argdef \n "$a -type unknown" + set line [list $a -type unknown] ;#list protect for odd names of arguments + append argdef \n $line + #append argdef \n "$a -type unknown" } } } @@ -6635,7 +6680,8 @@ y" {return quirkykeyscript} set untabify [dict get $opts -untabify] set do_ln [expr {[dict exists $received --line-number]}] #thanks to Richard Suchenwirth for the original - wiki.tcl-lang.org/page/corp - #Note: modified here to support aliases and relative/absolute name (with respect to namespace .ie ::name vs name) + #Note: modified and much-extended here to support aliases and relative/absolute name (with respect to namespace .ie ::name vs name) + if {[info exists punk::console::tabwidth]} { set tw $::punk::console::tabwidth } else { @@ -6722,10 +6768,19 @@ y" {return quirkykeyscript} #set bodytext [punk::lib::undent [textutil::untabify2 $bodytext $tw]] if {$untabify ne "none"} { - set bodytext [punk::lib::undent [punk::ansi::untabify -with $untabify -stops $tw $bodytext]] + #set bodytext [punk::lib::undent [punk::ansi::untabify -with $untabify -stops $tw $bodytext]] + set bodytext [punk::ansi::untabify -with $untabify -stops $tw $bodytext] } - append body [punk::lib::indent $bodytext $indent] + set opt_indent 0 + if {$opt_indent} { + #we generally don't want to indent the body. + #Some text strings are constructed based on specific indentation. + append body [punk::lib::indent $bodytext $indent] + } else { + #no indent - more likely we could run the result (if -syntax none) to regenerate the proc with strings intact regarding their spacing relative to the left margin. + append body $bodytext + } set argl {} @@ -6734,24 +6789,47 @@ y" {return quirkykeyscript} #if {[info default $origin $a defvar]} { # lappend a $defvar #} - set result [nseval $targetns [string map [list %n% $name %a% $a] { - #qualify all command names when running in arbitrary namespace - ::if {[::info default "%n%" "%a%" punk_ns_corp_defvar]} { - ::return [::list default $punk_ns_corp_defvar][::unset punk_ns_corp_defvar] ;#keep the targetns tidy - } else { - ::return [::list none] - } - }]] - if {[lindex $result 0] eq "default"} { - lappend a [lindex $result 1] + + #string map is risky for strange values of $a + #set result [nseval $targetns [string map [list %n% $name %a% $a] { + # #qualify all command names when running in arbitrary namespace + # ::if {[::info default "%n%" "%a%" punk_ns_corp_defvar]} { + # #::return [::list default [::tcl::string::map [::list {"} {\"} \[ {\[]} \] {\]} ] $punk_ns_corp_defvar]][::unset punk_ns_corp_defvar] ;#keep the targetns tidy + # ::return [::list default $punk_ns_corp_defvar][::unset punk_ns_corp_defvar] ;#keep the targetns tidy + # } else { + # ::return [::list none] + # } + #}]] + + #this very odd construct is to avoid using the namespace argument of apply. (handling of *weird/inadvisable* namespaces) + #we use an uplevel from within the apply which runs in the global namespace, (but called via nseval from within targetns) and a result var for 'info default' in the current punk::ns namespace. + #set result [nseval $targetns [list apply [list {procname argname} { + # set has_default [uplevel 1 [list info default $procname $argname ::punk::ns::corp_defvar]] + # if {$has_default} { + # set answer [list default $::punk::ns::corp_defvar] + # } else { + # set answer [list none] + # } + # unset ::punk::ns::corp_defvar + # return $answer + #} ] $name $a]] + #if {[lindex $result 0] eq "default"} { + # lappend a [lindex $result 1] + #} + + set default_info [info_default $targetns $name $a] + if {[dict get $default_info exists]} { + lappend a [dict get $default_info default] } + lappend argl $a } #list proc [nsjoin ${targetns} $name] $argl $body #todo - load highlighters as functions from somewhere set is_highlighted 1 ;# default assumption set lnc [punk::ansi::a+ term-73] - set lnr "\x1b\[m" + #set lnr "\x1b\[m" + set lnr [punk::console::code_a] switch -- $syntax { basic { #rudimentary colourising only diff --git a/src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/tdl-0.1.0.tm b/src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/tdl-0.1.0.tm index 6b1480be..431c979e 100644 --- a/src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/tdl-0.1.0.tm +++ b/src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punk/tdl-0.1.0.tm @@ -50,8 +50,7 @@ namespace eval punk::tdl { # $i invokehidden namespace delete {*}[$i invokehidden namespace children] $i alias unknown apply {{i tag args} { upvar 1 result result - set e [concat [list tag $tag]\ - [lrange $args 0 [expr {([llength $args] & ~1) - 1}]]] + set e [concat [list tag $tag] [lrange $args 0 [expr {([llength $args] & ~1) - 1}]]] if {[llength $args] % 2} { set saved $result set result {} diff --git a/src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punkcheck-0.1.0.tm b/src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punkcheck-0.1.0.tm index c286d765..2d80abcb 100644 --- a/src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punkcheck-0.1.0.tm +++ b/src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/punkcheck-0.1.0.tm @@ -303,9 +303,15 @@ namespace eval punkcheck { set o_targets [lsort -dictionary -increasing $relativepath_targetset] ;#exact sort order not critical - but must be consistent - #set targetdict [my targetset_dict] set record_list [punkcheck::load_records_from_file $punkcheck_file] + + #--------------------------------------------------------------------------- + #load as dict to test for dupes + #set _targetdict [my targetset_dict] + set _targetdict [punkcheck::recordlist::records_as_target_dict $record_list] + #--------------------------------------------------------------------------- + set extractioninfo [punkcheck::recordlist::extract_or_create_fileset_record $o_targets $record_list] set o_fileset_record [dict get $extractioninfo record] set record_list [dict get $extractioninfo recordset] @@ -2085,6 +2091,10 @@ namespace eval punkcheck { foreach rec $record_list { if {[dict get $rec tag] eq "FILEINFO"} { set tgtlist [dict get $rec -targets] + if {[dict exists $result $tgtlist]} { + #todo - warn - duplicate record for same targetlist - shouldn't happen as we should be using get_file_record to find existing records + error "punkcheck::recordlist::records_as_target_dict - multiple records with same targetlist '$tgtlist'" + } dict set result $tgtlist $rec } } @@ -2092,8 +2102,6 @@ namespace eval punkcheck { } - - #will only match if same base was used.. and same targetlist proc get_file_record {targetlist record_list} { set posn 0 @@ -2349,12 +2357,12 @@ namespace eval punkcheck { } #extract new or existing filerecord for path given - #review - locking/concurrency + #REVIEW - locking/concurrency proc extract_or_create_fileset_record {relative_target_paths recordset} { set fetch_record_result [punkcheck::recordlist::get_file_record $relative_target_paths $recordset] set existing_posn [dict get $fetch_record_result position] if {$existing_posn == -1} { - #puts stdout "NO existing record for $relative_target_paths" + puts stdout "punkcheck NO existing record for $relative_target_paths" set isnew 1 set fileset_record [dict create tag FILEINFO -targets $relative_target_paths body {}] } else { diff --git a/src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/shellrun-0.1.1.tm b/src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/shellrun-0.1.1.tm index c3f7ab10..96c578cd 100644 --- a/src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/shellrun-0.1.1.tm +++ b/src/project_layouts/custom/_project/punk.project-0.1/src/bootsupport/modules/shellrun-0.1.1.tm @@ -362,6 +362,7 @@ namespace eval shellrun { } lappend chunklist [list "info" "$c$exitinfo$n"] } elseif {[dict exists $exitinfo error]} { + # -tcl (with error) set c [a+ yellow bold] lappend chunklist [list "info" "${c}error [dict get $exitinfo error]$n"] lappend chunklist [list "info" "errorCode [dict get $exitinfo errorCode]"] @@ -369,7 +370,8 @@ namespace eval shellrun { lappend chunklist [list "info" errorInfo] lappend chunklist [list "stderr" [dict get $exitinfo errorInfo]] } else { - set c [a+ Yellow red bold] + # -tcl (without error) + set c [a+ Green white bold] #lappend chunklist [list "info" "$c$exitinfo$n"] lappend chunklist [list "info" [punk::ansi::ansiwrap_raw $c \x1b\[m "" $exitinfo]] } @@ -511,12 +513,14 @@ namespace eval shellrun { } lappend chunklist [list "info" "$c$exitinfo$n"] } elseif {[dict exists $exitinfo error]} { + # -tcl (with error) set c [a+ yellow bold] lappend chunklist [list "info" "error [dict get $exitinfo error]"] lappend chunklist [list "info" "errorCode [dict get $exitinfo errorCode]"] lappend chunklist [list "info" "errorInfo [list [dict get $exitinfo errorInfo]]"] } else { - set c [a+ Yellow red bold] + # -tcl (without error) + set c [a+ Green white bold] #lappend chunklist [list "info" "$c$exitinfo$n"] lappend chunklist [list "info" [punk::ansi::ansiwrap_raw $c "\x1b\[m" "" $exitinfo]] } diff --git a/src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/overtype-1.7.4.tm b/src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/overtype-1.7.4.tm index 1b71be1f..403e971c 100644 --- a/src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/overtype-1.7.4.tm +++ b/src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/overtype-1.7.4.tm @@ -3280,6 +3280,7 @@ tcl::namespace::eval overtype { set next_stop [lindex $tstops $prev_stop_idx+1] ;#if our tab_column is exactly on a stop, we still want to move to the next stop. set this_tab_width [expr {$next_stop - $tab_column}] ;#diff between two adjacent columns is one. + #insert the tab and the correct number of null columns for the tab expansion. set graphemes [list \t {*}[lrepeat [expr {$this_tab_width -1}] "\u0000"]] priv::render_insertgraphemes $idx $graphemes [lindex $overstacks $idx_over] [lindex $overstacks_gx $idx_over] incr idx $this_tab_width @@ -3594,8 +3595,6 @@ tcl::namespace::eval overtype { #This reflows for each grapheme inserted - but for now this is simpler than trying to handle multiple graphemes at once. priv::render_insertgraphemes $idx [list $ch] [lindex $overstacks $idx_over] [lindex $overstacks_gx $idx_over] incr idx - #don't incr cursor_column - review. - } else { priv::render_addchar $idx $ch [lindex $overstacks $idx_over] [lindex $overstacks_gx $idx_over] $insert_mode incr idx @@ -5598,9 +5597,9 @@ tcl::namespace::eval overtype { #} #-info values 2,3,4 for view modes - if {($opt_returnextra | 3) == $opt_returnextra} { + if {$opt_returnextra & 3} { set viewop VIEWCODES - } elseif {($opt_returnextra | 4) == $opt_returnextra} { + } elseif {$opt_returnextra & 4} { set viewop VIEWSTYLE } @@ -5622,7 +5621,7 @@ tcl::namespace::eval overtype { } #-info values 9,10,11,12 - if {($opt_returnextra | 8) == $opt_returnextra} { + if {$opt_returnextra & 8} { return [pdict -channel none result] } else { return $result diff --git a/src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/ansi-0.1.1.tm b/src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/ansi-0.1.1.tm index 7e7bc823..f9997649 100644 --- a/src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/ansi-0.1.1.tm +++ b/src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/ansi-0.1.1.tm @@ -5170,6 +5170,13 @@ Brightblack 100 Brightred 101 Brightgreen 102 Brightyellow 103 Brightblu set c [format %c [expr {$col + 31}]] return \x1bY${r}${c} } + + + #standard vt52 doesn't support color (monochrome displays only) + #Atari and some vt52 emulators may support limited colors - review + #todo - vt52color background vs foreground + #\x1bb foreground. + #\x1bc background. proc vt52color {int} { if {[string is integer -strict $int]} { if {$int < 0 || $int > 15} { @@ -5177,6 +5184,7 @@ Brightblack 100 Brightred 101 Brightgreen 102 Brightyellow 103 Brightblu } } set char [format %c [expr {$int + 31}]] + #foreground and background are the same char - but vt52 has separate modes for fg/bg - so we could just return the char and let caller decide which mode to be in return \x1bb${char} } @@ -6800,12 +6808,14 @@ be as if this was off - ie lone CR. return [dict create textcells $textcells scopes $scopes cellblocks $cellblocks blockwidths $blockwidths] } proc expand_elastic_tabs {textblock {with {" " " "}}} { + lassign $with tabchar spacechar + #temp set tstops [lrange [punk::lib::range 1 200 8] 1 end] + #REVIEW + set computed [_compute_plastic_tabstops $textblock 4] - lassign $with tabchar spacechar - set computed [_compute_plastic_tabstops $textblock 4] set numrows [llength [dict get $computed textcells]] #set numcols [expr {[dict get $computed scopes 0 columncount] - 1}] set cellblocks [dict get $computed cellblocks] diff --git a/src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/args-0.2.1.tm b/src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/args-0.2.1.tm index 0056e9d0..1ff7fd37 100644 --- a/src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/args-0.2.1.tm +++ b/src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/args-0.2.1.tm @@ -10459,7 +10459,12 @@ tcl::namespace::eval punk::args { set ts [Dict_getdef $arginfo -typesynopsis ""] set n [expr {[llength $typelist]-1}] - set name_tail [lrange $argname end-$n end];#if there are enough tail words in the argname to match -types + if {![catch {llength $argname}]} { + set name_tail [lrange $argname end-$n end];#if there are enough tail words in the argname to match -types + } else { + #argname is not a valid Tcl list - so we can't take tail words from it for display hints + set name_tail [list $argname] + } set clause "" if {$ts ne ""} { set tp_displaylist $ts @@ -10468,7 +10473,7 @@ tcl::namespace::eval punk::args { } foreach typespec $typelist td $tp_displaylist elementname $name_tail { - #elementname will commonly be empty + #elementname will commonly be empty after first iteration if {[string match {\?*\?} $typespec]} { set tp [string range $typespec 1 end-1] set member_optional 1 diff --git a/src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/console-0.1.1.tm b/src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/console-0.1.1.tm index 9c378b1a..5271bbfb 100644 --- a/src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/console-0.1.1.tm +++ b/src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/console-0.1.1.tm @@ -784,50 +784,34 @@ namespace eval punk::console { tailcall ::punk::ansi::a? {*}$args } } - #proc a? {args} { - # #stdout - # variable ansi_wanted - # if {$ansi_wanted <= 0} { - # puts -nonewline [punk::ansi::ansistripraw [::punk::ansi::a?]] - # } else { - # tailcall ansi::a? {*}$args - # } - #} #REVIEW! this needs reworking. #It needs to be clarified as to what ansi off is supposed to do. #Turning ansi off only stops new ansi being generated - but what about codes stored in configurations of existing elements such as tables/frames? #It will stop underlines/bold/reverse as well as SGR colours + #colour off is more specific - it only stops SGR colour codes from being generated - but underlines/bold/reverse will still be generated. #what about ansi movement codes etc? #we already have colour on|off which disables SGR codes in a+ etc as well as stderr/stdout channel transforms proc ansi {{onoff {}}} { variable ansi_wanted if {[string length $onoff]} { - set onoff [string tolower $onoff] - switch -- $onoff { - 1 - - on - - true - - yes { - set ansi_wanted 1 - } - 0 - - off - - false - - no { - set ansi_wanted 0 - punk::ansi::sgr_cache -action clear - } - default { - set ansi_wanted 2 - } - default { - error "punk::console::ansi expected 0|1|on|off|true|false|yes|no|default" - } + if {$onoff eq "default"} { + set ansi_wanted 2 + catch {punk::repl::reset_prompt} + return + } + if {![string is boolean -strict $onoff]} { + error "punk::console::ansi expected a boolean e.g 0|1|on|off|true|false|yes|no" + } + if {$onoff} { + set ansi_wanted 1 + } else { + set ansi_wanted 0 + punk::ansi::sgr_cache -action clear } + catch {punk::repl::reset_prompt} } - catch {punk::repl::reset_prompt} - puts stderr "::punk::console::ansi - use 'colour' command to turn SGR codes on/off" + puts stderr "::punk::console::ansi - use 'colour' command to turn SGR codes on/off (except bold/underline/reverse which are controlled by 'ansi' command)" return [expr {$ansi_wanted}] } @@ -863,8 +847,8 @@ namespace eval punk::console { #test - find a better place to set terminal type variable is_vt52 0 proc vt52 {{onoff {}}} { - #todo - return to colour state beforehand?. support 0-15 vt52 colours? - #we shouldn't have to trun off colour to enter vt52 - we should make punk::console emit correct codes + #todo - return to colour state beforehand?. support 0-15 vt52 colours? (ATARI and some emulators - not original vt52) + #we shouldn't have to turn off colour to enter vt52 - we should make punk::console emit correct codes variable is_vt52 if {$onoff eq ""} { return $is_vt52 @@ -2873,7 +2857,7 @@ namespace eval punk::console { return 0 } set existing_mode [twapi::GetConsoleMode $h_out] - if {[expr {$existing_mode & 4}]} { + if {$existing_mode & 4} { #virtual terminal processing happens to be enabled - so it's supported return 1 } diff --git a/src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/mix/base-0.1.tm b/src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/mix/base-0.1.tm index ea9fc85f..eb1e1c5e 100644 --- a/src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/mix/base-0.1.tm +++ b/src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/mix/base-0.1.tm @@ -682,7 +682,7 @@ namespace eval punk::mix::base { cd $base ;#cd is process-wide.. keep cd in effect for as small a scope as possible. (review for thread issues) #temp emission to stdout.. todo - repl telemetry channel - puts stdout "cksum_path: creating temporary tar archive for $path" + puts stdout "\ncksum_path: creating temporary tar archive for $path" puts -nonewline stdout " at: $archivename ..." set tsstart [clock millis] if {[set tarpath [auto_execok tar]] ne ""} { @@ -709,7 +709,7 @@ namespace eval punk::mix::base { set sizeinfo "(file type $ftype - tarred size [punk::lib::format_number [file size $archivename]] bytes)" } set tsstart [clock millis] - puts -nonewline stdout "cksum_path: calculating cksum using $opt_cksum_algorithm for $target $sizeinfo ... " + puts -nonewline stdout "\ncksum_path: calculating cksum using $opt_cksum_algorithm for $target $sizeinfo ... " set cksum [{*}$cksum_command $archivename] set tsend [clock millis] set ms [expr {$tsend - $tsstart}] diff --git a/src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/mix/cli-0.3.1.tm b/src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/mix/cli-0.3.1.tm index dd2f5abd..05e8724f 100644 --- a/src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/mix/cli-0.3.1.tm +++ b/src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/mix/cli-0.3.1.tm @@ -599,6 +599,12 @@ namespace eval punk::mix::cli { if {[string match "foobar" $current_source_dir]} { set is_interesting 1 } + + #debug for issues on non-windows platforms. + if {$::tcl_platform(platform) ne "windows"} { + set is_interesting 1 + } + if {$is_interesting} { puts "build_modules_from_source_to_base >>> module $current_source_dir/$modpath" } @@ -609,10 +615,13 @@ namespace eval punk::mix::cli { #split_modulename_version version part will be empty if not valid tcl version #last segment doesn't look even slightly versiony - fail. puts stderr "ERROR: Unable to confirm file $current_source_dir/$modpath is a reasonably versioned .tm module - ABORTING." + flush stderr + after 1000 exit 1 } switch -- $modtype { pod { + puts -nonewline stderr "p-" #basename still contains leading #modpod- if {[string match #modpod-* $basename]} { set basename [string range $basename 8 end] @@ -689,6 +698,7 @@ namespace eval punk::mix::cli { puts stdout "$current_source_dir/$modpath" puts stdout "to:" puts stdout "$podtree_copy" + flush stdout file copy $current_source_dir/$modpath $podtree_copy if {$tmfile_versionsegment eq $magicversion} { set tmfile $buildfolder/#modpod-$basename-$module_build_version/$basename-$magicversion.tm @@ -809,6 +819,7 @@ namespace eval punk::mix::cli { } } tarjar { + puts -nonewline stderr "t-" #maint - overall code structure same as pod - refactor? #basename may still contain #tarjar- #to be obsoleted - update modpod to (optionally) use vfs::tar ? @@ -992,6 +1003,7 @@ namespace eval punk::mix::cli { } file { + puts -nonewline stderr "f-" set m $modpath if {$tmfile_versionsegment eq $magicversion} { #set basename [join [lrange $fileparts 0 end-1] -] diff --git a/src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/ns-0.1.0.tm b/src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/ns-0.1.0.tm index 6fcb3aa3..dc8c765c 100644 --- a/src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/ns-0.1.0.tm +++ b/src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/ns-0.1.0.tm @@ -2671,16 +2671,20 @@ y" {return quirkykeyscript} foreach {tgt_cmd ns nscmd} $resolved_targets { puts "tracing target: $tgt_cmd whilst running: $origin $arglist" - ::tcl::namespace::eval $ns [list ::trace add execution $nscmd enter [list ::punk::ns::_cmdtrace_enter ::punk::ns::linedict $tgt_cmd]] - ::tcl::namespace::eval $ns [list ::trace add execution $nscmd enterstep [list ::punk::ns::_cmdtrace_enterstep ::punk::ns::linedict $tgt_cmd]] - ::tcl::namespace::eval $ns [list ::trace add execution $nscmd leave [list ::punk::ns::_cmdtrace_leave ::punk::ns::linedict $tgt_cmd]] + #::tcl::namespace::eval $ns [list ::trace add execution $nscmd enter [list ::punk::ns::_cmdtrace_enter ::punk::ns::linedict $tgt_cmd]] + #::tcl::namespace::eval $ns [list ::trace add execution $nscmd enterstep [list ::punk::ns::_cmdtrace_enterstep ::punk::ns::linedict $tgt_cmd]] + #::tcl::namespace::eval $ns [list ::trace add execution $nscmd leave [list ::punk::ns::_cmdtrace_leave ::punk::ns::linedict $tgt_cmd]] + nseval $ns [list ::trace add execution $nscmd enter [list ::punk::ns::_cmdtrace_enter ::punk::ns::linedict $tgt_cmd]] + nseval $ns [list ::trace add execution $nscmd enterstep [list ::punk::ns::_cmdtrace_enterstep ::punk::ns::linedict $tgt_cmd]] + nseval $ns [list ::trace add execution $nscmd leave [list ::punk::ns::_cmdtrace_leave ::punk::ns::linedict $tgt_cmd]] } try { #uplevel 1 [list $origin {*}$arglist] set _cmdtrace_disabled false - ::tcl::namespace::eval $origin_ns [list $origin_nscmd {*}$arglist] + #::tcl::namespace::eval $origin_ns [list $origin_nscmd {*}$arglist] + nseval $origin_ns [list $origin_nscmd {*}$arglist] } trap {} {errMsg errOptions} { set _cmdtrace_disabled true #(even a puts can involve function calls - e.g in contexts where there are stacked channels) @@ -2689,9 +2693,12 @@ y" {return quirkykeyscript} } finally { set _cmdtrace_disabled true foreach {tgt_cmd ns nscmd} $resolved_targets { - ::tcl::namespace::eval $ns [list ::trace remove execution $nscmd enterstep [list ::punk::ns::_cmdtrace_enterstep ::punk::ns::linedict $tgt_cmd]] - ::tcl::namespace::eval $ns [list ::trace remove execution $nscmd enter [list ::punk::ns::_cmdtrace_enter ::punk::ns::linedict $tgt_cmd]] - ::tcl::namespace::eval $ns [list ::trace remove execution $nscmd leave [list ::punk::ns::_cmdtrace_leave ::punk::ns::linedict $tgt_cmd]] + #::tcl::namespace::eval $ns [list ::trace remove execution $nscmd enterstep [list ::punk::ns::_cmdtrace_enterstep ::punk::ns::linedict $tgt_cmd]] + #::tcl::namespace::eval $ns [list ::trace remove execution $nscmd enter [list ::punk::ns::_cmdtrace_enter ::punk::ns::linedict $tgt_cmd]] + #::tcl::namespace::eval $ns [list ::trace remove execution $nscmd leave [list ::punk::ns::_cmdtrace_leave ::punk::ns::linedict $tgt_cmd]] + nseval $ns [list ::trace remove execution $nscmd enterstep [list ::punk::ns::_cmdtrace_enterstep ::punk::ns::linedict $tgt_cmd]] + nseval $ns [list ::trace remove execution $nscmd enter [list ::punk::ns::_cmdtrace_enter ::punk::ns::linedict $tgt_cmd]] + nseval $ns [list ::trace remove execution $nscmd leave [list ::punk::ns::_cmdtrace_leave ::punk::ns::linedict $tgt_cmd]] } } @@ -4168,6 +4175,21 @@ y" {return quirkykeyscript} return [dict create origin $origin origintype $origintype which $resolved whichtype $whichtype] } + proc info_default {targetns targetproc targetarg} { + #this *very odd* construct is to avoid using the namespace argument of apply. (handling of *weird/inadvisable* namespaces) + #we use an uplevel from within the apply which runs in the global namespace, (but called via nseval from within targetns) and a result var for 'info default' in the current punk::ns namespace. + nseval $targetns [list apply [list {procname argname} { + set has_default [uplevel 1 [list info default $procname $argname ::punk::ns::corp_defvar]] + if {$has_default} { + set answer [dict create exists 1 default $::punk::ns::corp_defvar] + } else { + set answer [dict create exists 0 default {}] + } + unset ::punk::ns::corp_defvar + return $answer + } ] $targetproc $targetarg] + } + #review - should be in punk::args? proc generate_autodef {args} { set cmd [lindex $args 0] @@ -4659,7 +4681,10 @@ y" {return quirkykeyscript} #we can't use 'info args :::' - tcl won't find it set ns [nsprefix $origin] set nscmd [nstail $origin] - set infoargs [namespace eval $ns [list ::tcl::info::args $nscmd]] + #set infoargs [namespace eval $ns [list ::tcl::info::args $nscmd]] + set infoargs [nseval $ns [list ::tcl::info::args $nscmd]] + + set argdef [punk::lib::tstr -return string { @id -id "${$autoid}" @cmd -help\ @@ -4673,15 +4698,33 @@ y" {return quirkykeyscript} incr i #we need a varname for ::tcl::info::default - but as we need to run it in the ns we have to be careful, #or we risk variable collisions/pollution of the target ns. - set default_info [apply [list {procname argname} { - if {[::tcl::info::default $procname $argname defaultval]} { - return [dict create exists 1 default $defaultval] - } else { - return [dict create exists 0 default ""] - } - } $ns] $nscmd $a] + + #odd + #set default_info [apply [list {procname argname} { + # if {[::tcl::info::default $procname $argname defaultval]} { + # return [dict create exists 1 default $defaultval] + # } else { + # return [dict create exists 0 default ""] + # } + #} $ns] $nscmd $a] + set default_info [info_default $ns $nscmd $a] + + if {[dict get $default_info exists]} { - append argdef \n "$a -type unknown -default \"[dict get $default_info default]\"" + #We have to be careful if default value is something like a single double-quote. + #e.g proc ::csv::join {values {sepChar ,} {delChar {"}} {delMode auto}} {...} + + #building it as a string is tricky, we need to quote it, but not if already quoted + #- this attempt is broken + # #append argdef \n "$a -type unknown -default \"[dict get $default_info default]\"" + # #set default_info [string map [list \{ \\{ \} \\}] $default_info] + # #append argdef \n "$a -type unknown -default {" [dict get $default_info default] "}" + + #building it as a list seems likely to be more robust. + #(we parse each line as a list in punk::args) + #REVIEW + set line [list $a -type unknown -default [dict get $default_info default]] + append argdef \n $line } else { if {$i == [llength $infoargs]-1 && $a eq "args"} { #we need to use a name that doesn't collide with any previous arguments @@ -4705,7 +4748,9 @@ y" {return quirkykeyscript} } append argdef \n "$args_element -type unknown -multiple 1 -optional 1" } else { - append argdef \n "$a -type unknown" + set line [list $a -type unknown] ;#list protect for odd names of arguments + append argdef \n $line + #append argdef \n "$a -type unknown" } } } @@ -6635,7 +6680,8 @@ y" {return quirkykeyscript} set untabify [dict get $opts -untabify] set do_ln [expr {[dict exists $received --line-number]}] #thanks to Richard Suchenwirth for the original - wiki.tcl-lang.org/page/corp - #Note: modified here to support aliases and relative/absolute name (with respect to namespace .ie ::name vs name) + #Note: modified and much-extended here to support aliases and relative/absolute name (with respect to namespace .ie ::name vs name) + if {[info exists punk::console::tabwidth]} { set tw $::punk::console::tabwidth } else { @@ -6722,10 +6768,19 @@ y" {return quirkykeyscript} #set bodytext [punk::lib::undent [textutil::untabify2 $bodytext $tw]] if {$untabify ne "none"} { - set bodytext [punk::lib::undent [punk::ansi::untabify -with $untabify -stops $tw $bodytext]] + #set bodytext [punk::lib::undent [punk::ansi::untabify -with $untabify -stops $tw $bodytext]] + set bodytext [punk::ansi::untabify -with $untabify -stops $tw $bodytext] } - append body [punk::lib::indent $bodytext $indent] + set opt_indent 0 + if {$opt_indent} { + #we generally don't want to indent the body. + #Some text strings are constructed based on specific indentation. + append body [punk::lib::indent $bodytext $indent] + } else { + #no indent - more likely we could run the result (if -syntax none) to regenerate the proc with strings intact regarding their spacing relative to the left margin. + append body $bodytext + } set argl {} @@ -6734,24 +6789,47 @@ y" {return quirkykeyscript} #if {[info default $origin $a defvar]} { # lappend a $defvar #} - set result [nseval $targetns [string map [list %n% $name %a% $a] { - #qualify all command names when running in arbitrary namespace - ::if {[::info default "%n%" "%a%" punk_ns_corp_defvar]} { - ::return [::list default $punk_ns_corp_defvar][::unset punk_ns_corp_defvar] ;#keep the targetns tidy - } else { - ::return [::list none] - } - }]] - if {[lindex $result 0] eq "default"} { - lappend a [lindex $result 1] + + #string map is risky for strange values of $a + #set result [nseval $targetns [string map [list %n% $name %a% $a] { + # #qualify all command names when running in arbitrary namespace + # ::if {[::info default "%n%" "%a%" punk_ns_corp_defvar]} { + # #::return [::list default [::tcl::string::map [::list {"} {\"} \[ {\[]} \] {\]} ] $punk_ns_corp_defvar]][::unset punk_ns_corp_defvar] ;#keep the targetns tidy + # ::return [::list default $punk_ns_corp_defvar][::unset punk_ns_corp_defvar] ;#keep the targetns tidy + # } else { + # ::return [::list none] + # } + #}]] + + #this very odd construct is to avoid using the namespace argument of apply. (handling of *weird/inadvisable* namespaces) + #we use an uplevel from within the apply which runs in the global namespace, (but called via nseval from within targetns) and a result var for 'info default' in the current punk::ns namespace. + #set result [nseval $targetns [list apply [list {procname argname} { + # set has_default [uplevel 1 [list info default $procname $argname ::punk::ns::corp_defvar]] + # if {$has_default} { + # set answer [list default $::punk::ns::corp_defvar] + # } else { + # set answer [list none] + # } + # unset ::punk::ns::corp_defvar + # return $answer + #} ] $name $a]] + #if {[lindex $result 0] eq "default"} { + # lappend a [lindex $result 1] + #} + + set default_info [info_default $targetns $name $a] + if {[dict get $default_info exists]} { + lappend a [dict get $default_info default] } + lappend argl $a } #list proc [nsjoin ${targetns} $name] $argl $body #todo - load highlighters as functions from somewhere set is_highlighted 1 ;# default assumption set lnc [punk::ansi::a+ term-73] - set lnr "\x1b\[m" + #set lnr "\x1b\[m" + set lnr [punk::console::code_a] switch -- $syntax { basic { #rudimentary colourising only diff --git a/src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/tdl-0.1.0.tm b/src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/tdl-0.1.0.tm index 6b1480be..431c979e 100644 --- a/src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/tdl-0.1.0.tm +++ b/src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punk/tdl-0.1.0.tm @@ -50,8 +50,7 @@ namespace eval punk::tdl { # $i invokehidden namespace delete {*}[$i invokehidden namespace children] $i alias unknown apply {{i tag args} { upvar 1 result result - set e [concat [list tag $tag]\ - [lrange $args 0 [expr {([llength $args] & ~1) - 1}]]] + set e [concat [list tag $tag] [lrange $args 0 [expr {([llength $args] & ~1) - 1}]]] if {[llength $args] % 2} { set saved $result set result {} diff --git a/src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punkcheck-0.1.0.tm b/src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punkcheck-0.1.0.tm index c286d765..2d80abcb 100644 --- a/src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punkcheck-0.1.0.tm +++ b/src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/punkcheck-0.1.0.tm @@ -303,9 +303,15 @@ namespace eval punkcheck { set o_targets [lsort -dictionary -increasing $relativepath_targetset] ;#exact sort order not critical - but must be consistent - #set targetdict [my targetset_dict] set record_list [punkcheck::load_records_from_file $punkcheck_file] + + #--------------------------------------------------------------------------- + #load as dict to test for dupes + #set _targetdict [my targetset_dict] + set _targetdict [punkcheck::recordlist::records_as_target_dict $record_list] + #--------------------------------------------------------------------------- + set extractioninfo [punkcheck::recordlist::extract_or_create_fileset_record $o_targets $record_list] set o_fileset_record [dict get $extractioninfo record] set record_list [dict get $extractioninfo recordset] @@ -2085,6 +2091,10 @@ namespace eval punkcheck { foreach rec $record_list { if {[dict get $rec tag] eq "FILEINFO"} { set tgtlist [dict get $rec -targets] + if {[dict exists $result $tgtlist]} { + #todo - warn - duplicate record for same targetlist - shouldn't happen as we should be using get_file_record to find existing records + error "punkcheck::recordlist::records_as_target_dict - multiple records with same targetlist '$tgtlist'" + } dict set result $tgtlist $rec } } @@ -2092,8 +2102,6 @@ namespace eval punkcheck { } - - #will only match if same base was used.. and same targetlist proc get_file_record {targetlist record_list} { set posn 0 @@ -2349,12 +2357,12 @@ namespace eval punkcheck { } #extract new or existing filerecord for path given - #review - locking/concurrency + #REVIEW - locking/concurrency proc extract_or_create_fileset_record {relative_target_paths recordset} { set fetch_record_result [punkcheck::recordlist::get_file_record $relative_target_paths $recordset] set existing_posn [dict get $fetch_record_result position] if {$existing_posn == -1} { - #puts stdout "NO existing record for $relative_target_paths" + puts stdout "punkcheck NO existing record for $relative_target_paths" set isnew 1 set fileset_record [dict create tag FILEINFO -targets $relative_target_paths body {}] } else { diff --git a/src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/shellrun-0.1.1.tm b/src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/shellrun-0.1.1.tm index c3f7ab10..96c578cd 100644 --- a/src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/shellrun-0.1.1.tm +++ b/src/project_layouts/custom/_project/punk.shell-0.1/src/bootsupport/modules/shellrun-0.1.1.tm @@ -362,6 +362,7 @@ namespace eval shellrun { } lappend chunklist [list "info" "$c$exitinfo$n"] } elseif {[dict exists $exitinfo error]} { + # -tcl (with error) set c [a+ yellow bold] lappend chunklist [list "info" "${c}error [dict get $exitinfo error]$n"] lappend chunklist [list "info" "errorCode [dict get $exitinfo errorCode]"] @@ -369,7 +370,8 @@ namespace eval shellrun { lappend chunklist [list "info" errorInfo] lappend chunklist [list "stderr" [dict get $exitinfo errorInfo]] } else { - set c [a+ Yellow red bold] + # -tcl (without error) + set c [a+ Green white bold] #lappend chunklist [list "info" "$c$exitinfo$n"] lappend chunklist [list "info" [punk::ansi::ansiwrap_raw $c \x1b\[m "" $exitinfo]] } @@ -511,12 +513,14 @@ namespace eval shellrun { } lappend chunklist [list "info" "$c$exitinfo$n"] } elseif {[dict exists $exitinfo error]} { + # -tcl (with error) set c [a+ yellow bold] lappend chunklist [list "info" "error [dict get $exitinfo error]"] lappend chunklist [list "info" "errorCode [dict get $exitinfo errorCode]"] lappend chunklist [list "info" "errorInfo [list [dict get $exitinfo errorInfo]]"] } else { - set c [a+ Yellow red bold] + # -tcl (without error) + set c [a+ Green white bold] #lappend chunklist [list "info" "$c$exitinfo$n"] lappend chunklist [list "info" [punk::ansi::ansiwrap_raw $c "\x1b\[m" "" $exitinfo]] } diff --git a/src/vfs/_vfscommon.vfs/modules/overtype-1.7.4.tm b/src/vfs/_vfscommon.vfs/modules/overtype-1.7.4.tm index 1b71be1f..403e971c 100644 --- a/src/vfs/_vfscommon.vfs/modules/overtype-1.7.4.tm +++ b/src/vfs/_vfscommon.vfs/modules/overtype-1.7.4.tm @@ -3280,6 +3280,7 @@ tcl::namespace::eval overtype { set next_stop [lindex $tstops $prev_stop_idx+1] ;#if our tab_column is exactly on a stop, we still want to move to the next stop. set this_tab_width [expr {$next_stop - $tab_column}] ;#diff between two adjacent columns is one. + #insert the tab and the correct number of null columns for the tab expansion. set graphemes [list \t {*}[lrepeat [expr {$this_tab_width -1}] "\u0000"]] priv::render_insertgraphemes $idx $graphemes [lindex $overstacks $idx_over] [lindex $overstacks_gx $idx_over] incr idx $this_tab_width @@ -3594,8 +3595,6 @@ tcl::namespace::eval overtype { #This reflows for each grapheme inserted - but for now this is simpler than trying to handle multiple graphemes at once. priv::render_insertgraphemes $idx [list $ch] [lindex $overstacks $idx_over] [lindex $overstacks_gx $idx_over] incr idx - #don't incr cursor_column - review. - } else { priv::render_addchar $idx $ch [lindex $overstacks $idx_over] [lindex $overstacks_gx $idx_over] $insert_mode incr idx @@ -5598,9 +5597,9 @@ tcl::namespace::eval overtype { #} #-info values 2,3,4 for view modes - if {($opt_returnextra | 3) == $opt_returnextra} { + if {$opt_returnextra & 3} { set viewop VIEWCODES - } elseif {($opt_returnextra | 4) == $opt_returnextra} { + } elseif {$opt_returnextra & 4} { set viewop VIEWSTYLE } @@ -5622,7 +5621,7 @@ tcl::namespace::eval overtype { } #-info values 9,10,11,12 - if {($opt_returnextra | 8) == $opt_returnextra} { + if {$opt_returnextra & 8} { return [pdict -channel none result] } else { return $result diff --git a/src/vfs/_vfscommon.vfs/modules/punk/ansi-0.1.1.tm b/src/vfs/_vfscommon.vfs/modules/punk/ansi-0.1.1.tm index 7e7bc823..f9997649 100644 --- a/src/vfs/_vfscommon.vfs/modules/punk/ansi-0.1.1.tm +++ b/src/vfs/_vfscommon.vfs/modules/punk/ansi-0.1.1.tm @@ -5170,6 +5170,13 @@ Brightblack 100 Brightred 101 Brightgreen 102 Brightyellow 103 Brightblu set c [format %c [expr {$col + 31}]] return \x1bY${r}${c} } + + + #standard vt52 doesn't support color (monochrome displays only) + #Atari and some vt52 emulators may support limited colors - review + #todo - vt52color background vs foreground + #\x1bb foreground. + #\x1bc background. proc vt52color {int} { if {[string is integer -strict $int]} { if {$int < 0 || $int > 15} { @@ -5177,6 +5184,7 @@ Brightblack 100 Brightred 101 Brightgreen 102 Brightyellow 103 Brightblu } } set char [format %c [expr {$int + 31}]] + #foreground and background are the same char - but vt52 has separate modes for fg/bg - so we could just return the char and let caller decide which mode to be in return \x1bb${char} } @@ -6800,12 +6808,14 @@ be as if this was off - ie lone CR. return [dict create textcells $textcells scopes $scopes cellblocks $cellblocks blockwidths $blockwidths] } proc expand_elastic_tabs {textblock {with {" " " "}}} { + lassign $with tabchar spacechar + #temp set tstops [lrange [punk::lib::range 1 200 8] 1 end] + #REVIEW + set computed [_compute_plastic_tabstops $textblock 4] - lassign $with tabchar spacechar - set computed [_compute_plastic_tabstops $textblock 4] set numrows [llength [dict get $computed textcells]] #set numcols [expr {[dict get $computed scopes 0 columncount] - 1}] set cellblocks [dict get $computed cellblocks] diff --git a/src/vfs/_vfscommon.vfs/modules/punk/args-0.2.1.tm b/src/vfs/_vfscommon.vfs/modules/punk/args-0.2.1.tm index 0056e9d0..1ff7fd37 100644 --- a/src/vfs/_vfscommon.vfs/modules/punk/args-0.2.1.tm +++ b/src/vfs/_vfscommon.vfs/modules/punk/args-0.2.1.tm @@ -10459,7 +10459,12 @@ tcl::namespace::eval punk::args { set ts [Dict_getdef $arginfo -typesynopsis ""] set n [expr {[llength $typelist]-1}] - set name_tail [lrange $argname end-$n end];#if there are enough tail words in the argname to match -types + if {![catch {llength $argname}]} { + set name_tail [lrange $argname end-$n end];#if there are enough tail words in the argname to match -types + } else { + #argname is not a valid Tcl list - so we can't take tail words from it for display hints + set name_tail [list $argname] + } set clause "" if {$ts ne ""} { set tp_displaylist $ts @@ -10468,7 +10473,7 @@ tcl::namespace::eval punk::args { } foreach typespec $typelist td $tp_displaylist elementname $name_tail { - #elementname will commonly be empty + #elementname will commonly be empty after first iteration if {[string match {\?*\?} $typespec]} { set tp [string range $typespec 1 end-1] set member_optional 1 diff --git a/src/vfs/_vfscommon.vfs/modules/punk/console-0.1.1.tm b/src/vfs/_vfscommon.vfs/modules/punk/console-0.1.1.tm index 9c378b1a..5271bbfb 100644 --- a/src/vfs/_vfscommon.vfs/modules/punk/console-0.1.1.tm +++ b/src/vfs/_vfscommon.vfs/modules/punk/console-0.1.1.tm @@ -784,50 +784,34 @@ namespace eval punk::console { tailcall ::punk::ansi::a? {*}$args } } - #proc a? {args} { - # #stdout - # variable ansi_wanted - # if {$ansi_wanted <= 0} { - # puts -nonewline [punk::ansi::ansistripraw [::punk::ansi::a?]] - # } else { - # tailcall ansi::a? {*}$args - # } - #} #REVIEW! this needs reworking. #It needs to be clarified as to what ansi off is supposed to do. #Turning ansi off only stops new ansi being generated - but what about codes stored in configurations of existing elements such as tables/frames? #It will stop underlines/bold/reverse as well as SGR colours + #colour off is more specific - it only stops SGR colour codes from being generated - but underlines/bold/reverse will still be generated. #what about ansi movement codes etc? #we already have colour on|off which disables SGR codes in a+ etc as well as stderr/stdout channel transforms proc ansi {{onoff {}}} { variable ansi_wanted if {[string length $onoff]} { - set onoff [string tolower $onoff] - switch -- $onoff { - 1 - - on - - true - - yes { - set ansi_wanted 1 - } - 0 - - off - - false - - no { - set ansi_wanted 0 - punk::ansi::sgr_cache -action clear - } - default { - set ansi_wanted 2 - } - default { - error "punk::console::ansi expected 0|1|on|off|true|false|yes|no|default" - } + if {$onoff eq "default"} { + set ansi_wanted 2 + catch {punk::repl::reset_prompt} + return + } + if {![string is boolean -strict $onoff]} { + error "punk::console::ansi expected a boolean e.g 0|1|on|off|true|false|yes|no" + } + if {$onoff} { + set ansi_wanted 1 + } else { + set ansi_wanted 0 + punk::ansi::sgr_cache -action clear } + catch {punk::repl::reset_prompt} } - catch {punk::repl::reset_prompt} - puts stderr "::punk::console::ansi - use 'colour' command to turn SGR codes on/off" + puts stderr "::punk::console::ansi - use 'colour' command to turn SGR codes on/off (except bold/underline/reverse which are controlled by 'ansi' command)" return [expr {$ansi_wanted}] } @@ -863,8 +847,8 @@ namespace eval punk::console { #test - find a better place to set terminal type variable is_vt52 0 proc vt52 {{onoff {}}} { - #todo - return to colour state beforehand?. support 0-15 vt52 colours? - #we shouldn't have to trun off colour to enter vt52 - we should make punk::console emit correct codes + #todo - return to colour state beforehand?. support 0-15 vt52 colours? (ATARI and some emulators - not original vt52) + #we shouldn't have to turn off colour to enter vt52 - we should make punk::console emit correct codes variable is_vt52 if {$onoff eq ""} { return $is_vt52 @@ -2873,7 +2857,7 @@ namespace eval punk::console { return 0 } set existing_mode [twapi::GetConsoleMode $h_out] - if {[expr {$existing_mode & 4}]} { + if {$existing_mode & 4} { #virtual terminal processing happens to be enabled - so it's supported return 1 } diff --git a/src/vfs/_vfscommon.vfs/modules/punk/mix/base-0.1.tm b/src/vfs/_vfscommon.vfs/modules/punk/mix/base-0.1.tm index ea9fc85f..eb1e1c5e 100644 --- a/src/vfs/_vfscommon.vfs/modules/punk/mix/base-0.1.tm +++ b/src/vfs/_vfscommon.vfs/modules/punk/mix/base-0.1.tm @@ -682,7 +682,7 @@ namespace eval punk::mix::base { cd $base ;#cd is process-wide.. keep cd in effect for as small a scope as possible. (review for thread issues) #temp emission to stdout.. todo - repl telemetry channel - puts stdout "cksum_path: creating temporary tar archive for $path" + puts stdout "\ncksum_path: creating temporary tar archive for $path" puts -nonewline stdout " at: $archivename ..." set tsstart [clock millis] if {[set tarpath [auto_execok tar]] ne ""} { @@ -709,7 +709,7 @@ namespace eval punk::mix::base { set sizeinfo "(file type $ftype - tarred size [punk::lib::format_number [file size $archivename]] bytes)" } set tsstart [clock millis] - puts -nonewline stdout "cksum_path: calculating cksum using $opt_cksum_algorithm for $target $sizeinfo ... " + puts -nonewline stdout "\ncksum_path: calculating cksum using $opt_cksum_algorithm for $target $sizeinfo ... " set cksum [{*}$cksum_command $archivename] set tsend [clock millis] set ms [expr {$tsend - $tsstart}] diff --git a/src/vfs/_vfscommon.vfs/modules/punk/mix/cli-0.3.1.tm b/src/vfs/_vfscommon.vfs/modules/punk/mix/cli-0.3.1.tm index dd2f5abd..05e8724f 100644 --- a/src/vfs/_vfscommon.vfs/modules/punk/mix/cli-0.3.1.tm +++ b/src/vfs/_vfscommon.vfs/modules/punk/mix/cli-0.3.1.tm @@ -599,6 +599,12 @@ namespace eval punk::mix::cli { if {[string match "foobar" $current_source_dir]} { set is_interesting 1 } + + #debug for issues on non-windows platforms. + if {$::tcl_platform(platform) ne "windows"} { + set is_interesting 1 + } + if {$is_interesting} { puts "build_modules_from_source_to_base >>> module $current_source_dir/$modpath" } @@ -609,10 +615,13 @@ namespace eval punk::mix::cli { #split_modulename_version version part will be empty if not valid tcl version #last segment doesn't look even slightly versiony - fail. puts stderr "ERROR: Unable to confirm file $current_source_dir/$modpath is a reasonably versioned .tm module - ABORTING." + flush stderr + after 1000 exit 1 } switch -- $modtype { pod { + puts -nonewline stderr "p-" #basename still contains leading #modpod- if {[string match #modpod-* $basename]} { set basename [string range $basename 8 end] @@ -689,6 +698,7 @@ namespace eval punk::mix::cli { puts stdout "$current_source_dir/$modpath" puts stdout "to:" puts stdout "$podtree_copy" + flush stdout file copy $current_source_dir/$modpath $podtree_copy if {$tmfile_versionsegment eq $magicversion} { set tmfile $buildfolder/#modpod-$basename-$module_build_version/$basename-$magicversion.tm @@ -809,6 +819,7 @@ namespace eval punk::mix::cli { } } tarjar { + puts -nonewline stderr "t-" #maint - overall code structure same as pod - refactor? #basename may still contain #tarjar- #to be obsoleted - update modpod to (optionally) use vfs::tar ? @@ -992,6 +1003,7 @@ namespace eval punk::mix::cli { } file { + puts -nonewline stderr "f-" set m $modpath if {$tmfile_versionsegment eq $magicversion} { #set basename [join [lrange $fileparts 0 end-1] -] diff --git a/src/vfs/_vfscommon.vfs/modules/punk/ns-0.1.0.tm b/src/vfs/_vfscommon.vfs/modules/punk/ns-0.1.0.tm index 6fcb3aa3..dc8c765c 100644 --- a/src/vfs/_vfscommon.vfs/modules/punk/ns-0.1.0.tm +++ b/src/vfs/_vfscommon.vfs/modules/punk/ns-0.1.0.tm @@ -2671,16 +2671,20 @@ y" {return quirkykeyscript} foreach {tgt_cmd ns nscmd} $resolved_targets { puts "tracing target: $tgt_cmd whilst running: $origin $arglist" - ::tcl::namespace::eval $ns [list ::trace add execution $nscmd enter [list ::punk::ns::_cmdtrace_enter ::punk::ns::linedict $tgt_cmd]] - ::tcl::namespace::eval $ns [list ::trace add execution $nscmd enterstep [list ::punk::ns::_cmdtrace_enterstep ::punk::ns::linedict $tgt_cmd]] - ::tcl::namespace::eval $ns [list ::trace add execution $nscmd leave [list ::punk::ns::_cmdtrace_leave ::punk::ns::linedict $tgt_cmd]] + #::tcl::namespace::eval $ns [list ::trace add execution $nscmd enter [list ::punk::ns::_cmdtrace_enter ::punk::ns::linedict $tgt_cmd]] + #::tcl::namespace::eval $ns [list ::trace add execution $nscmd enterstep [list ::punk::ns::_cmdtrace_enterstep ::punk::ns::linedict $tgt_cmd]] + #::tcl::namespace::eval $ns [list ::trace add execution $nscmd leave [list ::punk::ns::_cmdtrace_leave ::punk::ns::linedict $tgt_cmd]] + nseval $ns [list ::trace add execution $nscmd enter [list ::punk::ns::_cmdtrace_enter ::punk::ns::linedict $tgt_cmd]] + nseval $ns [list ::trace add execution $nscmd enterstep [list ::punk::ns::_cmdtrace_enterstep ::punk::ns::linedict $tgt_cmd]] + nseval $ns [list ::trace add execution $nscmd leave [list ::punk::ns::_cmdtrace_leave ::punk::ns::linedict $tgt_cmd]] } try { #uplevel 1 [list $origin {*}$arglist] set _cmdtrace_disabled false - ::tcl::namespace::eval $origin_ns [list $origin_nscmd {*}$arglist] + #::tcl::namespace::eval $origin_ns [list $origin_nscmd {*}$arglist] + nseval $origin_ns [list $origin_nscmd {*}$arglist] } trap {} {errMsg errOptions} { set _cmdtrace_disabled true #(even a puts can involve function calls - e.g in contexts where there are stacked channels) @@ -2689,9 +2693,12 @@ y" {return quirkykeyscript} } finally { set _cmdtrace_disabled true foreach {tgt_cmd ns nscmd} $resolved_targets { - ::tcl::namespace::eval $ns [list ::trace remove execution $nscmd enterstep [list ::punk::ns::_cmdtrace_enterstep ::punk::ns::linedict $tgt_cmd]] - ::tcl::namespace::eval $ns [list ::trace remove execution $nscmd enter [list ::punk::ns::_cmdtrace_enter ::punk::ns::linedict $tgt_cmd]] - ::tcl::namespace::eval $ns [list ::trace remove execution $nscmd leave [list ::punk::ns::_cmdtrace_leave ::punk::ns::linedict $tgt_cmd]] + #::tcl::namespace::eval $ns [list ::trace remove execution $nscmd enterstep [list ::punk::ns::_cmdtrace_enterstep ::punk::ns::linedict $tgt_cmd]] + #::tcl::namespace::eval $ns [list ::trace remove execution $nscmd enter [list ::punk::ns::_cmdtrace_enter ::punk::ns::linedict $tgt_cmd]] + #::tcl::namespace::eval $ns [list ::trace remove execution $nscmd leave [list ::punk::ns::_cmdtrace_leave ::punk::ns::linedict $tgt_cmd]] + nseval $ns [list ::trace remove execution $nscmd enterstep [list ::punk::ns::_cmdtrace_enterstep ::punk::ns::linedict $tgt_cmd]] + nseval $ns [list ::trace remove execution $nscmd enter [list ::punk::ns::_cmdtrace_enter ::punk::ns::linedict $tgt_cmd]] + nseval $ns [list ::trace remove execution $nscmd leave [list ::punk::ns::_cmdtrace_leave ::punk::ns::linedict $tgt_cmd]] } } @@ -4168,6 +4175,21 @@ y" {return quirkykeyscript} return [dict create origin $origin origintype $origintype which $resolved whichtype $whichtype] } + proc info_default {targetns targetproc targetarg} { + #this *very odd* construct is to avoid using the namespace argument of apply. (handling of *weird/inadvisable* namespaces) + #we use an uplevel from within the apply which runs in the global namespace, (but called via nseval from within targetns) and a result var for 'info default' in the current punk::ns namespace. + nseval $targetns [list apply [list {procname argname} { + set has_default [uplevel 1 [list info default $procname $argname ::punk::ns::corp_defvar]] + if {$has_default} { + set answer [dict create exists 1 default $::punk::ns::corp_defvar] + } else { + set answer [dict create exists 0 default {}] + } + unset ::punk::ns::corp_defvar + return $answer + } ] $targetproc $targetarg] + } + #review - should be in punk::args? proc generate_autodef {args} { set cmd [lindex $args 0] @@ -4659,7 +4681,10 @@ y" {return quirkykeyscript} #we can't use 'info args :::' - tcl won't find it set ns [nsprefix $origin] set nscmd [nstail $origin] - set infoargs [namespace eval $ns [list ::tcl::info::args $nscmd]] + #set infoargs [namespace eval $ns [list ::tcl::info::args $nscmd]] + set infoargs [nseval $ns [list ::tcl::info::args $nscmd]] + + set argdef [punk::lib::tstr -return string { @id -id "${$autoid}" @cmd -help\ @@ -4673,15 +4698,33 @@ y" {return quirkykeyscript} incr i #we need a varname for ::tcl::info::default - but as we need to run it in the ns we have to be careful, #or we risk variable collisions/pollution of the target ns. - set default_info [apply [list {procname argname} { - if {[::tcl::info::default $procname $argname defaultval]} { - return [dict create exists 1 default $defaultval] - } else { - return [dict create exists 0 default ""] - } - } $ns] $nscmd $a] + + #odd + #set default_info [apply [list {procname argname} { + # if {[::tcl::info::default $procname $argname defaultval]} { + # return [dict create exists 1 default $defaultval] + # } else { + # return [dict create exists 0 default ""] + # } + #} $ns] $nscmd $a] + set default_info [info_default $ns $nscmd $a] + + if {[dict get $default_info exists]} { - append argdef \n "$a -type unknown -default \"[dict get $default_info default]\"" + #We have to be careful if default value is something like a single double-quote. + #e.g proc ::csv::join {values {sepChar ,} {delChar {"}} {delMode auto}} {...} + + #building it as a string is tricky, we need to quote it, but not if already quoted + #- this attempt is broken + # #append argdef \n "$a -type unknown -default \"[dict get $default_info default]\"" + # #set default_info [string map [list \{ \\{ \} \\}] $default_info] + # #append argdef \n "$a -type unknown -default {" [dict get $default_info default] "}" + + #building it as a list seems likely to be more robust. + #(we parse each line as a list in punk::args) + #REVIEW + set line [list $a -type unknown -default [dict get $default_info default]] + append argdef \n $line } else { if {$i == [llength $infoargs]-1 && $a eq "args"} { #we need to use a name that doesn't collide with any previous arguments @@ -4705,7 +4748,9 @@ y" {return quirkykeyscript} } append argdef \n "$args_element -type unknown -multiple 1 -optional 1" } else { - append argdef \n "$a -type unknown" + set line [list $a -type unknown] ;#list protect for odd names of arguments + append argdef \n $line + #append argdef \n "$a -type unknown" } } } @@ -6635,7 +6680,8 @@ y" {return quirkykeyscript} set untabify [dict get $opts -untabify] set do_ln [expr {[dict exists $received --line-number]}] #thanks to Richard Suchenwirth for the original - wiki.tcl-lang.org/page/corp - #Note: modified here to support aliases and relative/absolute name (with respect to namespace .ie ::name vs name) + #Note: modified and much-extended here to support aliases and relative/absolute name (with respect to namespace .ie ::name vs name) + if {[info exists punk::console::tabwidth]} { set tw $::punk::console::tabwidth } else { @@ -6722,10 +6768,19 @@ y" {return quirkykeyscript} #set bodytext [punk::lib::undent [textutil::untabify2 $bodytext $tw]] if {$untabify ne "none"} { - set bodytext [punk::lib::undent [punk::ansi::untabify -with $untabify -stops $tw $bodytext]] + #set bodytext [punk::lib::undent [punk::ansi::untabify -with $untabify -stops $tw $bodytext]] + set bodytext [punk::ansi::untabify -with $untabify -stops $tw $bodytext] } - append body [punk::lib::indent $bodytext $indent] + set opt_indent 0 + if {$opt_indent} { + #we generally don't want to indent the body. + #Some text strings are constructed based on specific indentation. + append body [punk::lib::indent $bodytext $indent] + } else { + #no indent - more likely we could run the result (if -syntax none) to regenerate the proc with strings intact regarding their spacing relative to the left margin. + append body $bodytext + } set argl {} @@ -6734,24 +6789,47 @@ y" {return quirkykeyscript} #if {[info default $origin $a defvar]} { # lappend a $defvar #} - set result [nseval $targetns [string map [list %n% $name %a% $a] { - #qualify all command names when running in arbitrary namespace - ::if {[::info default "%n%" "%a%" punk_ns_corp_defvar]} { - ::return [::list default $punk_ns_corp_defvar][::unset punk_ns_corp_defvar] ;#keep the targetns tidy - } else { - ::return [::list none] - } - }]] - if {[lindex $result 0] eq "default"} { - lappend a [lindex $result 1] + + #string map is risky for strange values of $a + #set result [nseval $targetns [string map [list %n% $name %a% $a] { + # #qualify all command names when running in arbitrary namespace + # ::if {[::info default "%n%" "%a%" punk_ns_corp_defvar]} { + # #::return [::list default [::tcl::string::map [::list {"} {\"} \[ {\[]} \] {\]} ] $punk_ns_corp_defvar]][::unset punk_ns_corp_defvar] ;#keep the targetns tidy + # ::return [::list default $punk_ns_corp_defvar][::unset punk_ns_corp_defvar] ;#keep the targetns tidy + # } else { + # ::return [::list none] + # } + #}]] + + #this very odd construct is to avoid using the namespace argument of apply. (handling of *weird/inadvisable* namespaces) + #we use an uplevel from within the apply which runs in the global namespace, (but called via nseval from within targetns) and a result var for 'info default' in the current punk::ns namespace. + #set result [nseval $targetns [list apply [list {procname argname} { + # set has_default [uplevel 1 [list info default $procname $argname ::punk::ns::corp_defvar]] + # if {$has_default} { + # set answer [list default $::punk::ns::corp_defvar] + # } else { + # set answer [list none] + # } + # unset ::punk::ns::corp_defvar + # return $answer + #} ] $name $a]] + #if {[lindex $result 0] eq "default"} { + # lappend a [lindex $result 1] + #} + + set default_info [info_default $targetns $name $a] + if {[dict get $default_info exists]} { + lappend a [dict get $default_info default] } + lappend argl $a } #list proc [nsjoin ${targetns} $name] $argl $body #todo - load highlighters as functions from somewhere set is_highlighted 1 ;# default assumption set lnc [punk::ansi::a+ term-73] - set lnr "\x1b\[m" + #set lnr "\x1b\[m" + set lnr [punk::console::code_a] switch -- $syntax { basic { #rudimentary colourising only diff --git a/src/vfs/_vfscommon.vfs/modules/punk/tdl-0.1.0.tm b/src/vfs/_vfscommon.vfs/modules/punk/tdl-0.1.0.tm index 6b1480be..431c979e 100644 --- a/src/vfs/_vfscommon.vfs/modules/punk/tdl-0.1.0.tm +++ b/src/vfs/_vfscommon.vfs/modules/punk/tdl-0.1.0.tm @@ -50,8 +50,7 @@ namespace eval punk::tdl { # $i invokehidden namespace delete {*}[$i invokehidden namespace children] $i alias unknown apply {{i tag args} { upvar 1 result result - set e [concat [list tag $tag]\ - [lrange $args 0 [expr {([llength $args] & ~1) - 1}]]] + set e [concat [list tag $tag] [lrange $args 0 [expr {([llength $args] & ~1) - 1}]]] if {[llength $args] % 2} { set saved $result set result {} diff --git a/src/vfs/_vfscommon.vfs/modules/punkcheck-0.1.0.tm b/src/vfs/_vfscommon.vfs/modules/punkcheck-0.1.0.tm index 366014c3..2d80abcb 100644 --- a/src/vfs/_vfscommon.vfs/modules/punkcheck-0.1.0.tm +++ b/src/vfs/_vfscommon.vfs/modules/punkcheck-0.1.0.tm @@ -303,9 +303,15 @@ namespace eval punkcheck { set o_targets [lsort -dictionary -increasing $relativepath_targetset] ;#exact sort order not critical - but must be consistent - #set targetdict [my targetset_dict] set record_list [punkcheck::load_records_from_file $punkcheck_file] + + #--------------------------------------------------------------------------- + #load as dict to test for dupes + #set _targetdict [my targetset_dict] + set _targetdict [punkcheck::recordlist::records_as_target_dict $record_list] + #--------------------------------------------------------------------------- + set extractioninfo [punkcheck::recordlist::extract_or_create_fileset_record $o_targets $record_list] set o_fileset_record [dict get $extractioninfo record] set record_list [dict get $extractioninfo recordset] @@ -1757,6 +1763,7 @@ namespace eval punkcheck { if {![file exists $current_target_dir/$m]} { #puts stderr "punkcheck: first copy to $current_target_dir/$m " file mkdir $current_target_dir + puts stderr "punkcheck: about to: file copy $current_source_dir/$m $current_target_dir" file copy $current_source_dir/$m $current_target_dir set new_tgt_cksum_info [punk::mix::base::lib::cksum_path $current_target_dir/$m] lappend files_copied $current_source_dir/$m @@ -1804,6 +1811,7 @@ namespace eval punkcheck { } if {$is_target_unmodified_since_install} { file mkdir $current_target_dir + puts stderr "punkcheck: synced-targets about to: file copy -force $current_source_dir/$m $current_target_dir" file copy -force $current_source_dir/$m $current_target_dir set new_tgt_cksum_info [punk::mix::base::lib::cksum_path $current_target_dir/$m] lappend files_copied $current_source_dir/$m @@ -2083,6 +2091,10 @@ namespace eval punkcheck { foreach rec $record_list { if {[dict get $rec tag] eq "FILEINFO"} { set tgtlist [dict get $rec -targets] + if {[dict exists $result $tgtlist]} { + #todo - warn - duplicate record for same targetlist - shouldn't happen as we should be using get_file_record to find existing records + error "punkcheck::recordlist::records_as_target_dict - multiple records with same targetlist '$tgtlist'" + } dict set result $tgtlist $rec } } @@ -2090,8 +2102,6 @@ namespace eval punkcheck { } - - #will only match if same base was used.. and same targetlist proc get_file_record {targetlist record_list} { set posn 0 @@ -2347,12 +2357,12 @@ namespace eval punkcheck { } #extract new or existing filerecord for path given - #review - locking/concurrency + #REVIEW - locking/concurrency proc extract_or_create_fileset_record {relative_target_paths recordset} { set fetch_record_result [punkcheck::recordlist::get_file_record $relative_target_paths $recordset] set existing_posn [dict get $fetch_record_result position] if {$existing_posn == -1} { - #puts stdout "NO existing record for $relative_target_paths" + puts stdout "punkcheck NO existing record for $relative_target_paths" set isnew 1 set fileset_record [dict create tag FILEINFO -targets $relative_target_paths body {}] } else { diff --git a/src/vfs/_vfscommon.vfs/modules/shellrun-0.1.1.tm b/src/vfs/_vfscommon.vfs/modules/shellrun-0.1.1.tm index c3f7ab10..96c578cd 100644 --- a/src/vfs/_vfscommon.vfs/modules/shellrun-0.1.1.tm +++ b/src/vfs/_vfscommon.vfs/modules/shellrun-0.1.1.tm @@ -362,6 +362,7 @@ namespace eval shellrun { } lappend chunklist [list "info" "$c$exitinfo$n"] } elseif {[dict exists $exitinfo error]} { + # -tcl (with error) set c [a+ yellow bold] lappend chunklist [list "info" "${c}error [dict get $exitinfo error]$n"] lappend chunklist [list "info" "errorCode [dict get $exitinfo errorCode]"] @@ -369,7 +370,8 @@ namespace eval shellrun { lappend chunklist [list "info" errorInfo] lappend chunklist [list "stderr" [dict get $exitinfo errorInfo]] } else { - set c [a+ Yellow red bold] + # -tcl (without error) + set c [a+ Green white bold] #lappend chunklist [list "info" "$c$exitinfo$n"] lappend chunklist [list "info" [punk::ansi::ansiwrap_raw $c \x1b\[m "" $exitinfo]] } @@ -511,12 +513,14 @@ namespace eval shellrun { } lappend chunklist [list "info" "$c$exitinfo$n"] } elseif {[dict exists $exitinfo error]} { + # -tcl (with error) set c [a+ yellow bold] lappend chunklist [list "info" "error [dict get $exitinfo error]"] lappend chunklist [list "info" "errorCode [dict get $exitinfo errorCode]"] lappend chunklist [list "info" "errorInfo [list [dict get $exitinfo errorInfo]]"] } else { - set c [a+ Yellow red bold] + # -tcl (without error) + set c [a+ Green white bold] #lappend chunklist [list "info" "$c$exitinfo$n"] lappend chunklist [list "info" [punk::ansi::ansiwrap_raw $c "\x1b\[m" "" $exitinfo]] } diff --git a/src/vfs/_vfscommon.vfs/modules/voo-1.0.0.tm b/src/vfs/_vfscommon.vfs/modules/voo-1.0.0.tm index e377d288..a70a19be 100644 --- a/src/vfs/_vfscommon.vfs/modules/voo-1.0.0.tm +++ b/src/vfs/_vfscommon.vfs/modules/voo-1.0.0.tm @@ -1,3 +1,7 @@ + +#https://github.com/AlaoPrado/voo +#License: MIT + namespace eval voo { # package version variable version 1.0.0