File Coverage

lib/Term/ReadLine/Perl5.pm
Criterion Covered Total %
statement 80 104 76.9
branch 17 34 50.0
condition 6 18 33.3
subroutine 20 24 83.3
pod 9 11 81.8
total 132 191 69.1


line stmt bran cond sub pod time code
1             # -*- Perl -*-
2             package Term::ReadLine::Perl5;
3             =encoding utf8
4              
5             =head1 Name
6              
7             Term::ReadLine::Perl5 - A Perl5 implementation GNU Readline
8              
9             =head2 Overview
10              
11             This is a implementation of the GNU Readline/History Library written
12             in Perl5.
13              
14             GNU Readline reads lines from an interactive terminal with I or
15             I editing capabilities. It provides as mechanism for saving
16             history of previous input.
17              
18             This package typically used in command-line interfaces and REPLs (Read,
19             Eval, Print, Loop).
20              
21             =head2 Demo program
22              
23             Another package, L is available to let
24             you run I to experiment with its capabilities
25             and show how to use the API.
26              
27             =head1 Synopsis
28              
29             use Term::ReadLine::Perl5;
30             $term = Term::ReadLine::Perl5->new('ProgramName');
31             while ( defined ($_ = $term->readline('prompt>')) ) {
32             ...
33             }
34              
35             =cut
36              
37 9     9   555526 use warnings; use strict;
  9     9   114  
  9         381  
  9         66  
  9         19  
  9         262  
38 9     9   5509 use Term::ReadLine::Perl5::readline;
  9         33  
  9         1739  
39 9     9   148 no warnings 'once';
  9         23  
  9         587  
40              
41             our $VERSION = '1.45';
42              
43 9     9   57 use Carp;
  9         19  
  9         631  
44 9     9   80 eval "use rlib '.' "; # rlib is now optional
  9         30  
  9         77  
45 9     9   60 use Term::ReadLine::Perl5::History;
  9         21  
  9         1178  
46 9     9   3582 use Term::ReadLine::Perl5::OO;
  9         41  
  9         353  
47 9     9   67 use Term::ReadLine::Perl5::OO::History;
  9         21  
  9         211  
48 9     9   2875 use Term::ReadLine::Perl5::Tie;
  9         30  
  9         299  
49 9     9   67 use Term::ReadLine::Perl5::readline;
  9         23  
  9         1332  
50              
51 9     9   67 use vars qw($editMode);
  9         25  
  9         12927  
