diff --git a/src/bootsupport/modules/overtype-1.6.1.tm b/src/bootsupport/modules/overtype-1.6.1.tm index 079caec..91ed77e 100644 --- a/src/bootsupport/modules/overtype-1.6.1.tm +++ b/src/bootsupport/modules/overtype-1.6.1.tm @@ -507,39 +507,8 @@ proc overtype::left {args} { set cursor_saved_attributes $c_saved_attributes } - #background line is narrower than data in line set overflow_handled 0 - if {!$opt_overflow && !$autowrap_mode} { - #not allowed to overflow column or wrap therefore we get overflow data to truncate - if {[dict get $opts -ellipsis]} { - set show_ellipsis 1 - if {!$opt_ellipsiswhitespace} { - #we don't want ellipsis if only whitespace was lost - set lostdata "" - if {$overflow_right ne ""} { - append lostdata $overflow_right - } - if {$unapplied ne ""} { - append lostdata $unapplied - } - if {[string trim $lostdata] eq ""} { - set show_ellipsis 0 - } - #set lostdata [string range $overtext end-[expr {$overflowlength-1}] end] - if {[string trim [ansistrip $lostdata]] eq ""} { - set show_ellipsis 0 - } - } - if {$show_ellipsis} { - set rendered [overtype::right $rendered $opt_ellipsistext] - } - set overflow_handled 1 - } else { - #no wrap - no ellipsis - silently truncate - set overflow_handled 1 - } - } @@ -1022,6 +991,40 @@ proc overtype::left {args} { } + + if {!$opt_overflow && !$autowrap_mode} { + #not allowed to overflow column or wrap therefore we get overflow data to truncate + if {[dict get $opts -ellipsis]} { + set show_ellipsis 1 + if {!$opt_ellipsiswhitespace} { + #we don't want ellipsis if only whitespace was lost + set lostdata "" + if {$overflow_right ne ""} { + append lostdata $overflow_right + } + if {$unapplied ne ""} { + append lostdata $unapplied + } + if {[string trim $lostdata] eq ""} { + set show_ellipsis 0 + } + #set lostdata [string range $overtext end-[expr {$overflowlength-1}] end] + if {[string trim [ansistrip $lostdata]] eq ""} { + set show_ellipsis 0 + } + } + if {$show_ellipsis} { + set rendered [overtype::right $rendered $opt_ellipsistext] + } + set overflow_handled 1 + } else { + #no wrap - no ellipsis - silently truncate + set overflow_handled 1 + } + } + + + if {$renderedrow <= [llength $outputlines]} { lset outputlines [expr {$renderedrow-1}] $rendered } else { @@ -3076,8 +3079,10 @@ proc overtype::renderline {args} { #puts stderr "remainder:$overflow_right" } #pdict $understacks + if {[punk::ansi::ta::detect_sgr $outstring]} { - append outstring [punk::ansi::a] + append outstring [punk::ansi::a] ;#without this - we would get for example, trailing backgrounds after rightmost column + #close off any open gx? #probably should - and overflow_right reopen? } diff --git a/src/bootsupport/modules/punk/console-0.1.1.tm b/src/bootsupport/modules/punk/console-0.1.1.tm index af8129b..538c779 100644 --- a/src/bootsupport/modules/punk/console-0.1.1.tm +++ b/src/bootsupport/modules/punk/console-0.1.1.tm @@ -1025,10 +1025,32 @@ namespace eval punk::console { } - proc get_cursor_pos_list {} { - return [split [get_cursor_pos] ";"] + proc get_cursor_pos_list {{inoutchannels {stdin stdout}}} { + return [split [get_cursor_pos $inoutchannels] ";"] } - proc get_size {} { + + #todo - determine cursor on/off state before the call to restore properly. May only be possible + proc get_size {{inoutchannels {stdin stdout}}} { + lassign $inoutchannels in out + if {[catch { + #some terminals (conemu on windows) scroll the viewport when we make a big move down like this - a move to 1 1 immediately after cursor_save doesn't seem to fix that. + #This issue also occurs when switching back from the alternate screen buffer - so perhaps that needs to be addressed elsewhere. + lassign [get_cursor_pos_list $inoutchannels] start_row start_col + puts -nonewline $out [punk::ansi::cursor_off][punk::ansi::move 2000 2000] + lassign [get_cursor_pos_list $inoutchannels] lines cols + puts -nonewline $out [punk::ansi::move $start_row $start_col][punk::console::cursor_on];flush stdout + set result [list columns $cols rows $lines] + } errM]} { + puts -nonewline $out [punk::ansi::move $start_row $start_col] + puts -nonewline $out [punk::ansi::cursor_on] + error "$errM" + } else { + return $result + } + } + + #faster - but uses cursor_save - which we may want to avoid if calling during another operation which uses cursor save/restore + proc get_size_cursorrestore {} { if {[catch { #some terminals (conemu on windows) scroll the viewport when we make a big move down like this - a move to 1 1 immediately after cursor_save doesn't seem to fix that. #This issue also occurs when switching back from the alternate screen buffer - so perhaps that needs to be addressed elsewhere. @@ -1044,8 +1066,8 @@ namespace eval punk::console { return $result } } - proc get_dimensions {} { - lassign [get_size] _c cols _l lines + proc get_dimensions {{inoutchannels {stdin stdout}}} { + lassign [get_size $inoutchannels] _c cols _l lines return "${cols}x${lines}" } #the (xterm?) CSI 18t query is supported by *some* terminals @@ -1120,7 +1142,7 @@ namespace eval punk::console { return [expr {$col2 - $col1}] } - #todo! - improve + #todo! - improve ideally we want to use VT sequences to determine - and make a separate utility for testing via systemcalls/os api proc test_can_ansi {} { #don't set ansi_avaliable here - we want to be able to change things, retest etc. if {"windows" eq "$::tcl_platform(platform)"} { @@ -1392,7 +1414,7 @@ namespace eval punk::console { puts -nonewline stdout $commands return "" } - #we can be faster and more efficient if we use the consoles cursor_save_dec command - but each savecursor overrides any previous one. + #we can be (slightly?) faster and more efficient if we use the consoles cursor_save_dec command - but each savecursor overrides any previous one. #leave cursor_off/cursor_on to caller who can wrap more efficiently.. proc cursorsave_move_emit_return {row col data args} { set commands "" diff --git a/src/modules/punk/basictelnet-999999.0a1.0.tm b/src/modules/punk/basictelnet-999999.0a1.0.tm index 8ea4eef..bb47789 100644 --- a/src/modules/punk/basictelnet-999999.0a1.0.tm +++ b/src/modules/punk/basictelnet-999999.0a1.0.tm @@ -101,7 +101,11 @@ namespace eval punk::basictelnet { namespace export * variable closed - #todo - use these as defaults - provide a way to configure/listen to local events and notify server + variable consolewidth ;#entire console width - checked only at each telnet start for performance reasons (as we don't yet have sigwinch for unix, and on windows we don't yet have an equivalent) + #consolewidth should be about 80 cols wider than the window_cols setting if debug on same screen is to be used. (debug pane on RHS of screen) + #todo - launch a separate telnet server (or something) and allow debugging to a totally separate window that can be monitored with another telnet client - review + + #todo - use these as defaults - provide a way to configure/listen to local events and notify server (sigwinch unix, unknown windows) set window_cols 80 set window_rows 25 @@ -199,7 +203,7 @@ namespace eval punk::basictelnet { dict set optioncodes 43 [list name "Telnet Remote Serial Port (RSP)" short "RSP"] dict set optioncodes 44 [list name "Com Port Control Option"] dict set optioncodes 45 [list name "Telnet Supress Local Echo" short "no-local-echo"] - dict set optioncodes 46 [list name "Telnet Start TLS" short "starttls"] + dict set optioncodes 46 [list name "Telnet Start TLS" short "start_tls"] dict set optioncodes 47 [list name "KERMIT"] dict set optioncodes 48 [list name "SEND-URL"] dict set optioncodes 49 [list name "FORWARD_X"] @@ -378,6 +382,7 @@ namespace eval punk::basictelnet { #experiment proc debug_frame {info inputchannel outputchannel} { + variable consolewidth variable encoding_guess variable terminal_type variable writing_debug_frame @@ -401,10 +406,10 @@ namespace eval punk::basictelnet { #set existing_handler [fileevent stdin readable] set RST "\x1b\[m" - set w 80 - set infoframe [textblock::frame -width $w -ansiborder [a+ green bold] -title "[a cyan]Telnet Debug $terminal_type (encoding guess:$encoding_guess)$RST" $info] + set debug_width 80 + set infoframe [textblock::frame -width $debug_width -ansiborder [a+ green bold] -title "[a cyan]Telnet Debug $terminal_type (encoding guess:$encoding_guess)$RST" $info] #set w [textblock::width $infoframe] - set spacepatch "$RST[textblock::block $w 4 { }]" + set spacepatch "$RST[textblock::block $debug_width 4 { }]" #puts -nonewline [punk::ansi::cursor_off] #use non cursorsave version - slower - but less likely to interfere with cursor operations in data @@ -417,12 +422,13 @@ namespace eval punk::basictelnet { } if {[catch { - #punk::console::move_emitblock_return 6 90 $spacepatch\n$infoframe - punk::console::move_emitblock_return 6 90 $spacepatch - flush stdout - punk::console::move_emitblock_return 10 90 $infoframe - flush stdout - #puts -nonewline stdout [punk::ansi::cursor_on] ;#Enabling cursor should take account of whether it was enabled before - we don't have that info currently! review + #90 + set debug_offset [expr {$consolewidth - $debug_width}] + punk::console::move_emitblock_return 6 $debug_offset $spacepatch + flush stdout + punk::console::move_emitblock_return 10 $debug_offset $infoframe + flush stdout + #puts -nonewline stdout [punk::ansi::cursor_on] ;#Enabling cursor should take account of whether it was enabled before - we don't have that info currently! review } errM]} { puts stderr "debug_frame error: $errM" } @@ -452,6 +458,19 @@ namespace eval punk::basictelnet { } proc telnet {{server localhost} {port telnet}} { + variable debug + variable consolewidth ;#note - this is not terminal width for the telnet output - which needs to be about 80cols narrower if debug is to be displayed on same screen + set consolewidth [dict get [punk::console::get_size] columns] + if {$debug && $consolewidth-$::punk::basictelnet::window_cols < 80} { + puts stderr "Terminal width not wide enough for debug_window width: 80 + telnet window_cols:$::punk::basictelnet::window_cols" + puts stderr "Turn off debug, or make terminal window wider" + return + } elseif {$consolewidth < $::punk::basictelnet::window_cols} { + puts stderr "Terminal width is less than telnet window_cols:$::punk::basictelnet::window_cols" + puts stderr "Ensure terminal is greater than or equal to punk::basictelnet::window_cols" + return + } + #todo - allow telnet with channels other than stdin/stdout - and multiple sessions - per session option_states reset_option_states set sock [socket $server $port] diff --git a/src/modules/punk/console-999999.0a1.0.tm b/src/modules/punk/console-999999.0a1.0.tm index b72aa32..e62fec6 100644 --- a/src/modules/punk/console-999999.0a1.0.tm +++ b/src/modules/punk/console-999999.0a1.0.tm @@ -1025,10 +1025,32 @@ namespace eval punk::console { } - proc get_cursor_pos_list {} { - return [split [get_cursor_pos] ";"] + proc get_cursor_pos_list {{inoutchannels {stdin stdout}}} { + return [split [get_cursor_pos $inoutchannels] ";"] } - proc get_size {} { + + #todo - determine cursor on/off state before the call to restore properly. May only be possible + proc get_size {{inoutchannels {stdin stdout}}} { + lassign $inoutchannels in out + if {[catch { + #some terminals (conemu on windows) scroll the viewport when we make a big move down like this - a move to 1 1 immediately after cursor_save doesn't seem to fix that. + #This issue also occurs when switching back from the alternate screen buffer - so perhaps that needs to be addressed elsewhere. + lassign [get_cursor_pos_list $inoutchannels] start_row start_col + puts -nonewline $out [punk::ansi::cursor_off][punk::ansi::move 2000 2000] + lassign [get_cursor_pos_list $inoutchannels] lines cols + puts -nonewline $out [punk::ansi::move $start_row $start_col][punk::console::cursor_on];flush stdout + set result [list columns $cols rows $lines] + } errM]} { + puts -nonewline $out [punk::ansi::move $start_row $start_col] + puts -nonewline $out [punk::ansi::cursor_on] + error "$errM" + } else { + return $result + } + } + + #faster - but uses cursor_save - which we may want to avoid if calling during another operation which uses cursor save/restore + proc get_size_cursorrestore {} { if {[catch { #some terminals (conemu on windows) scroll the viewport when we make a big move down like this - a move to 1 1 immediately after cursor_save doesn't seem to fix that. #This issue also occurs when switching back from the alternate screen buffer - so perhaps that needs to be addressed elsewhere. @@ -1044,8 +1066,8 @@ namespace eval punk::console { return $result } } - proc get_dimensions {} { - lassign [get_size] _c cols _l lines + proc get_dimensions {{inoutchannels {stdin stdout}}} { + lassign [get_size $inoutchannels] _c cols _l lines return "${cols}x${lines}" } #the (xterm?) CSI 18t query is supported by *some* terminals @@ -1120,7 +1142,7 @@ namespace eval punk::console { return [expr {$col2 - $col1}] } - #todo! - improve + #todo! - improve ideally we want to use VT sequences to determine - and make a separate utility for testing via systemcalls/os api proc test_can_ansi {} { #don't set ansi_avaliable here - we want to be able to change things, retest etc. if {"windows" eq "$::tcl_platform(platform)"} { @@ -1392,7 +1414,7 @@ namespace eval punk::console { puts -nonewline stdout $commands return "" } - #we can be faster and more efficient if we use the consoles cursor_save_dec command - but each savecursor overrides any previous one. + #we can be (slightly?) faster and more efficient if we use the consoles cursor_save_dec command - but each savecursor overrides any previous one. #leave cursor_off/cursor_on to caller who can wrap more efficiently.. proc cursorsave_move_emit_return {row col data args} { set commands "" diff --git a/src/modules/punk/repl-0.1.tm b/src/modules/punk/repl-0.1.tm index 1b85021..0350ae2 100644 --- a/src/modules/punk/repl-0.1.tm +++ b/src/modules/punk/repl-0.1.tm @@ -1843,6 +1843,17 @@ proc repl::repl_process_data {inputchan type chunk stdinlines prompt_config} { #-------------------------- if {[set ::punk::console::ansi_available]} { package require textblock + #experimental - use punk::console::get_size to determine current visible width. + #This should ideally be using sigwinch or some equivalent to set a value somewhere. + #testing each time is very inefficient (1+ms) + #unfortunately there isn't an easy way to get such an event on windows console based systems - REVIEW. + set do_checkwidth 1 ;#make configurable if performance hit is too severe? TODO + if {$do_checkwidth} { + set consolewidth [dict get [punk::console::get_size] columns] + } else { + set consolewidth 132 ;#todo - something better! + } + set debug_width 0 if {$::punk::repl::debug_repl > 0} { set lastc [string index $chunk end] set lastc [ansistring VIEW -lf 1 -vt 1 $lastc] @@ -1866,12 +1877,13 @@ proc repl::repl_process_data {inputchan type chunk stdinlines prompt_config} { } else { set info [textblock::frame -ansiborder [a+ green bold] -title "[a cyan]debugview_raw[a]" $info] } - set w [textblock::width $info] - set spacepatch [textblock::block $w 2 " "] + set debug_width [textblock::width $info] + set spacepatch [textblock::block $debug_width 2 " "] puts -nonewline [punk::ansi::cursor_off] - #use non cursorsave versions as test - punk::console::move_emitblock_return 8 120 $spacepatch - punk::console::move_emitblock_return 10 120 $info + #use non cursorsave versions - cursor save/restore will interfere with any concurrent ansi rendering that uses save/restore - because save/restore is a single item, not a stack. + set debug_offset [[expr {$consolewidth - $debug_width - 2}]] + punk::console::move_emitblock_return 8 $debug_offset $spacepatch + punk::console::move_emitblock_return 10 $debug_offset $info puts -nonewline [punk::ansi::cursor_on] } if {[catch { @@ -1886,16 +1898,18 @@ proc repl::repl_process_data {inputchan type chunk stdinlines prompt_config} { set info [textblock::frame -title "[a red]error[a]" "$editbuf_error\n$::errorInfo"] } else { set title "[a cyan]editbuf lines [$editbuf linecount][a]" - append title "[a+ yellow bold] col:[$editbuf cursor_column] row:[$editbuf cursor_row][a]" + append title "[a+ yellow bold] col:[format %3s [$editbuf cursor_column]] row:[$editbuf cursor_row][a]" set row1 " lastchar:[ansistring VIEW -lf 1 [$editbuf last_char]] lastgrapheme:[ansistring VIEW -lf 1 [$editbuf last_grapheme]]" set row2 " lastansi:[ansistring VIEW -lf 1 [$editbuf last_ansi]]" set info [a+ green bold]$row1\n$row2[a]\n$info set info [textblock::frame -ansiborder [a+ green bold] -title $title $info] } - set w [textblock::width $info] - set spacepatch [textblock::block $w 2 " "] - punk::console::cursorsave_move_emitblock_return 8 40 $spacepatch - punk::console::cursorsave_move_emitblock_return 10 40 $info + set editbuf_width [textblock::width $info] + set spacepatch [textblock::block $editbuf_width 2 " "] + + set editbuf_offset [expr {$consolewidth - $debug_width - $editbuf_width - 2}] + punk::console::cursorsave_move_emitblock_return 8 $editbuf_offset $spacepatch + punk::console::cursorsave_move_emitblock_return 10 $editbuf_offset $info } diff --git a/src/modules/textblock-999999.0a1.0.tm b/src/modules/textblock-999999.0a1.0.tm index 492000d..ac6906d 100644 --- a/src/modules/textblock-999999.0a1.0.tm +++ b/src/modules/textblock-999999.0a1.0.tm @@ -416,13 +416,14 @@ namespace eval textblock { -subtitle ""\ -width ""\ -ansiborder ""\ + -ansibase ""\ -align "left"\ -ellipsis 1\ ] set opts [dict merge $defaults $arglist] foreach {k v} $opts { switch -- $k { - -etabs - -type - -title - -subtitle - -width - -ansiborder - -align - -ellipsis {} + -etabs - -type - -title - -subtitle - -width - -ansiborder - -ansibase - -align - -ellipsis {} default { error "frame option '$k' not understood. Valid options are [dict keys $defaults]" } @@ -472,6 +473,7 @@ namespace eval textblock { #these are all valid commands for overtype:: # -- --- --- --- --- --- set opt_ansiborder [dict get $opts -ansiborder] + set opt_ansibase [dict get $opts -ansibase] ;#experimental set opt_ellipsis [dict get $opts -ellipsis] # -- --- --- --- --- --- @@ -505,7 +507,10 @@ namespace eval textblock { #todo - render it with vertical overflow so we can process ansi moves? set linecount [textblock::height $contents] set rst [a] - set column [string repeat " " $contentwidth] ;#default - may need to override for custom frame + #set column [string repeat " " $contentwidth] ;#default - may need to override for custom frame + set underlayline [string repeat " " $contentwidth] + set underlay [::join [lrepeat $linecount $underlayline] \n] + switch -- $opt_type { "altg" { #old style ansi escape sequences with alternate graphics page G0 @@ -643,7 +648,9 @@ namespace eval textblock { set tbarwidth [expr {$opt_width - $tlc_width - $trc_width}] set bbarwidth [expr {$opt_width - $blc_width - $brc_width}] } - set column [string repeat " " $contentwidth] + #set column [string repeat " " $contentwidth] + set underlayline [string repeat " " $contentwidth] + set underlay [::join [lrepeat $linecount $underlayline] \n] if {$hlt_width == 1} { set tbar [string repeat $hlt $tbarwidth] @@ -692,9 +699,14 @@ namespace eval textblock { } else { set bottombar $bbar } + if {$opt_ansibase eq ""} { + set rstbase [a] + } else { + set rstbase [a]$opt_ansibase + } append fs $tlc$topbar$trc\n - set inner [overtype::$opt_align -ellipsis $opt_ellipsis $column $contents] - set body [textblock::join -- $lhs $inner $rhs] + set inner [overtype::$opt_align -ellipsis $opt_ellipsis $opt_ansibase$underlay$rstbase $opt_ansibase$contents$rstbase] + set body [textblock::join -- $lhs $opt_ansibase$inner$rstbase $rhs] append fs $body append fs \n $blc$bottombar$brc diff --git a/src/vendormodules/overtype-1.6.1.tm b/src/vendormodules/overtype-1.6.1.tm index 079caec..91ed77e 100644 --- a/src/vendormodules/overtype-1.6.1.tm +++ b/src/vendormodules/overtype-1.6.1.tm @@ -507,39 +507,8 @@ proc overtype::left {args} { set cursor_saved_attributes $c_saved_attributes } - #background line is narrower than data in line set overflow_handled 0 - if {!$opt_overflow && !$autowrap_mode} { - #not allowed to overflow column or wrap therefore we get overflow data to truncate - if {[dict get $opts -ellipsis]} { - set show_ellipsis 1 - if {!$opt_ellipsiswhitespace} { - #we don't want ellipsis if only whitespace was lost - set lostdata "" - if {$overflow_right ne ""} { - append lostdata $overflow_right - } - if {$unapplied ne ""} { - append lostdata $unapplied - } - if {[string trim $lostdata] eq ""} { - set show_ellipsis 0 - } - #set lostdata [string range $overtext end-[expr {$overflowlength-1}] end] - if {[string trim [ansistrip $lostdata]] eq ""} { - set show_ellipsis 0 - } - } - if {$show_ellipsis} { - set rendered [overtype::right $rendered $opt_ellipsistext] - } - set overflow_handled 1 - } else { - #no wrap - no ellipsis - silently truncate - set overflow_handled 1 - } - } @@ -1022,6 +991,40 @@ proc overtype::left {args} { } + + if {!$opt_overflow && !$autowrap_mode} { + #not allowed to overflow column or wrap therefore we get overflow data to truncate + if {[dict get $opts -ellipsis]} { + set show_ellipsis 1 + if {!$opt_ellipsiswhitespace} { + #we don't want ellipsis if only whitespace was lost + set lostdata "" + if {$overflow_right ne ""} { + append lostdata $overflow_right + } + if {$unapplied ne ""} { + append lostdata $unapplied + } + if {[string trim $lostdata] eq ""} { + set show_ellipsis 0 + } + #set lostdata [string range $overtext end-[expr {$overflowlength-1}] end] + if {[string trim [ansistrip $lostdata]] eq ""} { + set show_ellipsis 0 + } + } + if {$show_ellipsis} { + set rendered [overtype::right $rendered $opt_ellipsistext] + } + set overflow_handled 1 + } else { + #no wrap - no ellipsis - silently truncate + set overflow_handled 1 + } + } + + + if {$renderedrow <= [llength $outputlines]} { lset outputlines [expr {$renderedrow-1}] $rendered } else { @@ -3076,8 +3079,10 @@ proc overtype::renderline {args} { #puts stderr "remainder:$overflow_right" } #pdict $understacks + if {[punk::ansi::ta::detect_sgr $outstring]} { - append outstring [punk::ansi::a] + append outstring [punk::ansi::a] ;#without this - we would get for example, trailing backgrounds after rightmost column + #close off any open gx? #probably should - and overflow_right reopen? }