File Coverage

lib/Term/ReadLine/Perl5/OO/History.pm
Criterion Covered Total %
statement 71 90 78.8
branch 13 24 54.1
condition 4 15 26.6
subroutine 15 19 78.9
pod 13 14 92.8
total 116 162 71.6


line stmt bran cond sub pod time code
1             # Copyright (C) 2014 Rocky Bernstein
2             package Term::ReadLine::Perl5::OO::History;
3             =pod
4              
5             =head1 NAME
6              
7             Term::ReadLine::Perl5::OO:History
8              
9             =head1 DESCRIPTION
10              
11             Variables and functions supporting L's and
12             L's command history.
13              
14             =cut
15              
16 11     11   80 use warnings; use strict;
  11     11   28  
  11         368  
  11         64  
  11         42  
  11         383  
17              
18             =head1 SUBROUTINES
19              
20             =head2 add_line_to_history
21              
22             #B(I<$line>, I<$minlength>)
23              
24             Insert I<$line> into history list if I<$line> is:
25              
26             =over
27              
28             =item *
29              
30             bigger than the minimal length I<$minlength>
31              
32             =item *
33              
34             not same as last entry
35              
36             =back
37              
38             =cut
39              
40 11     11   816 use File::HomeDir; use File::Spec;
  11     11   9231  
  11         698  
  11         84  
  11         31  
  11         11001  