52              
53             if (require Term::ReadLine) {
54             our @ISA = qw(Term::ReadLine::Stub Exporter);
55             }
56             my (%attribs, $term);
57              
58             our @EXPORT = qw(IN OUT);
59              
60              
61             =head2 Variables
62              
63             Following GNU Readline/History Library variables can be accessed from
64             Perl program. See 'GNU Readline Library Manual' and ' GNU History
65             Library Manual' for each variable. You can access them via the
66             C method. Names of keys in this hash conform to standard
67             conventions with the leading C stripped.
68              
69             Example:
70              
71             $term = Term::ReadLine::Perl5->new('ReadLineTest');
72             $attribs = $term->Attribs;
73             $v = $attribs->{history_base}; # history_base
74              
75             =head3 Attribute Names
76              
77             completion_suppress_append (bool)
78             history_base (int)
79             history_stifled (int)
80             max_input_history (int)
81             outstream (file handle)
82              
83             =cut
84              
85             my %features = (
86             appname => 1, # "new" is recognized
87             minline => 1, # we have a working MinLine()
88             autohistory => 1, # lines are put into history automatically,
89             # subject to MinLine()
90             getHistory => 1, # we have a working getHistory()
91             setHistory => 1, # we have a working setHistory()
92             addHistory => 1, # we have a working add_history(), addhistory(),
93             # or addHistory()
94             readHistory => 1, # we have read_history() or readHistory()
95             writeHistory => 1, # we have writeHistory()
96             preput => 1, # the second argument to readline is processed
97             attribs => 1,
98             newTTY => 1, # we have newTTY()
99             stiflehistory => 1, # we have stifle_history()
100             );
101              
102             tie %attribs, 'Term::ReadLine::Perl5::Tie' or die ;
103             sub Attribs {
104 3     3 0 2851 \%attribs;
105             }
106              
107             =head1 Subroutine
108              
109             =head2 Standard Term::ReadLine Methods
110              
111             These methods are standard methods defined by
112             L.
113              
114             =head3 C
115              
116             Readline() -> 'Term::ReadLine::Perl5'
117              
118             returns the actual package that executes the commands. If this package
119             is used, the value is C.
120              
121             =cut
122              
123 2     2 1 561 sub ReadLine {'Term::ReadLine::Perl5'}
124              
125              
126             =head3 readline
127              
128             $bool = $term->readline($prompt, $default)
129              
130             The main routine to call interactively read lines. Parameter
131             I<$prompt> is the text you want to prompt with If it is empty string,
132             no preceding prompt text is given. It is I a default value of
133             "INPUT> " is used.
134              
135             Parameter I<$default> is the default value; it can be can be
136             omitted. The next input line is returned or I on EOF.
137              
138             =cut
139              
140             sub readline {
141 0     0 1 0 shift;
142 0         0 &Term::ReadLine::Perl5::readline::readline(@_);
143             }
144              
145             sub editModeFromShell() {
146 9     9 0 37754 my @shell_settings = `$ENV{'SHELL'} -c 'set -o'`;
147 9         212 my $use_vi = grep /vi\ton\n/, @shell_settings;
148 9 50       262 return $use_vi ? 'vicmd' : 'emacs';
149             }
150              
151             $editMode = 'emacs';
152             eval {$editMode = editModeFromShell};
153              
154             =head3 new
155              
156             B(I<$name>,[I[,I]])
157              
158             returns the handle for subsequent calls to following functions.
159             Argument is the name of the application. Optionally can be followed
160             by two arguments for C and C file handles. These arguments
161             should be globs.
162              
163             I<$name> is the name of the application.
164              
165             This routine may also get called via
166             Cnew($term_name)> if you have
167             C<$ENV{PERL_RL}> set to 'Perl5';
168              
169             At present, because this code has lots of global state, we currently don't
170             support more than one readline instance.
171              
172             =cut
173              
174             sub new {
175 3     3 1 1491 my $class = shift;
176 3 50       38 if (require Term::ReadLine) {
177 3         31 $features{tkRunning} = Term::ReadLine::Stub->Features->{'tkRunning'};
178 3         37 $features{ornaments} = Term::ReadLine::Stub->Features->{'ornaments'};
179             }
180 3 50       29 if (defined $term) {
181 0         0 my $stderr = $Term::ReadLine::Perl5::readline::term_OUT;
182 0         0 print $stderr "Cannot create second readline interface\n";
183 0         0 print "Using experimental OO interface based on Caroline\n";
184 0         0 my ($name, $in, $out) = @_;
185 0         0 my $opts = {
186             name => $name,
187             in => $in,
188             out => $out,
189             editMode => $editMode,
190             };
191 0         0 return Term::ReadLine::Perl5::OO->new($opts);
192             }
193 3         30 Term::ReadLine::Perl5::readline::preinit($editMode);
194 3         15 Term::ReadLine::Perl5::readline::init();
195              
196              
197 3         14 shift; # Package name
198 3 50       23 if (@_) {
199 0 0       0 if ($term) {
200 0 0       0 warn "Ignoring name of second readline interface.\n"
201             if defined $term;
202 0         0 shift;
203             } else {
204             # Set Name
205 0         0 $Term::ReadLine::Perl5::readline::rl_readline_name = shift;
206             }
207             }
208 3 50       22 if (!@_) {
209 3 50       17 if (!defined $term) {
210 3         67 my ($IN,$OUT) = Term::ReadLine->findConsole();
211             # Old Term::ReadLine did not have a workaround for a bug
212             # in Win devdriver
213 3 50 33     211 $IN = 'CONIN$' if $^O eq 'MSWin32' and "\U$IN" eq 'CON';
214 3 50 33     83 open(my $in_fh,
    50          
215             # A workaround for another bug in Win device driver
216             (($IN eq 'CONIN$' and $^O eq 'MSWin32') ? "+< $IN" : "< $IN"))
217             or croak "Cannot open $IN for read";
218 3 50       50 open(my $out_fh, ">$OUT") || croak "Cannot open $OUT for write: $!";
219 3         13 $Term::ReadLine::Perl5::readline::term_IN = $in_fh;
220 3         13 $Term::ReadLine::Perl5::readline::term_OUT = $out_fh;
221             }
222             } else {
223 0 0 0     0 if (defined $term and ($term->IN ne $_[0] or $term->OUT ne $_[1]) ) {
      0        
224 0         0 croak "Request for a second readline interface with different terminal";
225             }
226 0         0 $Term::ReadLine::Perl5::readline::term_IN = shift;
227 0         0 $Term::ReadLine::readline::term_OUT = shift
228             }
229             # FIXME? In https://github.com/rocky/p5-Term-ReadLine-Perl5/pull/12
230             # aferreira notes that the below should probably be something like
231             # $term = bless [$Term::ReadLine::readline::term_IN,
232             # $Term::ReadLine::readline::term_OUT];
233             # The following is here since it is mostly used for perl input:
234             # $readline::rl_basic_word_break_characters .= '-:+/*,[])}';
235 3         182 $term = bless [$readline::term_IN,$readline::term_OUT];
236 3         32 my $self = {
237             'IN' => $Term::ReadLine::Perl5::readline::term_IN,
238             'OUT' => $Term::ReadLine::Perl5::readline::term_OUT,
239             };
240 3         20 bless $self, $class;
241              
242 3 50 66     44 unless ($ENV{PERL_RL} and $ENV{PERL_RL} =~ /\bo\w*=0/) {
243 3         15 local $Term::ReadLine::termcap_nowarn = 1; # With newer Perls
244 3     0   47 local $SIG{__WARN__} = sub {}; # With older Perls
245 3         55 $term->ornaments(1);
246             }
247              
248             # FIXME: something rl_term_set in here causes terminal attributes
249             # like bold and underline to work.
250 3         37507 Term::ReadLine::Perl5::readline::rl_term_set();
251              
252 3         31 return $self;
253             }
254              
255             =head3 IN
256              
257             $term->IN
258              
259             Returns the input filehandle or C.
260              
261             =cut
262              
263             sub IN {
264 0     0 1 0 my ($self) = @_;
265 0         0 $self->{IN};
266             }
267              
268             =head3 OUT
269              
270             $term->OUT
271              
272             Returns the output filehandle or C.
273              
274             =cut
275              
276             sub OUT {
277 1     1 1 41 my ($self) = @_;
278 1         15 $self->{OUT};
279             }
280              
281              
282             =head3 newTTY
283              
284             BnewTTY>(I, I)
285              
286             takes two arguments which are input filehandle and output filehandle.
287             Switches to use these filehandles.
288              
289             =cut
290              
291             sub newTTY($$$) {
292 0     0 1 0 my ($self, $in, $out) = @_;
293 0         0 $Term::ReadLine::Perl5::readline::term_IN = $self->{'IN'} = $in;
294 0         0 $Term::ReadLine::Perl5::readline::term_OUT = $self->{'OUT'} = $out;
295 0         0 my $sel = select($out);
296 0         0 $| = 1; # for DB::OUT
297 0         0 select($sel);
298             }
299              
300             =head3 Minline
301              
302             B([I<$minlength>])>
303              
304             If B<$minlength> is given, set C<$readline::minlength> the minimum
305             length a $line for it to go into the readline history.
306              
307             The previous value is returned.
308              
309             =cut
310              
311             sub MinLine($;$) {
312 4     4 1 708 my $old = $minlength;
313 4 100       17 $minlength = $_[1] if @_ == 2;
314 4         22 return $old;
315             }
316              
317             #################### History ##########################################
318              
319             =head3 add_history
320              
321             $term->add_history>($line1, $line2, ...)
322              
323             adds the lines, I<$line1>, etc. to the input history list.
324              
325             I is an alias for this function.
326              
327             =cut
328              
329             # GNU ReadLine names
330             *add_history = \&Term::ReadLine::Perl5::History::add_history;
331             *remove_history = \&Term::ReadLine::Perl5::History::remove_history;
332             *replace_history_entry = \&Term::ReadLine::Perl5::History::replace_history_entry;
333              
334             *clear_history = \&Term::ReadLine::Perl5::History::clear_history;
335              
336             *history_is_stifled = \&Term::ReadLine::Perl5::History::history_is_stifled;
337             *read_history = \&Term::ReadLine::Perl5::History::read_history;
338             *unstifle_history = \&Term::ReadLine::Perl5::History::unstifle_history;
339             *write_history = \&Term::ReadLine::Perl5::History::write_history;
340              
341             # Not sure about the difference between history_list and GetHistory.
342             *history_list = \&Term::ReadLine::Perl5::OO::GetHistory;
343              
344             *rl_History = *Term::ReadLine::Perl5::rl_History;
345              
346              
347             # Some Term::ReadLine::Gnu names
348             *AddHistory = \&add_history;
349             *GetHistory = \&Term::ReadLine::Perl5::History::GetHistory;
350             *SetHistory = \&Term::ReadLine::Perl5::History::SetHistory;
351             *ReadHistory = \&Term::ReadLine::Perl5::History::ReadHistory;
352             *WriteHistory = \&Term::ReadLine::Perl5::History::WriteHistory;
353              
354             # Backward compatibility:
355             *addhistory = \&add_history;
356             *StifleHistory = \&stifle_history;
357              
358             =head3 stifle_history
359              
360             $term->stifle_history($max)
361              
362             Stifle or put a cap on the history list, remembering only C<$max>
363             number of lines.
364              
365             I is an alias for this function.
366              
367             =cut
368              
369             ### FIXME: stifle_history is still here because it updates $attribs.
370             ## Pass a reference?
371             sub stifle_history($$) {
372 3     3 1 12 my ($self, $max) = @_;
373 3 100 66     25 $max = 0 if !defined($max) || $max < 0;
374              
375 3 100       11 if (scalar @rl_History > $max) {
376 2         6 splice @rl_History, $max;
377 2         19 $attribs{history_length} = scalar @rl_History;
378             }
379              
380 3         34 $Term::ReadLine::Perl5::History::history_stifled = 1;
381 3         20 $attribs{max_input_history} = $self->{rl_max_input_history} = $max;
382             }
383              
384             =head3 Features
385              
386             B
387              
388             Returns a reference to a hash with keys being features present in
389             current implementation. Several optional features are used in the
390             minimal interface:
391              
392             =over
393              
394             =item *
395             I is present if you can add lines to history list via
396             the I method
397              
398             =item *
399             I is be present if a name, the first argument
400             to I was given
401              
402             =item *
403             I is present if lines are put into history automatically
404             subject to the line being longer than I.
405              
406             =item *
407             I is present if we get retrieve history via the I
408             method
409              
410             =item *
411             I is present if the I method available.
412              
413             =item *
414             I is present if the second argument to I method can
415             append text to the input to be read subsequently
416              
417             =item *
418             I is present you can read history
419             items previosly saved in a file.
420              
421             =item *
422             I is present if we can set history
423              
424             =item *
425             I is present you can put a limit of the nubmer of history
426             items to save via the I method
427              
428             =item *
429             I is present if a Tk application may run while I is
430             getting input.
431              
432             =item *
433             I is present you can save history to a file via the
434             I method
435              
436             =back
437              
438             =cut
439              
440 1     1 1 23 sub Features { \%features; }
441              
442             =head1 See also
443              
444             =over
445              
446             =item *
447              
448             L is the newer but unfinished fully OO version.
449              
450             =item *
451              
452             L is the first try at the OO package that most
453             programmers will use.
454              
455             =item *
456              
457             L is guide to the guts of the
458             non-OO portion of L
459              
460             =item *
461              
462             L describes the history
463             mechanism
464              
465             =item *
466              
467             L is a generic package which can be used to
468             select this among other compatible GNU Readline packages.
469              
470             =back
471              
472             =cut
473              
474             1;