From 834a472cf2b4591088d43e8240832df41ada3180 Mon Sep 17 00:00:00 2001 From: Julian Noble Date: Fri, 2 Jan 2026 16:03:52 +1100 Subject: [PATCH] punk::console add -passthrough as a parameter --- src/bootsupport/modules/punk/console-0.1.1.tm | 112 ++++++++++++------ src/modules/punk/console-999999.0a1.0.tm | 112 ++++++++++++------ 2 files changed, 152 insertions(+), 72 deletions(-) diff --git a/src/bootsupport/modules/punk/console-0.1.1.tm b/src/bootsupport/modules/punk/console-0.1.1.tm index 30df9ab6..2bf713b0 100644 --- a/src/bootsupport/modules/punk/console-0.1.1.tm +++ b/src/bootsupport/modules/punk/console-0.1.1.tm @@ -702,6 +702,21 @@ namespace eval punk::console { -terminal -default {stdin stdout} -type list -help\ "terminal (currently list of in/out channels) (todo - object?)" + -passthrough -default "" -choices {tmux auto} -choicecolumns 1 -choicelabels { + tmux\ + { Wrap ANSI sequence with tmux passthrough sequence. + \x1bPtmux\;\x1b\\ + Note that a tmux session could be connected to multiple + terminals (perhaps of different types) - in which case multiple + responses may be received. Passthrough should generally + be avoided except for debug/test purposes. + } + auto\ + { Use existence of ::env(TMUX) to detect tmux and + send tmux passthrough sequence. + Not recommended except for debug/test purposes. + } + } -expected_ms -default 300 -type integer -help\ "Expected number of ms for response from terminal. 100ms is usually plenty for a local terminal and a @@ -731,6 +746,7 @@ namespace eval punk::console { set expected [dict get $opts -expected_ms] set ignoreok [dict get $opts -ignoreok] set returntype [dict get $opts -return] + set passthrough [dict get $opts -passthrough] set query [dict get $values query] set capturingendregex [dict get $values capturingendregex] @@ -837,9 +853,15 @@ namespace eval punk::console { #write before console enableRaw vs after?? #There seem to be problems (e.g on WSL) if we write too early - the output ends up on screen but we don't read it - #zellij? screen? - if {[info exists ::env(TMUX)]} { - set query "\x1bPtmux\;[string map [list \x1b \x1b\x1b] $query]\x1b\\" + switch -- $passthrough { + auto { + if {[info exists ::env(TMUX)]} { + set query "\x1bPtmux\;[string map [list \x1b \x1b\x1b] $query]\x1b\\" + } + } + tmux { + set query "\x1bPtmux\;[string map [list \x1b \x1b\x1b] $query]\x1b\\" + } } puts -nonewline $output $query;flush $output chan configure $input -blocking 0 @@ -1348,6 +1370,7 @@ namespace eval punk::console { @opts -terminal -default {stdin stdout} -type list -help\ "terminal (currently list of in/out channels) (todo - object?)" + ${[punk::args::resolved_def -types opts ::punk::console::internal::get_ansi_response_payload -passthrough]} -expected_ms -type integer -default 500 -help\ "Number of ms to wait for response" @values -min 1 -max 1 @@ -1361,11 +1384,12 @@ namespace eval punk::console { lassign [dict values $argd] leaders opts values received set request [dict get $values request] set inoutchannels [dict get $opts -terminal] + set passthrough [dict get $opts -passthrough] set expected [dict get $opts -expected_ms] set capturingregex {(((.*)))$} ;#capture entire response same as response-payload set ts_start [clock millis] - set response [punk::console::internal::get_ansi_response_payload -ignoreok 1 -return dict -expected_ms $expected -terminal $inoutchannels $request $capturingregex] + set response [punk::console::internal::get_ansi_response_payload -ignoreok 1 -return dict -expected_ms $expected -terminal $inoutchannels -passthrough $passthrough $request $capturingregex] set ts_end [clock millis] puts stderr $response set out "" @@ -1786,6 +1810,7 @@ namespace eval punk::console { } @opts -console -type list -minsize 2 -default {stdin stdout} + ${[punk::args::resolved_def -types opts ::punk::console::internal::get_ansi_response_payload -passthrough]} @values -min 1 -max 1 mode -type {int|string} -multiple 0 -help\ "integer for DEC mode, or name as in the dict: @@ -1800,8 +1825,9 @@ namespace eval punk::console { proc dec_get_mode {args} { set argd [punk::args::parse $args withid ::punk::console::dec_get_mode] lassign [dict values $argd] leaders opts values - set terminal [dict get $opts -console] - set mode [dict get $values mode] + set terminal [dict get $opts -console] + set passthrough [dict get $opts -passthrough] + set mode [dict get $values mode] if {[string is integer -strict $mode]} { set m $mode @@ -1815,7 +1841,7 @@ namespace eval punk::console { } set capturingregex [string map [list %MODE% $m] {(.*)(\x1b\[\?%MODE%;([0-9]+)\$y)$}] ;#must capture prefix,entire-response,response-payload set request "\x1b\[?$m\$p" - set payload [punk::console::internal::get_ansi_response_payload -terminal $terminal $request $capturingregex] + set payload [punk::console::internal::get_ansi_response_payload -terminal $terminal -passthrough $passthrough $request $capturingregex] return $payload } @@ -1936,6 +1962,7 @@ namespace eval punk::console { } @opts -console -type list -minsize 2 -default {stdin stdout} + ${[punk::args::resolved_def -types opts ::punk::console::internal::get_ansi_response_payload -passthrough]} -refresh -type none -help\ "Force a re-test of the mode." -return -type string -choices {dict result} -default result -choicelabels { @@ -1953,7 +1980,8 @@ namespace eval punk::console { proc dec_has_mode {args} { set argd [punk::args::parse $args withid ::punk::console::dec_has_mode] lassign [dict values $argd] leaders opts values received - set console [dict get $opts -console] + set console [dict get $opts -console] + set passthrough [dict get $opts -passthrough] set num_or_name [dict get $values mode] set do_refresh [dict exists $received -refresh] set return [dict get $opts -return] @@ -1969,21 +1997,23 @@ namespace eval punk::console { } } variable dec_has_mode_cache + #make sure we cache on both console and passthrough + set cachekey "$console $passthrough" if {$do_refresh} { - if {[dict exists $dec_has_mode_cache $console $m]} { - dict unset dec_has_mode_cache $console $m + if {[dict exists $dec_has_mode_cache $cachekey $m]} { + dict unset dec_has_mode_cache $cachekey $m } } - if {![dict exists $dec_has_mode_cache $console $m]} { + if {![dict exists $dec_has_mode_cache $cachekey $m]} { set capturingregex [string map [list %MODE% $m] {(.*)(\x1b\[\?%MODE%;([0-9]+)\$y)$}] ;#must capture prefix,entire-response,response-payload set request "\x1b\[?$m\$p" - set payload [punk::console::internal::get_ansi_response_payload -terminal $console $request $capturingregex] + set payload [punk::console::internal::get_ansi_response_payload -terminal $console -passthrough $passthrough $request $capturingregex] #set has_mode [expr {$payload != 0}] #we can use the payload result as the response as non-zero responses evaluate to true set has_mode $payload if {$has_mode ne ""} { - dict set dec_has_mode_cache $console $m $has_mode + dict set dec_has_mode_cache $cachekey $m $has_mode set source "query" } else { #don't cache an empty/failed response - review @@ -1991,7 +2021,7 @@ namespace eval punk::console { set source "failedquery" } } else { - set has_mode [dict get $dec_has_mode_cache $console $m] + set has_mode [dict get $dec_has_mode_cache $cachekey $m] set source "cache" } if {$return eq "dict"} { @@ -2009,6 +2039,7 @@ namespace eval punk::console { {Show table of DEC modes with basic information.} @opts -console -type list -minsize 2 -default {stdin stdout} + ${[punk::args::resolved_def -types opts ::punk::console::internal::get_ansi_response_payload -passthrough]} -test -type none -help\ "Test current value/support for each mode" -supported -type none -help\ @@ -2020,8 +2051,9 @@ namespace eval punk::console { proc dec_modes {args} { set argd [punk::args::parse $args withid ::punk::console::dec_modes] lassign [dict values $argd] leaders opts values received - set terminal [dict get $opts -console] - set do_test [dict exists $received -test] + set terminal [dict get $opts -console] + set passthrough [dict get $opts -passthrough] + set do_test [dict exists $received -test] set only_supported [dict exists $received -supported] if {[dict exists $values match]} { set matches [dict get $values match] @@ -2079,7 +2111,7 @@ namespace eval punk::console { set RST "" if {$do_test} { #dec_has_mode can be cached - in which case only 0|3|4 can be relied upon without re-querying - set hasmode_dict [dec_has_mode -console $terminal -return dict $code] + set hasmode_dict [dec_has_mode -console $terminal -passthrough $passthrough -return dict $code] switch -- [dict get $hasmode_dict result] { 0 { if {$only_supported} { @@ -2094,7 +2126,7 @@ namespace eval punk::console { 1 - 2 { if {[dict get $hasmode_dict source] eq "cache"} { #a terminal query is required - set testresult [dec_get_mode -console $terminal $code] + set testresult [dec_get_mode -console $terminal -passthrough $passthrough $code] } else { set testresult [dict get $hasmode_dict result] if {![string is integer -strict $testresult]} { @@ -2140,7 +2172,7 @@ namespace eval punk::console { } else { if {$only_supported} { #dec_has_mode still queries terminal - but is cached if a response was received - if {[dec_has_mode -console $terminal $code] == 0} { + if {[dec_has_mode -console $terminal -passthrough $passthrough $code] == 0} { continue } } @@ -2189,6 +2221,7 @@ namespace eval punk::console { source indicates whether the result came from query or cache." } + ${[punk::args::resolved_def -types opts ::punk::console::internal::get_ansi_response_payload -passthrough]} @values -min 1 -max 1 mode -type {int|string} -help\ "integer for ANSI mode, or name as in the dict: @@ -2198,10 +2231,11 @@ namespace eval punk::console { proc ansi_has_mode {args} { set argd [punk::args::parse $args withid ::punk::console::ansi_has_mode] lassign [dict values $argd] leaders opts values received - set console [dict get $opts -console] + set console [dict get $opts -console] set num_or_name [dict get $values mode] - set return [dict get $opts -return] - set do_refresh [dict exists $received -refresh] + set return [dict get $opts -return] + set passthrough [dict get $opts -passthrough] + set do_refresh [dict exists $received -refresh] if {[string is integer -strict $num_or_name]} { set m $num_or_name @@ -2214,20 +2248,22 @@ namespace eval punk::console { } } variable ansi_has_mode_cache + #make sure we cache on both console and passthrough + set cachekey "$console $passthrough" if {$do_refresh} { - if {[dict exists $ansi_has_mode_cache $console $m]} { - dict unset ansi_has_mode_cache $console $m + if {[dict exists $ansi_has_mode_cache $cachekey $m]} { + dict unset ansi_has_mode_cache $cachekey $m } } - if {![dict exists $ansi_has_mode_cache $console $m]} { + if {![dict exists $ansi_has_mode_cache $cachekey $m]} { set capturingregex [string map [list %MODE% $m] {(.*)(\x1b\[%MODE%;([0-9]+)\$y)$}] ;#must capture prefix,entire-response,response-payload set request "\x1b\[$m\$p" - set payload [punk::console::internal::get_ansi_response_payload -terminal $console $request $capturingregex] + set payload [punk::console::internal::get_ansi_response_payload -terminal $console -passthrough $passthrough $request $capturingregex] #set has_mode [expr {$payload != 0}] set has_mode $payload if {$has_mode ne ""} { - dict set ansi_has_mode_cache $console $m $has_mode + dict set ansi_has_mode_cache $cachekey $m $has_mode set source "query" } else { #don't cache an empty/failed response - review @@ -2235,7 +2271,7 @@ namespace eval punk::console { set source "failedquery" } } else { - set has_mode [dict get $ansi_has_mode_cache $console $m] + set has_mode [dict get $ansi_has_mode_cache $cachekey $m] set source "cache" } if {$return eq "dict"} { @@ -2366,6 +2402,7 @@ namespace eval punk::console { } @opts -console -type list -minsize 2 -default {stdin stdout} + ${[punk::args::resolved_def -types opts ::punk::console::internal::get_ansi_response_payload -passthrough]} @values -min 1 -max 1 mode -type {int|string} -multiple 0 -help\ "integer for ANSI mode, or name as in the dict: @@ -2380,8 +2417,9 @@ namespace eval punk::console { proc ansi_get_mode {args} { set argd [punk::args::parse $args withid ::punk::console::ansi_get_mode] lassign [dict values $argd] leaders opts values - set terminal [dict get $opts -console] - set mode [dict get $values mode] + set terminal [dict get $opts -console] + set passthrough [dict get $opts -passthrough] + set mode [dict get $values mode] if {[string is integer -strict $mode]} { set m $mode @@ -2395,7 +2433,7 @@ namespace eval punk::console { } set capturingregex [string map [list %MODE% $m] {(.*)(\x1b\[%MODE%;([0-9]+)\$y)$}] ;#must capture prefix,entire-response,response-payload set request "\x1b\[$m\$p" - set payload [punk::console::internal::get_ansi_response_payload -terminal $terminal $request $capturingregex] + set payload [punk::console::internal::get_ansi_response_payload -terminal $terminal -passthrough $passthrough $request $capturingregex] return $payload } #todo ansi_unset_mode @@ -2409,6 +2447,7 @@ namespace eval punk::console { {Show table of ANSI modes with basic information.} @opts -console -type list -minsize 2 -default {stdin stdout} + ${[punk::args::resolved_def -types opts ::punk::console::internal::get_ansi_response_payload -passthrough]} -test -type none -help\ "Test current value/support for each mode" -supported -type none -help\ @@ -2420,8 +2459,9 @@ namespace eval punk::console { proc ansi_modes {args} { set argd [punk::args::parse $args withid ::punk::console::ansi_modes] lassign [dict values $argd] leaders opts values received - set terminal [dict get $opts -console] - set do_test [dict exists $received -test] + set terminal [dict get $opts -console] + set passthrough [dict get $opts -passthrough] + set do_test [dict exists $received -test] if {[dict exists $values match]} { set matches [dict get $values match] } else { @@ -2505,7 +2545,7 @@ namespace eval punk::console { set reset_state_colour "" set RST "" if {$do_test} { - set hasmode_dict [ansi_has_mode -console $terminal -return dict $code] + set hasmode_dict [ansi_has_mode -console $terminal -passthrough $passthrough -return dict $code] switch -- [dict get $hasmode_dict result] { 0 { if {$only_supported} { @@ -2520,7 +2560,7 @@ namespace eval punk::console { 1 - 2 { if {[dict get $hasmode_dict source] eq "cache"} { #a terminal query is required - set testresult [ansi_get_mode -console $terminal $code] + set testresult [ansi_get_mode -console $terminal -passthrough $passthrough $code] } else { set testresult [dict get $hasmode_dict result] if {![string is integer -strict $testresult]} { @@ -2566,7 +2606,7 @@ namespace eval punk::console { } else { if {$only_supported} { #ansi_has_mode still queries terminal - but is cached if a response was received - if {[ansi_has_mode -console $terminal $code] == 0} { + if {[ansi_has_mode -console $terminal -passthrough $passthrough $code] == 0} { continue } } diff --git a/src/modules/punk/console-999999.0a1.0.tm b/src/modules/punk/console-999999.0a1.0.tm index 98e74315..5af0ae30 100644 --- a/src/modules/punk/console-999999.0a1.0.tm +++ b/src/modules/punk/console-999999.0a1.0.tm @@ -702,6 +702,21 @@ namespace eval punk::console { -terminal -default {stdin stdout} -type list -help\ "terminal (currently list of in/out channels) (todo - object?)" + -passthrough -default "" -choices {tmux auto} -choicecolumns 1 -choicelabels { + tmux\ + { Wrap ANSI sequence with tmux passthrough sequence. + \x1bPtmux\;\x1b\\ + Note that a tmux session could be connected to multiple + terminals (perhaps of different types) - in which case multiple + responses may be received. Passthrough should generally + be avoided except for debug/test purposes. + } + auto\ + { Use existence of ::env(TMUX) to detect tmux and + send tmux passthrough sequence. + Not recommended except for debug/test purposes. + } + } -expected_ms -default 300 -type integer -help\ "Expected number of ms for response from terminal. 100ms is usually plenty for a local terminal and a @@ -731,6 +746,7 @@ namespace eval punk::console { set expected [dict get $opts -expected_ms] set ignoreok [dict get $opts -ignoreok] set returntype [dict get $opts -return] + set passthrough [dict get $opts -passthrough] set query [dict get $values query] set capturingendregex [dict get $values capturingendregex] @@ -837,9 +853,15 @@ namespace eval punk::console { #write before console enableRaw vs after?? #There seem to be problems (e.g on WSL) if we write too early - the output ends up on screen but we don't read it - #zellij? screen? - if {[info exists ::env(TMUX)]} { - set query "\x1bPtmux\;[string map [list \x1b \x1b\x1b] $query]\x1b\\" + switch -- $passthrough { + auto { + if {[info exists ::env(TMUX)]} { + set query "\x1bPtmux\;[string map [list \x1b \x1b\x1b] $query]\x1b\\" + } + } + tmux { + set query "\x1bPtmux\;[string map [list \x1b \x1b\x1b] $query]\x1b\\" + } } puts -nonewline $output $query;flush $output chan configure $input -blocking 0 @@ -1348,6 +1370,7 @@ namespace eval punk::console { @opts -terminal -default {stdin stdout} -type list -help\ "terminal (currently list of in/out channels) (todo - object?)" + ${[punk::args::resolved_def -types opts ::punk::console::internal::get_ansi_response_payload -passthrough]} -expected_ms -type integer -default 500 -help\ "Number of ms to wait for response" @values -min 1 -max 1 @@ -1361,11 +1384,12 @@ namespace eval punk::console { lassign [dict values $argd] leaders opts values received set request [dict get $values request] set inoutchannels [dict get $opts -terminal] + set passthrough [dict get $opts -passthrough] set expected [dict get $opts -expected_ms] set capturingregex {(((.*)))$} ;#capture entire response same as response-payload set ts_start [clock millis] - set response [punk::console::internal::get_ansi_response_payload -ignoreok 1 -return dict -expected_ms $expected -terminal $inoutchannels $request $capturingregex] + set response [punk::console::internal::get_ansi_response_payload -ignoreok 1 -return dict -expected_ms $expected -terminal $inoutchannels -passthrough $passthrough $request $capturingregex] set ts_end [clock millis] puts stderr $response set out "" @@ -1786,6 +1810,7 @@ namespace eval punk::console { } @opts -console -type list -minsize 2 -default {stdin stdout} + ${[punk::args::resolved_def -types opts ::punk::console::internal::get_ansi_response_payload -passthrough]} @values -min 1 -max 1 mode -type {int|string} -multiple 0 -help\ "integer for DEC mode, or name as in the dict: @@ -1800,8 +1825,9 @@ namespace eval punk::console { proc dec_get_mode {args} { set argd [punk::args::parse $args withid ::punk::console::dec_get_mode] lassign [dict values $argd] leaders opts values - set terminal [dict get $opts -console] - set mode [dict get $values mode] + set terminal [dict get $opts -console] + set passthrough [dict get $opts -passthrough] + set mode [dict get $values mode] if {[string is integer -strict $mode]} { set m $mode @@ -1815,7 +1841,7 @@ namespace eval punk::console { } set capturingregex [string map [list %MODE% $m] {(.*)(\x1b\[\?%MODE%;([0-9]+)\$y)$}] ;#must capture prefix,entire-response,response-payload set request "\x1b\[?$m\$p" - set payload [punk::console::internal::get_ansi_response_payload -terminal $terminal $request $capturingregex] + set payload [punk::console::internal::get_ansi_response_payload -terminal $terminal -passthrough $passthrough $request $capturingregex] return $payload } @@ -1936,6 +1962,7 @@ namespace eval punk::console { } @opts -console -type list -minsize 2 -default {stdin stdout} + ${[punk::args::resolved_def -types opts ::punk::console::internal::get_ansi_response_payload -passthrough]} -refresh -type none -help\ "Force a re-test of the mode." -return -type string -choices {dict result} -default result -choicelabels { @@ -1953,7 +1980,8 @@ namespace eval punk::console { proc dec_has_mode {args} { set argd [punk::args::parse $args withid ::punk::console::dec_has_mode] lassign [dict values $argd] leaders opts values received - set console [dict get $opts -console] + set console [dict get $opts -console] + set passthrough [dict get $opts -passthrough] set num_or_name [dict get $values mode] set do_refresh [dict exists $received -refresh] set return [dict get $opts -return] @@ -1969,21 +1997,23 @@ namespace eval punk::console { } } variable dec_has_mode_cache + #make sure we cache on both console and passthrough + set cachekey "$console $passthrough" if {$do_refresh} { - if {[dict exists $dec_has_mode_cache $console $m]} { - dict unset dec_has_mode_cache $console $m + if {[dict exists $dec_has_mode_cache $cachekey $m]} { + dict unset dec_has_mode_cache $cachekey $m } } - if {![dict exists $dec_has_mode_cache $console $m]} { + if {![dict exists $dec_has_mode_cache $cachekey $m]} { set capturingregex [string map [list %MODE% $m] {(.*)(\x1b\[\?%MODE%;([0-9]+)\$y)$}] ;#must capture prefix,entire-response,response-payload set request "\x1b\[?$m\$p" - set payload [punk::console::internal::get_ansi_response_payload -terminal $console $request $capturingregex] + set payload [punk::console::internal::get_ansi_response_payload -terminal $console -passthrough $passthrough $request $capturingregex] #set has_mode [expr {$payload != 0}] #we can use the payload result as the response as non-zero responses evaluate to true set has_mode $payload if {$has_mode ne ""} { - dict set dec_has_mode_cache $console $m $has_mode + dict set dec_has_mode_cache $cachekey $m $has_mode set source "query" } else { #don't cache an empty/failed response - review @@ -1991,7 +2021,7 @@ namespace eval punk::console { set source "failedquery" } } else { - set has_mode [dict get $dec_has_mode_cache $console $m] + set has_mode [dict get $dec_has_mode_cache $cachekey $m] set source "cache" } if {$return eq "dict"} { @@ -2009,6 +2039,7 @@ namespace eval punk::console { {Show table of DEC modes with basic information.} @opts -console -type list -minsize 2 -default {stdin stdout} + ${[punk::args::resolved_def -types opts ::punk::console::internal::get_ansi_response_payload -passthrough]} -test -type none -help\ "Test current value/support for each mode" -supported -type none -help\ @@ -2020,8 +2051,9 @@ namespace eval punk::console { proc dec_modes {args} { set argd [punk::args::parse $args withid ::punk::console::dec_modes] lassign [dict values $argd] leaders opts values received - set terminal [dict get $opts -console] - set do_test [dict exists $received -test] + set terminal [dict get $opts -console] + set passthrough [dict get $opts -passthrough] + set do_test [dict exists $received -test] set only_supported [dict exists $received -supported] if {[dict exists $values match]} { set matches [dict get $values match] @@ -2079,7 +2111,7 @@ namespace eval punk::console { set RST "" if {$do_test} { #dec_has_mode can be cached - in which case only 0|3|4 can be relied upon without re-querying - set hasmode_dict [dec_has_mode -console $terminal -return dict $code] + set hasmode_dict [dec_has_mode -console $terminal -passthrough $passthrough -return dict $code] switch -- [dict get $hasmode_dict result] { 0 { if {$only_supported} { @@ -2094,7 +2126,7 @@ namespace eval punk::console { 1 - 2 { if {[dict get $hasmode_dict source] eq "cache"} { #a terminal query is required - set testresult [dec_get_mode -console $terminal $code] + set testresult [dec_get_mode -console $terminal -passthrough $passthrough $code] } else { set testresult [dict get $hasmode_dict result] if {![string is integer -strict $testresult]} { @@ -2140,7 +2172,7 @@ namespace eval punk::console { } else { if {$only_supported} { #dec_has_mode still queries terminal - but is cached if a response was received - if {[dec_has_mode -console $terminal $code] == 0} { + if {[dec_has_mode -console $terminal -passthrough $passthrough $code] == 0} { continue } } @@ -2189,6 +2221,7 @@ namespace eval punk::console { source indicates whether the result came from query or cache." } + ${[punk::args::resolved_def -types opts ::punk::console::internal::get_ansi_response_payload -passthrough]} @values -min 1 -max 1 mode -type {int|string} -help\ "integer for ANSI mode, or name as in the dict: @@ -2198,10 +2231,11 @@ namespace eval punk::console { proc ansi_has_mode {args} { set argd [punk::args::parse $args withid ::punk::console::ansi_has_mode] lassign [dict values $argd] leaders opts values received - set console [dict get $opts -console] + set console [dict get $opts -console] set num_or_name [dict get $values mode] - set return [dict get $opts -return] - set do_refresh [dict exists $received -refresh] + set return [dict get $opts -return] + set passthrough [dict get $opts -passthrough] + set do_refresh [dict exists $received -refresh] if {[string is integer -strict $num_or_name]} { set m $num_or_name @@ -2214,20 +2248,22 @@ namespace eval punk::console { } } variable ansi_has_mode_cache + #make sure we cache on both console and passthrough + set cachekey "$console $passthrough" if {$do_refresh} { - if {[dict exists $ansi_has_mode_cache $console $m]} { - dict unset ansi_has_mode_cache $console $m + if {[dict exists $ansi_has_mode_cache $cachekey $m]} { + dict unset ansi_has_mode_cache $cachekey $m } } - if {![dict exists $ansi_has_mode_cache $console $m]} { + if {![dict exists $ansi_has_mode_cache $cachekey $m]} { set capturingregex [string map [list %MODE% $m] {(.*)(\x1b\[%MODE%;([0-9]+)\$y)$}] ;#must capture prefix,entire-response,response-payload set request "\x1b\[$m\$p" - set payload [punk::console::internal::get_ansi_response_payload -terminal $console $request $capturingregex] + set payload [punk::console::internal::get_ansi_response_payload -terminal $console -passthrough $passthrough $request $capturingregex] #set has_mode [expr {$payload != 0}] set has_mode $payload if {$has_mode ne ""} { - dict set ansi_has_mode_cache $console $m $has_mode + dict set ansi_has_mode_cache $cachekey $m $has_mode set source "query" } else { #don't cache an empty/failed response - review @@ -2235,7 +2271,7 @@ namespace eval punk::console { set source "failedquery" } } else { - set has_mode [dict get $ansi_has_mode_cache $console $m] + set has_mode [dict get $ansi_has_mode_cache $cachekey $m] set source "cache" } if {$return eq "dict"} { @@ -2366,6 +2402,7 @@ namespace eval punk::console { } @opts -console -type list -minsize 2 -default {stdin stdout} + ${[punk::args::resolved_def -types opts ::punk::console::internal::get_ansi_response_payload -passthrough]} @values -min 1 -max 1 mode -type {int|string} -multiple 0 -help\ "integer for ANSI mode, or name as in the dict: @@ -2380,8 +2417,9 @@ namespace eval punk::console { proc ansi_get_mode {args} { set argd [punk::args::parse $args withid ::punk::console::ansi_get_mode] lassign [dict values $argd] leaders opts values - set terminal [dict get $opts -console] - set mode [dict get $values mode] + set terminal [dict get $opts -console] + set passthrough [dict get $opts -passthrough] + set mode [dict get $values mode] if {[string is integer -strict $mode]} { set m $mode @@ -2395,7 +2433,7 @@ namespace eval punk::console { } set capturingregex [string map [list %MODE% $m] {(.*)(\x1b\[%MODE%;([0-9]+)\$y)$}] ;#must capture prefix,entire-response,response-payload set request "\x1b\[$m\$p" - set payload [punk::console::internal::get_ansi_response_payload -terminal $terminal $request $capturingregex] + set payload [punk::console::internal::get_ansi_response_payload -terminal $terminal -passthrough $passthrough $request $capturingregex] return $payload } #todo ansi_unset_mode @@ -2409,6 +2447,7 @@ namespace eval punk::console { {Show table of ANSI modes with basic information.} @opts -console -type list -minsize 2 -default {stdin stdout} + ${[punk::args::resolved_def -types opts ::punk::console::internal::get_ansi_response_payload -passthrough]} -test -type none -help\ "Test current value/support for each mode" -supported -type none -help\ @@ -2420,8 +2459,9 @@ namespace eval punk::console { proc ansi_modes {args} { set argd [punk::args::parse $args withid ::punk::console::ansi_modes] lassign [dict values $argd] leaders opts values received - set terminal [dict get $opts -console] - set do_test [dict exists $received -test] + set terminal [dict get $opts -console] + set passthrough [dict get $opts -passthrough] + set do_test [dict exists $received -test] if {[dict exists $values match]} { set matches [dict get $values match] } else { @@ -2505,7 +2545,7 @@ namespace eval punk::console { set reset_state_colour "" set RST "" if {$do_test} { - set hasmode_dict [ansi_has_mode -console $terminal -return dict $code] + set hasmode_dict [ansi_has_mode -console $terminal -passthrough $passthrough -return dict $code] switch -- [dict get $hasmode_dict result] { 0 { if {$only_supported} { @@ -2520,7 +2560,7 @@ namespace eval punk::console { 1 - 2 { if {[dict get $hasmode_dict source] eq "cache"} { #a terminal query is required - set testresult [ansi_get_mode -console $terminal $code] + set testresult [ansi_get_mode -console $terminal -passthrough $passthrough $code] } else { set testresult [dict get $hasmode_dict result] if {![string is integer -strict $testresult]} { @@ -2566,7 +2606,7 @@ namespace eval punk::console { } else { if {$only_supported} { #ansi_has_mode still queries terminal - but is cached if a response was received - if {[ansi_has_mode -console $terminal $code] == 0} { + if {[ansi_has_mode -console $terminal -passthrough $passthrough $code] == 0} { continue } }