41             my $HOME = File::HomeDir->my_home;
42              
43             sub add_line_to_history
44             {
45 0     0 1 0 my ($self, $line, $minlength) = @_;
46 0         0 my $rl_History = $self->{rl_History};
47 0         0 my $rl_MaxHistorySize = $self->{rl_MaxHistorySize};
48 0 0 0     0 if (length($line) >= $minlength
      0        
49             && (!@$rl_History || $rl_History->[$#$rl_History] ne $line)
50             ) {
51             ## if the history list is full, shift out an old one first....
52 0         0 while (@$rl_History >= $self->{rl_MaxHistorySize}) {
53 0         0 shift(@$rl_History);
54 0         0 $self->{rl_HistoryIndex}--;
55             }
56              
57 0         0 push(@$rl_History, $line); ## tack new one on the end
58             }
59             }
60              
61             =head2 add_history
62              
63             #B(I<$line1>, ...)
64              
65             Place lines in array I<@_> at the end of the history list unless the
66             history is stifled, or there are already too many items.
67              
68             =cut
69              
70             sub add_history {
71 8     8 1 33 my $self = shift;
72 8 100 66     40 if ($self->{history_stifled} &&
73             ($self->{rl_history_length} ==
74             $self->{rl_max_input_history})) {
75             # If the history is stifled, and history_length is zero,
76             # and it equals max_input_history, we don't save items.
77 1 50       4 return if $self->{rl_max_input_history} == 0;
78 1         2 shift @{$self->{rl_History}};
  1         3  
79             }
80 8         13 push @{$self->{rl_History}}, @_;
  8         25  
81 8         19 $self->{rl_HistoryIndex} += scalar @_;
82 8         15 $self->{rl_history_length} = scalar @{$self->{rl_History}};
  8         16  
83             }
84              
85              
86             =head2 read_history
87              
88             #B(I<$filename>)
89              
90             Add the contents of I<$filename> to the history list, a line at a time. If
91             filename is undef, then read from `~/.history'. Returns 0 if
92             successful, or I<$!> if not.
93              
94             =cut
95              
96             sub read_history($;$) {
97 2     2 1 7 my ($self, $filename) = @_;
98 2 50       8 $filename = File::Spec->catfile($HOME, '.history') unless $filename;
99 2         8 my @history;
100 2 50       60 open(my $fh, '<:encoding(utf-8)', $filename ) or return $!;
101 2         235 while (my $hist = <$fh>) {
102 5         21 chomp($hist);
103 5         19 push @history, $hist;
104             };
105             # Use non OO form since this can be called in a non-OO way.
106 2         9 SetHistory($self, @history);
107 2         19 close $fh;
108 2         15 return 0;
109             }
110              
111             =head2 remove_history
112              
113             #B(I, I<$which>)
114              
115             Remove history element C<$which> from the history. The removed
116             element is returned.
117              
118             =cut
119              
120             sub remove_history($$) {
121 1     1 1 6 my ($self, $which) = @_;
122             return undef if
123 1 50 33     18 $which < 0 || $which >= $self->{rl_history_length};
124 1         4 my $removed = splice @{$self->{rl_History}}, $which, 1;
  1         7  
125 1         4 $self->{rl_history_length}--;
126             $self->{rl_HistoryIndex} =
127             $self->{rl_history_length} if
128             $self->{rl_history_length} <
129 1 50       5 $self->{rl_HistoryIndex};
130 1         3 return $removed;
131             }
132              
133             =head2 GetHistory
134              
135             B
136              
137             returns the history of input as a list.
138              
139             =cut
140              
141             sub GetHistory {
142 8     8 1 22 my $self = shift;
143 8         19 @{$self->{rl_History}};
  8         73  
144             }
145              
146             =head2 SetHistory
147              
148             #B(I<$line1> [, I<$line2>, ...])
149              
150             Sets the history of input, from where it can be used.
151              
152             =cut
153              
154             sub SetHistory {
155 7     7 1 18 my $self = shift;
156 7         25 $self->{rl_History} = \@_;
157             $self->{rl_HistoryIndex} =
158 7         29 $self->{rl_history_length} = $self->{rl_max_input_history} = scalar(@_);
159             }
160              
161             =head2 history_is_stifled
162              
163             C
164              
165             Returns I if saved history has a limited (stifled) or I
166             if there is no limit (unstifled).
167              
168             =cut
169              
170             sub history_is_stifled {
171 5     5 1 8 my ($self) = shift;
172 5 100       28 $self->{history_stifled} ? 1 : 0;
173             }
174              
175             =head2 unstifle_history
176              
177             C
178              
179             Unstifle or remove limit the history list.
180              
181             Theprevious maximum number of history entries is returned. The value
182             is positive if the history was stifled and negative if it wasn't.
183              
184             =cut
185              
186             sub unstifle_history($) {
187 1     1 1 2 my $self = shift;
188 1 50       3 if ($self->{history_stifled}) {
189 1         2 $self->{history_stifled }= 0;
190 1         3 return (scalar @{$self->{rl_History}});
  1         3  
191             } else {
192 0         0 return - scalar @{$self->{rl_History}};
  0         0  
193             }
194             }
195              
196             =head2 replace_history_entry
197              
198             #B, I<$data>)>
199              
200             Make the history entry at I<$which> have I<$data>. This returns the old
201             entry. In the case of an invalid I<$which>, I is returned.
202              
203             =cut
204              
205             sub replace_history_entry {
206 1     1 1 3 my $self = shift;
207 1         3 my ($which, $data) = @_;
208 1 50 33     9 return undef if $which < 0 || $which >= $self->{rl_history_length};
209 1         3 my $replaced = splice @{$self->{rl_History}}, $which, 1, $data;
  1         4  
210 1         3 return $replaced;
211             }
212              
213             =head2 clear_history
214              
215             #B()
216              
217             Clear or reset readline history.
218              
219             =cut
220              
221             sub clear_history($) {
222 0     0 1 0 my $self = shift;
223 0         0 $self->{rl_History} = [];
224             $self->{rl_HistoryIndex} =
225 0         0 $self->{rl_history_length} = 0;
226             }
227              
228             sub history_list($)
229             {
230 0     0 0 0 my $self = shift;
231 0         0 my @rl_History = @{$self->{rl_History}};
  0         0  
232 0         0 @rl_History[1..$#rl_History]
233             }
234              
235             =head2 write_history
236             #B(I<$filename>)
237              
238             Write the current history to filename, overwriting filename if
239             necessary. If filename is NULL, then write the history list to
240             `~/.history'. Returns 0 on success, or errno on a read or write error.
241              
242             I and I follow GNU Readline's C
243             convention of returning 0 for success and 1 for failure.
244              
245             =cut
246              
247             sub write_history($$) {
248 2     2 1 9 my ($self, $filename) = @_;
249 2 50   1   127 open(my $fh, '>:encoding(utf-8)', $filename ) or return $!;
  1         10  
  1         3  
  1         9  
250 2         12110 for my $hist (@{$self->{rl_History}}) {
  2         11  
251 5 50       32 next unless $hist =~ /\S/;
252 5         25 print $fh $hist . "\n";
253             }
254 2         108 close $fh;
255 2         16 return 0;
256             }
257              
258             =head2 ReadHistory
259              
260             #B([I<$filename> [,I<$from> [,I<$to>]]])
261              
262             $i = ReadHistory('~/.history')
263              
264             Adds the contents of I<$filename> to the history list, a line at a
265             time. If $ is false, then read from F<~/.history>. Start
266             reading at line I<$from> and end at I<$to>. If I<$from> is omitted or
267             zero, start at the beginning. If I<$to> is omitted or less than
268             I<$from>, then read until the end of the file. Returns true if
269             successful, or false if not.
270              
271             I the return code is the negation of
272             L. Otherwise, it's the same.
273              
274             =cut
275              
276             sub ReadHistory {
277 0     0 1 0 my ($self, $filename) = @_;
278             # Use non-OO form since this can be called in a non-OO way
279 0         0 ! read_history($self, $filename);
280             }
281              
282             =head2 WriteHistory
283              
284             #B([I<$filename>])
285              
286             $i = WriteHistory('~/.history')
287              
288             Writes the current history to I<$filename>, overwriting I<$filename>
289             if necessary. If I<$filename> is false, then write the history list
290             to F<~/.history>. Returns true if successful, or false if
291             not. I the return code is the negation of
292             L. Otherwise, it's the same.
293              
294             =cut
295              
296             sub WriteHistory {
297             # Use non-OO form since this can be called in a non-OO way
298 1     1 1 6 my ($self, $filename) = @_;
299 1         11 ! write_history($self, $filename);
300             }
301             =head1 AUTHOR
302              
303             Rocky Bernstein
304              
305             =head1 SEE ALSO
306              
307             L
308              
309             =cut
310              
311             1;