From 856fab4c883a0966b0fffc4abe8d9d8bd27ce11a Mon Sep 17 00:00:00 2001 From: Julian Noble Date: Thu, 26 Sep 2024 22:28:28 +1000 Subject: [PATCH] punk::repl extra stdout flush - comments regarding stderr/stdout interleaving --- src/modules/punk/repl-0.1.tm | 12 +++++++++++- .../src/bootsupport/modules/punk/console-0.1.1.tm | 8 ++++++-- .../src/bootsupport/modules/punk/console-0.1.1.tm | 8 ++++++-- 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/src/modules/punk/repl-0.1.tm b/src/modules/punk/repl-0.1.tm index b887976d..eef8799d 100644 --- a/src/modules/punk/repl-0.1.tm +++ b/src/modules/punk/repl-0.1.tm @@ -609,9 +609,19 @@ proc repl::newout2 {} { proc repl::doprompt {prompt {col {green bold}}} { #prompt to stderr. #We can pipe commands into repl's stdin without the prompt interfering with the output. - #Although all command output for each line goes to stdout - not just what is emmited with puts + #Although all command output for each line goes to stdout - not just what is emitted with puts if {$::tcl_interactive} { + flush stdout; #we are writing this prompt on stderr, but stdout could still be writing to screen + #our first char on stderr is based on the 'lastchar' of stdout which we have recorded but may not have arrived on screen. + #The issue we're trying to avoid is the (stderr)prompt arriving midway through a large stdout chunk + #REVIEW - this basic attempt to get stderr/stdout to cooperate is experimental and unlikely to achieve the desired effect + #note that our 'flush stdout' tcl call does not wait if stdout is non-blocking + #todo - investigate if the overhead is reasonable for a special channel that accepts stdout and stderr records with a reader to send to console in chunk-sizes we know will be emitted correctly + # - reader of such channel could be ok to be blocking (on read? on write to real channels?)... except everything still needs to be interruptable by things like signals? + #? - we want ordinary puts to stderr to be prioritized? to arrive on-screen - just not at arbitrary locations within stdout, and still must be correctly ordered wrt all other stderr + # - in our repl and code threads we don't want to put stderr/stdout writes in blocking mode and have code waiting on it + set last_char_info [screen_last_char_getinfo] if {![llength $last_char_info]} { set needs_clearance 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 6f385194..95ecb27d 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 @@ -177,9 +177,13 @@ namespace eval punk::console { } - #todo - something better - the 'channel' concept may not really apply on unix, as raw mode is for input and output modes + #todo - something better - the 'channel' concept may not really apply on unix, as raw mode is set for input and output modes currently - only valid to set on a readable channel? + #on windows they can be set independently (but not with stty) - REVIEW + + #NOTE - the is_raw is only being set in current interp - but the channel is shared. + #this is problematic with the repl thread being separate. - must be a tsv? REVIEW proc enableRaw {{channel stdin}} { - variable is_raw + variable is_raw variable previous_stty_state_$channel set sttycmd [auto_execok stty] if {[set previous_stty_state_$channel] eq ""} { 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 6f385194..95ecb27d 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 @@ -177,9 +177,13 @@ namespace eval punk::console { } - #todo - something better - the 'channel' concept may not really apply on unix, as raw mode is for input and output modes + #todo - something better - the 'channel' concept may not really apply on unix, as raw mode is set for input and output modes currently - only valid to set on a readable channel? + #on windows they can be set independently (but not with stty) - REVIEW + + #NOTE - the is_raw is only being set in current interp - but the channel is shared. + #this is problematic with the repl thread being separate. - must be a tsv? REVIEW proc enableRaw {{channel stdin}} { - variable is_raw + variable is_raw variable previous_stty_state_$channel set sttycmd [auto_execok stty] if {[set previous_stty_state_$channel] eq ""} {