1=head1 NAME 2 3Term::ReadLine - Perl interface to various C<readline> packages. 4If no real package is found, substitutes stubs instead of basic functions. 5 6=head1 SYNOPSIS 7 8 use Term::ReadLine; 9 my $term = Term::ReadLine->new('Simple Perl calc'); 10 my $prompt = "Enter your arithmetic expression: "; 11 my $OUT = $term->OUT || \*STDOUT; 12 while ( defined ($_ = $term->readline($prompt)) ) { 13 my $res = eval($_); 14 warn $@ if $@; 15 print $OUT $res, "\n" unless $@; 16 $term->addhistory($_) if /\S/; 17 } 18 19=head1 DESCRIPTION 20 21This package is just a front end to some other packages. It's a stub to 22set up a common interface to the various ReadLine implementations found on 23CPAN (under the C<Term::ReadLine::*> namespace). 24 25=head1 Minimal set of supported functions 26 27All the supported functions should be called as methods, i.e., either as 28 29 $term = Term::ReadLine->new('name'); 30 31or as 32 33 $term->addhistory('row'); 34 35where $term is a return value of Term::ReadLine-E<gt>new(). 36 37=over 12 38 39=item C<ReadLine> 40 41returns the actual package that executes the commands. Among possible 42values are C<Term::ReadLine::Gnu>, C<Term::ReadLine::Perl>, 43C<Term::ReadLine::Stub>. 44 45=item C<new> 46 47returns the handle for subsequent calls to following 48functions. Argument is the name of the application. Optionally can be 49followed by two arguments for C<IN> and C<OUT> filehandles. These 50arguments should be globs. 51 52=item C<readline> 53 54gets an input line, I<possibly> with actual C<readline> 55support. Trailing newline is removed. Returns C<undef> on C<EOF>. 56 57=item C<addhistory> 58 59adds the line to the history of input, from where it can be used if 60the actual C<readline> is present. 61 62=item C<IN>, C<OUT> 63 64return the filehandles for input and output or C<undef> if C<readline> 65input and output cannot be used for Perl. 66 67=item C<MinLine> 68 69If argument is specified, it is an advice on minimal size of line to 70be included into history. C<undef> means do not include anything into 71history. Returns the old value. 72 73=item C<findConsole> 74 75returns an array with two strings that give most appropriate names for 76files for input and output using conventions C<"E<lt>$in">, C<"E<gt>out">. 77 78The strings returned may not be useful for 3-argument open(). 79 80=item Attribs 81 82returns a reference to a hash which describes internal configuration 83of the package. Names of keys in this hash conform to standard 84conventions with the leading C<rl_> stripped. 85 86=item C<Features> 87 88Returns a reference to a hash with keys being features present in 89current implementation. Several optional features are used in the 90minimal interface: C<appname> should be present if the first argument 91to C<new> is recognized, and C<minline> should be present if 92C<MinLine> method is not dummy. C<autohistory> should be present if 93lines are put into history automatically (maybe subject to 94C<MinLine>), and C<addhistory> if C<addhistory> method is not dummy. 95 96If C<Features> method reports a feature C<attribs> as present, the 97method C<Attribs> is not dummy. 98 99=back 100 101=head1 Additional supported functions 102 103Actually C<Term::ReadLine> can use some other package, that will 104support a richer set of commands. 105 106All these commands are callable via method interface and have names 107which conform to standard conventions with the leading C<rl_> stripped. 108 109The stub package included with the perl distribution allows some 110additional methods: 111 112=over 12 113 114=item C<tkRunning> 115 116makes Tk event loop run when waiting for user input (i.e., during 117C<readline> method). 118 119=item C<event_loop> 120 121Registers call-backs to wait for user input (i.e., during C<readline> 122method). This supersedes tkRunning. 123 124The first call-back registered is the call back for waiting. It is 125expected that the callback will call the current event loop until 126there is something waiting to get on the input filehandle. The parameter 127passed in is the return value of the second call back. 128 129The second call-back registered is the call back for registration. The 130input filehandle (often STDIN, but not necessarily) will be passed in. 131 132For example, with AnyEvent: 133 134 $term->event_loop(sub { 135 my $data = shift; 136 $data->[1] = AE::cv(); 137 $data->[1]->recv(); 138 }, sub { 139 my $fh = shift; 140 my $data = []; 141 $data->[0] = AE::io($fh, 0, sub { $data->[1]->send() }); 142 $data; 143 }); 144 145The second call-back is optional if the call back is registered prior to 146the call to $term-E<gt>readline. 147 148Deregistration is done in this case by calling event_loop with C<undef> 149as its parameter: 150 151 $term->event_loop(undef); 152 153This will cause the data array ref to be removed, allowing normal garbage 154collection to clean it up. With AnyEvent, that will cause $data->[0] to 155be cleaned up, and AnyEvent will automatically cancel the watcher at that 156time. If another loop requires more than that to clean up a file watcher, 157that will be up to the caller to handle. 158 159=item C<ornaments> 160 161makes the command line stand out by using termcap data. The argument 162to C<ornaments> should be 0, 1, or a string of a form 163C<"aa,bb,cc,dd">. Four components of this string should be names of 164I<terminal capacities>, first two will be issued to make the prompt 165standout, last two to make the input line standout. 166 167=item C<newTTY> 168 169takes two arguments which are input filehandle and output filehandle. 170Switches to use these filehandles. 171 172=back 173 174One can check whether the currently loaded ReadLine package supports 175these methods by checking for corresponding C<Features>. 176 177=head1 EXPORTS 178 179None 180 181=head1 ENVIRONMENT 182 183The environment variable C<PERL_RL> governs which ReadLine clone is 184loaded. If the value is false, a dummy interface is used. If the value 185is true, it should be tail of the name of the package to use, such as 186C<Perl> or C<Gnu>. 187 188As a special case, if the value of this variable is space-separated, 189the tail might be used to disable the ornaments by setting the tail to 190be C<o=0> or C<ornaments=0>. The head should be as described above, say 191 192If the variable is not set, or if the head of space-separated list is 193empty, the best available package is loaded. 194 195 export "PERL_RL=Perl o=0" # Use Perl ReadLine sans ornaments 196 export "PERL_RL= o=0" # Use best available ReadLine sans ornaments 197 198(Note that processing of C<PERL_RL> for ornaments is in the discretion of the 199particular used C<Term::ReadLine::*> package). 200 201=cut 202 203use strict; 204 205package Term::ReadLine::Stub; 206our @ISA = qw'Term::ReadLine::Tk Term::ReadLine::TermCap'; 207 208$DB::emacs = $DB::emacs; # To pacify -w 209our @rl_term_set; 210*rl_term_set = \@Term::ReadLine::TermCap::rl_term_set; 211 212sub PERL_UNICODE_STDIN () { 0x0001 } 213 214sub ReadLine {'Term::ReadLine::Stub'} 215sub readline { 216 my $self = shift; 217 my ($in,$out,$str) = @$self; 218 my $prompt = shift; 219 print $out $rl_term_set[0], $prompt, $rl_term_set[1], $rl_term_set[2]; 220 $self->register_Tk 221 if not $Term::ReadLine::registered and $Term::ReadLine::toloop; 222 #$str = scalar <$in>; 223 $str = $self->get_line; 224 utf8::upgrade($str) 225 if (${^UNICODE} & PERL_UNICODE_STDIN || defined ${^ENCODING}) && 226 utf8::valid($str); 227 print $out $rl_term_set[3]; 228 # bug in 5.000: chomping empty string creates length -1: 229 chomp $str if defined $str; 230 $str; 231} 232sub addhistory {} 233 234# used for testing purpose 235sub devtty { return '/dev/tty' } 236 237sub findConsole { 238 my $console; 239 my $consoleOUT; 240 241 my $devtty = devtty(); 242 243 if ($^O ne 'MSWin32' and -e $devtty) { 244 $console = $devtty; 245 } elsif ($^O eq 'MSWin32' or $^O eq 'msys' or -e "con") { 246 $console = 'CONIN$'; 247 $consoleOUT = 'CONOUT$'; 248 } elsif ($^O eq 'VMS') { 249 $console = "sys\$command"; 250 } elsif ($^O eq 'os2' && !$DB::emacs) { 251 $console = "/dev/con"; 252 } else { 253 $console = undef; 254 } 255 256 $consoleOUT = $console unless defined $consoleOUT; 257 $console = "&STDIN" unless defined $console; 258 if ($console eq $devtty && !open(my $fh, "<", $console)) { 259 $console = "&STDIN"; 260 undef($consoleOUT); 261 } 262 if (!defined $consoleOUT) { 263 $consoleOUT = defined fileno(STDERR) && $^O ne 'MSWin32' ? "&STDERR" : "&STDOUT"; 264 } 265 ($console,$consoleOUT); 266} 267 268sub new { 269 die "method new called with wrong number of arguments" 270 unless @_==2 or @_==4; 271 #local (*FIN, *FOUT); 272 my ($FIN, $FOUT, $ret); 273 if (@_==2) { 274 my($console, $consoleOUT) = $_[0]->findConsole; 275 276 # the Windows CONIN$ needs GENERIC_WRITE mode to allow 277 # a SetConsoleMode() if we end up using Term::ReadKey 278 open FIN, (( $^O eq 'MSWin32' && $console eq 'CONIN$' ) ? '+<' : '<' ), $console; 279 # RT #132008: Still need 2-arg open here 280 open FOUT,">$consoleOUT"; 281 282 #OUT->autoflush(1); # Conflicts with debugger? 283 my $sel = select(FOUT); 284 $| = 1; # for DB::OUT 285 select($sel); 286 $ret = bless [\*FIN, \*FOUT]; 287 } else { # Filehandles supplied 288 $FIN = $_[2]; $FOUT = $_[3]; 289 #OUT->autoflush(1); # Conflicts with debugger? 290 my $sel = select($FOUT); 291 $| = 1; # for DB::OUT 292 select($sel); 293 $ret = bless [$FIN, $FOUT]; 294 } 295 if ($ret->Features->{ornaments} 296 and not ($ENV{PERL_RL} and $ENV{PERL_RL} =~ /\bo\w*=0/)) { 297 local $Term::ReadLine::termcap_nowarn = 1; 298 $ret->ornaments(1); 299 } 300 return $ret; 301} 302 303sub newTTY { 304 my ($self, $in, $out) = @_; 305 $self->[0] = $in; 306 $self->[1] = $out; 307 my $sel = select($out); 308 $| = 1; # for DB::OUT 309 select($sel); 310} 311 312sub IN { shift->[0] } 313sub OUT { shift->[1] } 314sub MinLine { undef } 315sub Attribs { {} } 316 317my %features = (tkRunning => 1, ornaments => 1, 'newTTY' => 1); 318sub Features { \%features } 319 320#sub get_line { 321# my $self = shift; 322# my $in = $self->IN; 323# local ($/) = "\n"; 324# return scalar <$in>; 325#} 326 327package Term::ReadLine; # So late to allow the above code be defined? 328 329our $VERSION = '1.17'; 330 331my ($which) = exists $ENV{PERL_RL} ? split /\s+/, $ENV{PERL_RL} : undef; 332if ($which) { 333 if ($which =~ /\bgnu\b/i){ 334 eval "use Term::ReadLine::Gnu;"; 335 } elsif ($which =~ /\bperl\b/i) { 336 eval "use Term::ReadLine::Perl;"; 337 } elsif ($which =~ /^(Stub|TermCap|Tk)$/) { 338 # it is already in memory to avoid false exception as seen in: 339 # PERL_RL=Stub perl -e'$SIG{__DIE__} = sub { print @_ }; require Term::ReadLine' 340 } else { 341 eval "use Term::ReadLine::$which;"; 342 } 343} elsif (defined $which and $which ne '') { # Defined but false 344 # Do nothing fancy 345} else { 346 eval "use Term::ReadLine::Gnu; 1" or eval "use Term::ReadLine::EditLine; 1" or eval "use Term::ReadLine::Perl; 1"; 347} 348 349#require FileHandle; 350 351# To make possible switch off RL in debugger: (Not needed, work done 352# in debugger). 353our @ISA; 354if (defined &Term::ReadLine::Gnu::readline) { 355 @ISA = qw(Term::ReadLine::Gnu Term::ReadLine::Stub); 356} elsif (defined &Term::ReadLine::EditLine::readline) { 357 @ISA = qw(Term::ReadLine::EditLine Term::ReadLine::Stub); 358} elsif (defined &Term::ReadLine::Perl::readline) { 359 @ISA = qw(Term::ReadLine::Perl Term::ReadLine::Stub); 360} elsif (defined $which && defined &{"Term::ReadLine::$which\::readline"}) { 361 @ISA = "Term::ReadLine::$which"; 362} else { 363 @ISA = qw(Term::ReadLine::Stub); 364} 365 366package Term::ReadLine::TermCap; 367 368# Prompt-start, prompt-end, command-line-start, command-line-end 369# -- zero-width beautifies to emit around prompt and the command line. 370our @rl_term_set = ("","","",""); 371# string encoded: 372our $rl_term_set = ',,,'; 373 374our $terminal; 375sub LoadTermCap { 376 return if defined $terminal; 377 378 require Term::Cap; 379 $terminal = Tgetent Term::Cap ({OSPEED => 9600}); # Avoid warning. 380} 381 382sub ornaments { 383 shift; 384 return $rl_term_set unless @_; 385 $rl_term_set = shift; 386 $rl_term_set ||= ',,,'; 387 $rl_term_set = 'us,ue,md,me' if $rl_term_set eq '1'; 388 my @ts = split /,/, $rl_term_set, 4; 389 eval { LoadTermCap }; 390 unless (defined $terminal) { 391 warn("Cannot find termcap: $@\n") unless $Term::ReadLine::termcap_nowarn; 392 $rl_term_set = ',,,'; 393 return; 394 } 395 @rl_term_set = map {$_ ? $terminal->Tputs($_,1) || '' : ''} @ts; 396 return $rl_term_set; 397} 398 399 400package Term::ReadLine::Tk; 401 402# This package inserts a Tk->fileevent() before the diamond operator. 403# The Tk watcher dispatches Tk events until the filehandle returned by 404# the$term->IN() accessor becomes ready for reading. It's assumed 405# that the diamond operator will return a line of input immediately at 406# that point. 407 408my ($giveup); 409 410# maybe in the future the Tk-specific aspects will be removed. 411sub Tk_loop{ 412 if (ref $Term::ReadLine::toloop) 413 { 414 $Term::ReadLine::toloop->[0]->($Term::ReadLine::toloop->[2]); 415 } 416 else 417 { 418 Tk::DoOneEvent(0) until $giveup; 419 $giveup = 0; 420 } 421}; 422 423sub register_Tk { 424 my $self = shift; 425 unless ($Term::ReadLine::registered++) 426 { 427 if (ref $Term::ReadLine::toloop) 428 { 429 $Term::ReadLine::toloop->[2] = $Term::ReadLine::toloop->[1]->($self->IN) if $Term::ReadLine::toloop->[1]; 430 } 431 else 432 { 433 Tk->fileevent($self->IN,'readable',sub { $giveup = 1}); 434 } 435 } 436}; 437 438sub tkRunning { 439 $Term::ReadLine::toloop = $_[1] if @_ > 1; 440 $Term::ReadLine::toloop; 441} 442 443sub event_loop { 444 shift; 445 446 # T::RL::Gnu and T::RL::Perl check that this exists, if not, 447 # it doesn't call the loop. Those modules will need to be 448 # fixed before this can be removed. 449 if (not defined &Tk::DoOneEvent) 450 { 451 *Tk::DoOneEvent = sub { 452 die "what?"; # this shouldn't be called. 453 } 454 } 455 456 # store the callback in toloop, again so that other modules will 457 # recognise it and call us for the loop. 458 $Term::ReadLine::toloop = [ @_ ] if @_ > 0; # 0 because we shifted off $self. 459 $Term::ReadLine::toloop; 460} 461 462sub PERL_UNICODE_STDIN () { 0x0001 } 463 464sub get_line { 465 my $self = shift; 466 my ($in,$out,$str) = @$self; 467 468 if ($Term::ReadLine::toloop) { 469 $self->register_Tk if not $Term::ReadLine::registered; 470 $self->Tk_loop; 471 } 472 473 local ($/) = "\n"; 474 $str = <$in>; 475 476 utf8::upgrade($str) 477 if (${^UNICODE} & PERL_UNICODE_STDIN || defined ${^ENCODING}) && 478 utf8::valid($str); 479 print $out $rl_term_set[3]; 480 # bug in 5.000: chomping empty string creates length -1: 481 chomp $str if defined $str; 482 483 $str; 484} 485 4861; 487 488