From 5ca77dff07348a9382e295a67b25d92cfea3c334 Mon Sep 17 00:00:00 2001 From: Julian Noble Date: Thu, 26 Sep 2024 04:32:43 +1000 Subject: [PATCH] fix repl get terminal dimensions using stty as fallback --- src/modules/punk/repl-0.1.tm | 40 ++++++++++++++++++++++++++++++------ 1 file changed, 34 insertions(+), 6 deletions(-) diff --git a/src/modules/punk/repl-0.1.tm b/src/modules/punk/repl-0.1.tm index ac08c9e5..3a6cab6c 100644 --- a/src/modules/punk/repl-0.1.tm +++ b/src/modules/punk/repl-0.1.tm @@ -1364,14 +1364,42 @@ proc repl::repl_handler {inputchan prompt_config} { lassign [dict get $outconf -winsize] cols rows } else { #fallback - try external executable. Which is a bit ugly - #tput can work on windows too if it's installed e.g from msys2 + #tput can't seem to get dimensions (on FreeBSD at least) when not run interactively - ie via exec. (always returns 80x24 no matter if run with <@stdin) + + #bizarrely - tput can work with exec on windows if it's installed e.g from msys2 #but can be *slow* compared to unix e.g 400ms+ vs <2ms on FreeBSD ! + #stty -a is 400ms+ vs 500us+ on FreeBSD + + if {"windows" eq $::tcl_platform(platform)} { + set tputcmd [auto_execok tput] + if {$tputcmd ne ""} { + if {![catch {exec {*}$tputcmd cols lines} values]} { + lassign $values cols rows + } + } + } - set tputcmd [auto_execok tput] - if {$tputcmd ne ""} { - if {![catch {exec {*}$tputcmd cols lines} values]} { - lassign $values cols rows - } + if {![string is integer -strict $cols] || ![string is integer -strict $rows]} { + #same for all platforms? tested on windows, wsl, FreeBSD + #exec stty -a gives a result on the first line like: + #speed xxxx baud; rows rr; columns cc; + #review - more robust parsing - do we know it's first line? + set sttycmd [auto_execok stty] + if {$sttycmd ne ""} { + #the more parseable: stty -g doesn't give rows/columns + if {![catch {exec {*}$sttycmd -a} result} { + lassign [split $result \n] firstline + set lineparts [split $firstline {;}] ;#we seem to get segments that look well behaved enough to be treated as tcl lists - review - regex? + set rowinfo [lsearch $lineparts -index end -inline $lineparts rows] + if {[llength $rowinfo] == 2} { + set rows [lindex $rowinfo 0] + } + set colinfo [lsearch $lineparts -index end -inline $lineparts columns] + if {[llength $colinfo] == 2} { + set cols [lindex $colinfo 0] + } + } + } } } if {[string is integer -strict $cols] && [string is integer -strict $rows]} {