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