1*0Sstevel@tonic-gate=head1 NAME 2*0Sstevel@tonic-gate 3*0Sstevel@tonic-gateTerm::ReadLine - Perl interface to various C<readline> packages. 4*0Sstevel@tonic-gateIf no real package is found, substitutes stubs instead of basic functions. 5*0Sstevel@tonic-gate 6*0Sstevel@tonic-gate=head1 SYNOPSIS 7*0Sstevel@tonic-gate 8*0Sstevel@tonic-gate use Term::ReadLine; 9*0Sstevel@tonic-gate my $term = new Term::ReadLine 'Simple Perl calc'; 10*0Sstevel@tonic-gate my $prompt = "Enter your arithmetic expression: "; 11*0Sstevel@tonic-gate my $OUT = $term->OUT || \*STDOUT; 12*0Sstevel@tonic-gate while ( defined ($_ = $term->readline($prompt)) ) { 13*0Sstevel@tonic-gate my $res = eval($_); 14*0Sstevel@tonic-gate warn $@ if $@; 15*0Sstevel@tonic-gate print $OUT $res, "\n" unless $@; 16*0Sstevel@tonic-gate $term->addhistory($_) if /\S/; 17*0Sstevel@tonic-gate } 18*0Sstevel@tonic-gate 19*0Sstevel@tonic-gate=head1 DESCRIPTION 20*0Sstevel@tonic-gate 21*0Sstevel@tonic-gateThis package is just a front end to some other packages. At the moment 22*0Sstevel@tonic-gatethis description is written, the only such package is Term-ReadLine, 23*0Sstevel@tonic-gateavailable on CPAN near you. The real target of this stub package is to 24*0Sstevel@tonic-gateset up a common interface to whatever Readline emerges with time. 25*0Sstevel@tonic-gate 26*0Sstevel@tonic-gate=head1 Minimal set of supported functions 27*0Sstevel@tonic-gate 28*0Sstevel@tonic-gateAll the supported functions should be called as methods, i.e., either as 29*0Sstevel@tonic-gate 30*0Sstevel@tonic-gate $term = new Term::ReadLine 'name'; 31*0Sstevel@tonic-gate 32*0Sstevel@tonic-gateor as 33*0Sstevel@tonic-gate 34*0Sstevel@tonic-gate $term->addhistory('row'); 35*0Sstevel@tonic-gate 36*0Sstevel@tonic-gatewhere $term is a return value of Term::ReadLine-E<gt>new(). 37*0Sstevel@tonic-gate 38*0Sstevel@tonic-gate=over 12 39*0Sstevel@tonic-gate 40*0Sstevel@tonic-gate=item C<ReadLine> 41*0Sstevel@tonic-gate 42*0Sstevel@tonic-gatereturns the actual package that executes the commands. Among possible 43*0Sstevel@tonic-gatevalues are C<Term::ReadLine::Gnu>, C<Term::ReadLine::Perl>, 44*0Sstevel@tonic-gateC<Term::ReadLine::Stub>. 45*0Sstevel@tonic-gate 46*0Sstevel@tonic-gate=item C<new> 47*0Sstevel@tonic-gate 48*0Sstevel@tonic-gatereturns the handle for subsequent calls to following 49*0Sstevel@tonic-gatefunctions. Argument is the name of the application. Optionally can be 50*0Sstevel@tonic-gatefollowed by two arguments for C<IN> and C<OUT> filehandles. These 51*0Sstevel@tonic-gatearguments should be globs. 52*0Sstevel@tonic-gate 53*0Sstevel@tonic-gate=item C<readline> 54*0Sstevel@tonic-gate 55*0Sstevel@tonic-gategets an input line, I<possibly> with actual C<readline> 56*0Sstevel@tonic-gatesupport. Trailing newline is removed. Returns C<undef> on C<EOF>. 57*0Sstevel@tonic-gate 58*0Sstevel@tonic-gate=item C<addhistory> 59*0Sstevel@tonic-gate 60*0Sstevel@tonic-gateadds the line to the history of input, from where it can be used if 61*0Sstevel@tonic-gatethe actual C<readline> is present. 62*0Sstevel@tonic-gate 63*0Sstevel@tonic-gate=item C<IN>, C<OUT> 64*0Sstevel@tonic-gate 65*0Sstevel@tonic-gatereturn the filehandles for input and output or C<undef> if C<readline> 66*0Sstevel@tonic-gateinput and output cannot be used for Perl. 67*0Sstevel@tonic-gate 68*0Sstevel@tonic-gate=item C<MinLine> 69*0Sstevel@tonic-gate 70*0Sstevel@tonic-gateIf argument is specified, it is an advice on minimal size of line to 71*0Sstevel@tonic-gatebe included into history. C<undef> means do not include anything into 72*0Sstevel@tonic-gatehistory. Returns the old value. 73*0Sstevel@tonic-gate 74*0Sstevel@tonic-gate=item C<findConsole> 75*0Sstevel@tonic-gate 76*0Sstevel@tonic-gatereturns an array with two strings that give most appropriate names for 77*0Sstevel@tonic-gatefiles for input and output using conventions C<"E<lt>$in">, C<"E<gt>out">. 78*0Sstevel@tonic-gate 79*0Sstevel@tonic-gate=item Attribs 80*0Sstevel@tonic-gate 81*0Sstevel@tonic-gatereturns a reference to a hash which describes internal configuration 82*0Sstevel@tonic-gateof the package. Names of keys in this hash conform to standard 83*0Sstevel@tonic-gateconventions with the leading C<rl_> stripped. 84*0Sstevel@tonic-gate 85*0Sstevel@tonic-gate=item C<Features> 86*0Sstevel@tonic-gate 87*0Sstevel@tonic-gateReturns a reference to a hash with keys being features present in 88*0Sstevel@tonic-gatecurrent implementation. Several optional features are used in the 89*0Sstevel@tonic-gateminimal interface: C<appname> should be present if the first argument 90*0Sstevel@tonic-gateto C<new> is recognized, and C<minline> should be present if 91*0Sstevel@tonic-gateC<MinLine> method is not dummy. C<autohistory> should be present if 92*0Sstevel@tonic-gatelines are put into history automatically (maybe subject to 93*0Sstevel@tonic-gateC<MinLine>), and C<addhistory> if C<addhistory> method is not dummy. 94*0Sstevel@tonic-gate 95*0Sstevel@tonic-gateIf C<Features> method reports a feature C<attribs> as present, the 96*0Sstevel@tonic-gatemethod C<Attribs> is not dummy. 97*0Sstevel@tonic-gate 98*0Sstevel@tonic-gate=back 99*0Sstevel@tonic-gate 100*0Sstevel@tonic-gate=head1 Additional supported functions 101*0Sstevel@tonic-gate 102*0Sstevel@tonic-gateActually C<Term::ReadLine> can use some other package, that will 103*0Sstevel@tonic-gatesupport reacher set of commands. 104*0Sstevel@tonic-gate 105*0Sstevel@tonic-gateAll these commands are callable via method interface and have names 106*0Sstevel@tonic-gatewhich conform to standard conventions with the leading C<rl_> stripped. 107*0Sstevel@tonic-gate 108*0Sstevel@tonic-gateThe stub package included with the perl distribution allows some 109*0Sstevel@tonic-gateadditional methods: 110*0Sstevel@tonic-gate 111*0Sstevel@tonic-gate=over 12 112*0Sstevel@tonic-gate 113*0Sstevel@tonic-gate=item C<tkRunning> 114*0Sstevel@tonic-gate 115*0Sstevel@tonic-gatemakes Tk event loop run when waiting for user input (i.e., during 116*0Sstevel@tonic-gateC<readline> method). 117*0Sstevel@tonic-gate 118*0Sstevel@tonic-gate=item C<ornaments> 119*0Sstevel@tonic-gate 120*0Sstevel@tonic-gatemakes the command line stand out by using termcap data. The argument 121*0Sstevel@tonic-gateto C<ornaments> should be 0, 1, or a string of a form 122*0Sstevel@tonic-gateC<"aa,bb,cc,dd">. Four components of this string should be names of 123*0Sstevel@tonic-gateI<terminal capacities>, first two will be issued to make the prompt 124*0Sstevel@tonic-gatestandout, last two to make the input line standout. 125*0Sstevel@tonic-gate 126*0Sstevel@tonic-gate=item C<newTTY> 127*0Sstevel@tonic-gate 128*0Sstevel@tonic-gatetakes two arguments which are input filehandle and output filehandle. 129*0Sstevel@tonic-gateSwitches to use these filehandles. 130*0Sstevel@tonic-gate 131*0Sstevel@tonic-gate=back 132*0Sstevel@tonic-gate 133*0Sstevel@tonic-gateOne can check whether the currently loaded ReadLine package supports 134*0Sstevel@tonic-gatethese methods by checking for corresponding C<Features>. 135*0Sstevel@tonic-gate 136*0Sstevel@tonic-gate=head1 EXPORTS 137*0Sstevel@tonic-gate 138*0Sstevel@tonic-gateNone 139*0Sstevel@tonic-gate 140*0Sstevel@tonic-gate=head1 ENVIRONMENT 141*0Sstevel@tonic-gate 142*0Sstevel@tonic-gateThe environment variable C<PERL_RL> governs which ReadLine clone is 143*0Sstevel@tonic-gateloaded. If the value is false, a dummy interface is used. If the value 144*0Sstevel@tonic-gateis true, it should be tail of the name of the package to use, such as 145*0Sstevel@tonic-gateC<Perl> or C<Gnu>. 146*0Sstevel@tonic-gate 147*0Sstevel@tonic-gateAs a special case, if the value of this variable is space-separated, 148*0Sstevel@tonic-gatethe tail might be used to disable the ornaments by setting the tail to 149*0Sstevel@tonic-gatebe C<o=0> or C<ornaments=0>. The head should be as described above, say 150*0Sstevel@tonic-gate 151*0Sstevel@tonic-gateIf the variable is not set, or if the head of space-separated list is 152*0Sstevel@tonic-gateempty, the best available package is loaded. 153*0Sstevel@tonic-gate 154*0Sstevel@tonic-gate export "PERL_RL=Perl o=0" # Use Perl ReadLine without ornaments 155*0Sstevel@tonic-gate export "PERL_RL= o=0" # Use best available ReadLine without ornaments 156*0Sstevel@tonic-gate 157*0Sstevel@tonic-gate(Note that processing of C<PERL_RL> for ornaments is in the discretion of the 158*0Sstevel@tonic-gateparticular used C<Term::ReadLine::*> package). 159*0Sstevel@tonic-gate 160*0Sstevel@tonic-gate=head1 CAVEATS 161*0Sstevel@tonic-gate 162*0Sstevel@tonic-gateIt seems that using Term::ReadLine from Emacs minibuffer doesn't work 163*0Sstevel@tonic-gatequite right and one will get an error message like 164*0Sstevel@tonic-gate 165*0Sstevel@tonic-gate Cannot open /dev/tty for read at ... 166*0Sstevel@tonic-gate 167*0Sstevel@tonic-gateOne possible workaround for this is to explicitly open /dev/tty like this 168*0Sstevel@tonic-gate 169*0Sstevel@tonic-gate open (FH, "/dev/tty" ) 170*0Sstevel@tonic-gate or eval 'sub Term::ReadLine::findConsole { ("&STDIN", "&STDERR") }'; 171*0Sstevel@tonic-gate die $@ if $@; 172*0Sstevel@tonic-gate close (FH); 173*0Sstevel@tonic-gate 174*0Sstevel@tonic-gateor you can try using the 4-argument form of Term::ReadLine->new(). 175*0Sstevel@tonic-gate 176*0Sstevel@tonic-gate=cut 177*0Sstevel@tonic-gate 178*0Sstevel@tonic-gateuse strict; 179*0Sstevel@tonic-gate 180*0Sstevel@tonic-gatepackage Term::ReadLine::Stub; 181*0Sstevel@tonic-gateour @ISA = qw'Term::ReadLine::Tk Term::ReadLine::TermCap'; 182*0Sstevel@tonic-gate 183*0Sstevel@tonic-gate$DB::emacs = $DB::emacs; # To peacify -w 184*0Sstevel@tonic-gateour @rl_term_set; 185*0Sstevel@tonic-gate*rl_term_set = \@Term::ReadLine::TermCap::rl_term_set; 186*0Sstevel@tonic-gate 187*0Sstevel@tonic-gatesub PERL_UNICODE_STDIN () { 0x0001 } 188*0Sstevel@tonic-gate 189*0Sstevel@tonic-gatesub ReadLine {'Term::ReadLine::Stub'} 190*0Sstevel@tonic-gatesub readline { 191*0Sstevel@tonic-gate my $self = shift; 192*0Sstevel@tonic-gate my ($in,$out,$str) = @$self; 193*0Sstevel@tonic-gate my $prompt = shift; 194*0Sstevel@tonic-gate print $out $rl_term_set[0], $prompt, $rl_term_set[1], $rl_term_set[2]; 195*0Sstevel@tonic-gate $self->register_Tk 196*0Sstevel@tonic-gate if not $Term::ReadLine::registered and $Term::ReadLine::toloop 197*0Sstevel@tonic-gate and defined &Tk::DoOneEvent; 198*0Sstevel@tonic-gate #$str = scalar <$in>; 199*0Sstevel@tonic-gate $str = $self->get_line; 200*0Sstevel@tonic-gate $str =~ s/^\s*\Q$prompt\E// if ($^O eq 'MacOS'); 201*0Sstevel@tonic-gate utf8::upgrade($str) 202*0Sstevel@tonic-gate if (${^UNICODE} & PERL_UNICODE_STDIN || defined ${^ENCODING}) && 203*0Sstevel@tonic-gate utf8::valid($str); 204*0Sstevel@tonic-gate print $out $rl_term_set[3]; 205*0Sstevel@tonic-gate # bug in 5.000: chomping empty string creats length -1: 206*0Sstevel@tonic-gate chomp $str if defined $str; 207*0Sstevel@tonic-gate $str; 208*0Sstevel@tonic-gate} 209*0Sstevel@tonic-gatesub addhistory {} 210*0Sstevel@tonic-gate 211*0Sstevel@tonic-gatesub findConsole { 212*0Sstevel@tonic-gate my $console; 213*0Sstevel@tonic-gate 214*0Sstevel@tonic-gate if ($^O eq 'MacOS') { 215*0Sstevel@tonic-gate $console = "Dev:Console"; 216*0Sstevel@tonic-gate } elsif (-e "/dev/tty") { 217*0Sstevel@tonic-gate $console = "/dev/tty"; 218*0Sstevel@tonic-gate } elsif (-e "con" or $^O eq 'MSWin32') { 219*0Sstevel@tonic-gate $console = "con"; 220*0Sstevel@tonic-gate } else { 221*0Sstevel@tonic-gate $console = "sys\$command"; 222*0Sstevel@tonic-gate } 223*0Sstevel@tonic-gate 224*0Sstevel@tonic-gate if (($^O eq 'amigaos') || ($^O eq 'beos') || ($^O eq 'epoc')) { 225*0Sstevel@tonic-gate $console = undef; 226*0Sstevel@tonic-gate } 227*0Sstevel@tonic-gate elsif ($^O eq 'os2') { 228*0Sstevel@tonic-gate if ($DB::emacs) { 229*0Sstevel@tonic-gate $console = undef; 230*0Sstevel@tonic-gate } else { 231*0Sstevel@tonic-gate $console = "/dev/con"; 232*0Sstevel@tonic-gate } 233*0Sstevel@tonic-gate } 234*0Sstevel@tonic-gate 235*0Sstevel@tonic-gate my $consoleOUT = $console; 236*0Sstevel@tonic-gate $console = "&STDIN" unless defined $console; 237*0Sstevel@tonic-gate if (!defined $consoleOUT) { 238*0Sstevel@tonic-gate $consoleOUT = defined fileno(STDERR) ? "&STDERR" : "&STDOUT"; 239*0Sstevel@tonic-gate } 240*0Sstevel@tonic-gate ($console,$consoleOUT); 241*0Sstevel@tonic-gate} 242*0Sstevel@tonic-gate 243*0Sstevel@tonic-gatesub new { 244*0Sstevel@tonic-gate die "method new called with wrong number of arguments" 245*0Sstevel@tonic-gate unless @_==2 or @_==4; 246*0Sstevel@tonic-gate #local (*FIN, *FOUT); 247*0Sstevel@tonic-gate my ($FIN, $FOUT, $ret); 248*0Sstevel@tonic-gate if (@_==2) { 249*0Sstevel@tonic-gate my($console, $consoleOUT) = $_[0]->findConsole; 250*0Sstevel@tonic-gate 251*0Sstevel@tonic-gate open(FIN, "<$console"); 252*0Sstevel@tonic-gate open(FOUT,">$consoleOUT"); 253*0Sstevel@tonic-gate #OUT->autoflush(1); # Conflicts with debugger? 254*0Sstevel@tonic-gate my $sel = select(FOUT); 255*0Sstevel@tonic-gate $| = 1; # for DB::OUT 256*0Sstevel@tonic-gate select($sel); 257*0Sstevel@tonic-gate $ret = bless [\*FIN, \*FOUT]; 258*0Sstevel@tonic-gate } else { # Filehandles supplied 259*0Sstevel@tonic-gate $FIN = $_[2]; $FOUT = $_[3]; 260*0Sstevel@tonic-gate #OUT->autoflush(1); # Conflicts with debugger? 261*0Sstevel@tonic-gate my $sel = select($FOUT); 262*0Sstevel@tonic-gate $| = 1; # for DB::OUT 263*0Sstevel@tonic-gate select($sel); 264*0Sstevel@tonic-gate $ret = bless [$FIN, $FOUT]; 265*0Sstevel@tonic-gate } 266*0Sstevel@tonic-gate if ($ret->Features->{ornaments} 267*0Sstevel@tonic-gate and not ($ENV{PERL_RL} and $ENV{PERL_RL} =~ /\bo\w*=0/)) { 268*0Sstevel@tonic-gate local $Term::ReadLine::termcap_nowarn = 1; 269*0Sstevel@tonic-gate $ret->ornaments(1); 270*0Sstevel@tonic-gate } 271*0Sstevel@tonic-gate return $ret; 272*0Sstevel@tonic-gate} 273*0Sstevel@tonic-gate 274*0Sstevel@tonic-gatesub newTTY { 275*0Sstevel@tonic-gate my ($self, $in, $out) = @_; 276*0Sstevel@tonic-gate $self->[0] = $in; 277*0Sstevel@tonic-gate $self->[1] = $out; 278*0Sstevel@tonic-gate my $sel = select($out); 279*0Sstevel@tonic-gate $| = 1; # for DB::OUT 280*0Sstevel@tonic-gate select($sel); 281*0Sstevel@tonic-gate} 282*0Sstevel@tonic-gate 283*0Sstevel@tonic-gatesub IN { shift->[0] } 284*0Sstevel@tonic-gatesub OUT { shift->[1] } 285*0Sstevel@tonic-gatesub MinLine { undef } 286*0Sstevel@tonic-gatesub Attribs { {} } 287*0Sstevel@tonic-gate 288*0Sstevel@tonic-gatemy %features = (tkRunning => 1, ornaments => 1, 'newTTY' => 1); 289*0Sstevel@tonic-gatesub Features { \%features } 290*0Sstevel@tonic-gate 291*0Sstevel@tonic-gatepackage Term::ReadLine; # So late to allow the above code be defined? 292*0Sstevel@tonic-gate 293*0Sstevel@tonic-gateour $VERSION = '1.01'; 294*0Sstevel@tonic-gate 295*0Sstevel@tonic-gatemy ($which) = exists $ENV{PERL_RL} ? split /\s+/, $ENV{PERL_RL} : undef; 296*0Sstevel@tonic-gateif ($which) { 297*0Sstevel@tonic-gate if ($which =~ /\bgnu\b/i){ 298*0Sstevel@tonic-gate eval "use Term::ReadLine::Gnu;"; 299*0Sstevel@tonic-gate } elsif ($which =~ /\bperl\b/i) { 300*0Sstevel@tonic-gate eval "use Term::ReadLine::Perl;"; 301*0Sstevel@tonic-gate } else { 302*0Sstevel@tonic-gate eval "use Term::ReadLine::$which;"; 303*0Sstevel@tonic-gate } 304*0Sstevel@tonic-gate} elsif (defined $which and $which ne '') { # Defined but false 305*0Sstevel@tonic-gate # Do nothing fancy 306*0Sstevel@tonic-gate} else { 307*0Sstevel@tonic-gate eval "use Term::ReadLine::Gnu; 1" or eval "use Term::ReadLine::Perl; 1"; 308*0Sstevel@tonic-gate} 309*0Sstevel@tonic-gate 310*0Sstevel@tonic-gate#require FileHandle; 311*0Sstevel@tonic-gate 312*0Sstevel@tonic-gate# To make possible switch off RL in debugger: (Not needed, work done 313*0Sstevel@tonic-gate# in debugger). 314*0Sstevel@tonic-gateour @ISA; 315*0Sstevel@tonic-gateif (defined &Term::ReadLine::Gnu::readline) { 316*0Sstevel@tonic-gate @ISA = qw(Term::ReadLine::Gnu Term::ReadLine::Stub); 317*0Sstevel@tonic-gate} elsif (defined &Term::ReadLine::Perl::readline) { 318*0Sstevel@tonic-gate @ISA = qw(Term::ReadLine::Perl Term::ReadLine::Stub); 319*0Sstevel@tonic-gate} elsif (defined $which && defined &{"Term::ReadLine::$which\::readline"}) { 320*0Sstevel@tonic-gate @ISA = "Term::ReadLine::$which"; 321*0Sstevel@tonic-gate} else { 322*0Sstevel@tonic-gate @ISA = qw(Term::ReadLine::Stub); 323*0Sstevel@tonic-gate} 324*0Sstevel@tonic-gate 325*0Sstevel@tonic-gatepackage Term::ReadLine::TermCap; 326*0Sstevel@tonic-gate 327*0Sstevel@tonic-gate# Prompt-start, prompt-end, command-line-start, command-line-end 328*0Sstevel@tonic-gate# -- zero-width beautifies to emit around prompt and the command line. 329*0Sstevel@tonic-gateour @rl_term_set = ("","","",""); 330*0Sstevel@tonic-gate# string encoded: 331*0Sstevel@tonic-gateour $rl_term_set = ',,,'; 332*0Sstevel@tonic-gate 333*0Sstevel@tonic-gateour $terminal; 334*0Sstevel@tonic-gatesub LoadTermCap { 335*0Sstevel@tonic-gate return if defined $terminal; 336*0Sstevel@tonic-gate 337*0Sstevel@tonic-gate require Term::Cap; 338*0Sstevel@tonic-gate $terminal = Tgetent Term::Cap ({OSPEED => 9600}); # Avoid warning. 339*0Sstevel@tonic-gate} 340*0Sstevel@tonic-gate 341*0Sstevel@tonic-gatesub ornaments { 342*0Sstevel@tonic-gate shift; 343*0Sstevel@tonic-gate return $rl_term_set unless @_; 344*0Sstevel@tonic-gate $rl_term_set = shift; 345*0Sstevel@tonic-gate $rl_term_set ||= ',,,'; 346*0Sstevel@tonic-gate $rl_term_set = 'us,ue,md,me' if $rl_term_set eq '1'; 347*0Sstevel@tonic-gate my @ts = split /,/, $rl_term_set, 4; 348*0Sstevel@tonic-gate eval { LoadTermCap }; 349*0Sstevel@tonic-gate unless (defined $terminal) { 350*0Sstevel@tonic-gate warn("Cannot find termcap: $@\n") unless $Term::ReadLine::termcap_nowarn; 351*0Sstevel@tonic-gate $rl_term_set = ',,,'; 352*0Sstevel@tonic-gate return; 353*0Sstevel@tonic-gate } 354*0Sstevel@tonic-gate @rl_term_set = map {$_ ? $terminal->Tputs($_,1) || '' : ''} @ts; 355*0Sstevel@tonic-gate return $rl_term_set; 356*0Sstevel@tonic-gate} 357*0Sstevel@tonic-gate 358*0Sstevel@tonic-gate 359*0Sstevel@tonic-gatepackage Term::ReadLine::Tk; 360*0Sstevel@tonic-gate 361*0Sstevel@tonic-gateour($count_handle, $count_DoOne, $count_loop); 362*0Sstevel@tonic-gate$count_handle = $count_DoOne = $count_loop = 0; 363*0Sstevel@tonic-gate 364*0Sstevel@tonic-gateour($giveup); 365*0Sstevel@tonic-gatesub handle {$giveup = 1; $count_handle++} 366*0Sstevel@tonic-gate 367*0Sstevel@tonic-gatesub Tk_loop { 368*0Sstevel@tonic-gate # Tk->tkwait('variable',\$giveup); # needs Widget 369*0Sstevel@tonic-gate $count_DoOne++, Tk::DoOneEvent(0) until $giveup; 370*0Sstevel@tonic-gate $count_loop++; 371*0Sstevel@tonic-gate $giveup = 0; 372*0Sstevel@tonic-gate} 373*0Sstevel@tonic-gate 374*0Sstevel@tonic-gatesub register_Tk { 375*0Sstevel@tonic-gate my $self = shift; 376*0Sstevel@tonic-gate $Term::ReadLine::registered++ 377*0Sstevel@tonic-gate or Tk->fileevent($self->IN,'readable',\&handle); 378*0Sstevel@tonic-gate} 379*0Sstevel@tonic-gate 380*0Sstevel@tonic-gatesub tkRunning { 381*0Sstevel@tonic-gate $Term::ReadLine::toloop = $_[1] if @_ > 1; 382*0Sstevel@tonic-gate $Term::ReadLine::toloop; 383*0Sstevel@tonic-gate} 384*0Sstevel@tonic-gate 385*0Sstevel@tonic-gatesub get_c { 386*0Sstevel@tonic-gate my $self = shift; 387*0Sstevel@tonic-gate $self->Tk_loop if $Term::ReadLine::toloop && defined &Tk::DoOneEvent; 388*0Sstevel@tonic-gate return getc $self->IN; 389*0Sstevel@tonic-gate} 390*0Sstevel@tonic-gate 391*0Sstevel@tonic-gatesub get_line { 392*0Sstevel@tonic-gate my $self = shift; 393*0Sstevel@tonic-gate $self->Tk_loop if $Term::ReadLine::toloop && defined &Tk::DoOneEvent; 394*0Sstevel@tonic-gate my $in = $self->IN; 395*0Sstevel@tonic-gate local ($/) = "\n"; 396*0Sstevel@tonic-gate return scalar <$in>; 397*0Sstevel@tonic-gate} 398*0Sstevel@tonic-gate 399*0Sstevel@tonic-gate1; 400*0Sstevel@tonic-gate 401