[TxMt] Re: Line buffering for the Stdout window?

Jean-Denis Muys jdmuys at free.fr
Thu Apr 16 18:19:36 UTC 2009


On Apr 13, 2009, at 6:23 PM, Alex Ross wrote:

> On Apr 13, 2009, at 7:10 AM, Jay Soffian wrote:
>
>> Python, Perl, Ruby, all use TextMate::Executor to handle cmd-R. It
>> appears to batch the stdout and stderr, instead of properly
>> interleaving them as they are produced.
>>
>> I think TextMate::Executor is Alex Ross's baby.
>
> The only way to get proper line-buffering from these is to run them
> attached to a TTY.  I tried “faking” it, but it's not really
> possible unless somebody writes a dylib that we inject into the
> process to force line buffering.  I don't really know how to do that,
> so it never got done…
>
> —alex

*** workaround for this problem below ***

It's true that by default, stdout is fully buffered unless attached to  
a TTY. However, it is usually possible to change its buffering mode  
from whatever language you are using. For example, from Perl, there  
are (at least) 3 different idioms to do that:

# idiom 1
my $previous  = select STDOUT;
$|=1;
select $previous;

# idiom 2
binmode(STDOUT, ":unix");

# idiom 3
STDOUT->autoflush(1);

However, non of those work within TextMate.

I don't mind the default buffering to be fully buffered.

I do mind however, not being able to change the buffering mode.

For example, save and run the following perl program in the terminal,  
and in TM to see the difference:

# ------------ snip -------------
warn "\ndefault buffering\n";
print "stdout line 1\n";
warn "stderr line 2\n";
print "stdout line 3\n";
warn "stderr line 4\n";
print "stdout line 5\n";

my $previous  = select STDOUT;
$|=1;
select $previous;

warn "\nline buffering\n";
print "stdout line 6\n";
warn "stderr line 7\n";
print "stdout line 8\n";
warn "stderr line 9\n";
print "stdout line 10\n";
# ------------ snip -------------

Note: executing the above program in the terminal with the usual  
command will have stdout and stderr attached to a TTY:

perl bufferingTest.pl

To execute it with stdout and stderr NOT attached to a TTY, one way is  
to pipe both output streams to the cat command:

perl bufferingTest.pl 2>&1 | cat


This gave me the following idea for a workaround for this problem:  
copy the line above into another file, called bufferingTest.sh (a  
shell "program"), and instead of running the original Perl program,  
run the .sh file.

This workaround works as expected, with only one minor issue: the  
output to stderr is not printed in red any more. Maybe someone can  
imagine a more subtle way to go?

One possible acceptable behaviour for me would be to have stderr and  
stdout printed in *different* windows. Would that be possible?

best regards,

JD







More information about the textmate mailing list