| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
# -*- perl -*- |
|
2
|
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
# Copyright (c) 2004 by Jeff Weisberg |
|
4
|
|
|
|
|
|
|
# Author: Jeff Weisberg |
|
5
|
|
|
|
|
|
|
# Created: 2004-Jun-03 10:24 (EDT) |
|
6
|
|
|
|
|
|
|
# Function: pager like more/less |
|
7
|
|
|
|
|
|
|
# |
|
8
|
|
|
|
|
|
|
# $Id: Pager.pm,v 1.4 2012/12/02 18:06:46 jaw Exp $ |
|
9
|
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
=head1 NAME |
|
11
|
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
Term::Pager - Page through text, a screenful at a time, like more or less |
|
13
|
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
=head1 SYNOPSIS |
|
15
|
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
use Term::Pager; |
|
17
|
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
my $t = Term::Pager->new( rows => 25, cols => 80 ); |
|
19
|
|
|
|
|
|
|
$t->add_text( $text ); |
|
20
|
|
|
|
|
|
|
$t->more(); |
|
21
|
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
=head1 DESCRIPTION |
|
23
|
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
This is a module for paging through text one screenful at a time. |
|
25
|
|
|
|
|
|
|
It supports the features you expect, including backwards |
|
26
|
|
|
|
|
|
|
movement and searching. It uses the keys you expect. |
|
27
|
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
=head1 USAGE |
|
29
|
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
=head2 Create the Pager |
|
31
|
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
$t = Term::Pager->new( option => value, ... ); |
|
33
|
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
If no options are specified, sensible default values will be used. |
|
35
|
|
|
|
|
|
|
The following options are recognized: |
|
36
|
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
=over 4 |
|
38
|
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
=item C |
|
40
|
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
The number of rows on your terminal. |
|
42
|
|
|
|
|
|
|
This defaults to 25. |
|
43
|
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
=item C |
|
45
|
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
The number of columns on your terminal. |
|
47
|
|
|
|
|
|
|
This defaults to 80. |
|
48
|
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
=item C |
|
50
|
|
|
|
|
|
|
|
|
51
|
|
|
|
|
|
|
The speed (baud rate) of your terminal. Will default |
|
52
|
|
|
|
|
|
|
to a sensible value. |
|
53
|
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
=back |
|
55
|
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
=head2 Adding Text |
|
57
|
|
|
|
|
|
|
|
|
58
|
|
|
|
|
|
|
You will need some text to page through. You can specify text as |
|
59
|
|
|
|
|
|
|
as a parameter to the constructor: |
|
60
|
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
text => $text |
|
62
|
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
Or add text later: |
|
64
|
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
$t->add_text( $text ); |
|
66
|
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
=cut |
|
68
|
|
|
|
|
|
|
; |
|
69
|
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
package Term::Pager; |
|
71
|
|
|
|
|
|
|
$VERSION = '1.02'; |
|
72
|
|
|
|
|
|
|
|
|
73
|
1
|
|
|
1
|
|
1407
|
use Term::Cap; |
|
|
1
|
|
|
|
|
2804
|
|
|
|
1
|
|
|
|
|
26
|
|
|
74
|
1
|
|
|
1
|
|
6
|
use strict; |
|
|
1
|
|
|
|
|
1
|
|
|
|
1
|
|
|
|
|
2313
|
|
|
75
|
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
sub new { |
|
77
|
0
|
|
|
0
|
0
|
|
my $class = shift; |
|
78
|
0
|
|
|
|
|
|
my %param = @_; |
|
79
|
|
|
|
|
|
|
|
|
80
|
0
|
|
0
|
|
|
|
my $t = Term::Cap->Tgetent({ OSPEED => ($param{speed} || 38400) }); |
|
81
|
0
|
|
|
|
|
|
my $dumbp; |
|
82
|
|
|
|
|
|
|
|
|
83
|
0
|
|
|
|
|
|
eval{ |
|
84
|
0
|
|
|
|
|
|
$t->Trequire(qw/cm ce cl sf sr/); |
|
85
|
|
|
|
|
|
|
}; |
|
86
|
0
|
0
|
|
|
|
|
$dumbp = 1 if $@; |
|
87
|
|
|
|
|
|
|
|
|
88
|
0
|
|
|
|
|
|
my $me = bless { |
|
89
|
|
|
|
|
|
|
# default values |
|
90
|
|
|
|
|
|
|
term => $t, |
|
91
|
|
|
|
|
|
|
cols => 80, |
|
92
|
|
|
|
|
|
|
rows => 25, |
|
93
|
|
|
|
|
|
|
dumbp => $dumbp, |
|
94
|
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
# if the termcap entries don't exist, nothing bad will happen |
|
96
|
|
|
|
|
|
|
HI => $t->Tputs('md') . $t->Tputs('us'), # search hilight |
|
97
|
|
|
|
|
|
|
SE => $t->Tputs('md') . $t->Tputs('us'), # search entry |
|
98
|
|
|
|
|
|
|
MN => $t->Tputs('md') . $t->Tputs('mr'), # popup menus |
|
99
|
|
|
|
|
|
|
ML => $t->Tputs('mr'), # mode line |
|
100
|
|
|
|
|
|
|
NO => $t->Tputs('me'), # normal |
|
101
|
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
# user supplied values override |
|
103
|
|
|
|
|
|
|
%param, |
|
104
|
|
|
|
|
|
|
}, $class; |
|
105
|
|
|
|
|
|
|
|
|
106
|
0
|
|
|
|
|
|
$me->{fnc} = { |
|
107
|
|
|
|
|
|
|
"\n"=> \&downline, |
|
108
|
|
|
|
|
|
|
' ' => \&downpage, |
|
109
|
|
|
|
|
|
|
'd' => \&downhalf, |
|
110
|
|
|
|
|
|
|
'q' => \&done, |
|
111
|
|
|
|
|
|
|
'b' => \&uppage, |
|
112
|
|
|
|
|
|
|
'y' => \&upline, |
|
113
|
|
|
|
|
|
|
'u' => \&uphalf, |
|
114
|
|
|
|
|
|
|
'r' => \&refresh, |
|
115
|
|
|
|
|
|
|
'h' => \&help, |
|
116
|
|
|
|
|
|
|
'?' => \&help, |
|
117
|
|
|
|
|
|
|
'0' => \&to_top, |
|
118
|
|
|
|
|
|
|
'g' => \&to_bott, |
|
119
|
|
|
|
|
|
|
'$' => \&to_bott, # ' |
|
120
|
|
|
|
|
|
|
'/' => \&search, |
|
121
|
|
|
|
|
|
|
'<' => \&move_left, |
|
122
|
|
|
|
|
|
|
'>' => \&move_right, |
|
123
|
|
|
|
|
|
|
}; |
|
124
|
|
|
|
|
|
|
|
|
125
|
0
|
|
|
|
|
|
$me; |
|
126
|
|
|
|
|
|
|
} |
|
127
|
|
|
|
|
|
|
|
|
128
|
|
|
|
|
|
|
sub add_text { |
|
129
|
0
|
|
|
0
|
0
|
|
my $me = shift; |
|
130
|
0
|
|
|
|
|
|
my $tx = shift; |
|
131
|
|
|
|
|
|
|
|
|
132
|
0
|
|
|
|
|
|
$me->{text} .= $tx; |
|
133
|
|
|
|
|
|
|
} |
|
134
|
|
|
|
|
|
|
|
|
135
|
|
|
|
|
|
|
sub add_func { |
|
136
|
0
|
|
|
0
|
0
|
|
my $me = shift; |
|
137
|
0
|
|
|
|
|
|
my $fn = shift; |
|
138
|
0
|
|
|
|
|
|
my $fc = shift; |
|
139
|
|
|
|
|
|
|
|
|
140
|
0
|
|
|
|
|
|
$me->{fnc}{$fn} = $fc; |
|
141
|
|
|
|
|
|
|
} |
|
142
|
|
|
|
|
|
|
|
|
143
|
|
|
|
|
|
|
sub more { |
|
144
|
0
|
|
|
0
|
0
|
|
my $me = shift; |
|
145
|
0
|
|
|
|
|
|
my $sp = $|; |
|
146
|
0
|
|
|
|
|
|
my $t = $me->{term}; |
|
147
|
|
|
|
|
|
|
|
|
148
|
0
|
|
|
|
|
|
$me->{L} = $me->{rows} - 1; |
|
149
|
0
|
|
|
|
|
|
$me->{l} = [ split /\n/, $me->{text} ]; |
|
150
|
0
|
|
|
|
|
|
$me->{nl}= @{ $me->{l} }; |
|
|
0
|
|
|
|
|
|
|
|
151
|
|
|
|
|
|
|
|
|
152
|
0
|
|
|
|
|
|
$me->{start} = 0; |
|
153
|
0
|
|
|
|
|
|
$me->{end} = $me->{L} - 1; |
|
154
|
|
|
|
|
|
|
|
|
155
|
0
|
|
|
|
|
|
$SIG{INT} = $SIG{QUIT} = \&done; |
|
156
|
0
|
|
|
|
|
|
system('stty -icanon -echo min 1'); |
|
157
|
0
|
|
|
|
|
|
$| = 1; |
|
158
|
|
|
|
|
|
|
|
|
159
|
0
|
|
|
|
|
|
eval { |
|
160
|
0
|
0
|
|
|
|
|
if( $me->{dumbp} ){ |
|
161
|
0
|
|
|
|
|
|
$me->dumb_mode(); |
|
162
|
|
|
|
|
|
|
}else{ |
|
163
|
0
|
|
|
|
|
|
print $me->{NO}; |
|
164
|
0
|
|
|
|
|
|
$me->refresh(); |
|
165
|
|
|
|
|
|
|
|
|
166
|
0
|
|
|
|
|
|
while(1){ |
|
167
|
0
|
|
|
|
|
|
print $t->Tgoto('cm', 0, $me->{L}); # bottom left |
|
168
|
0
|
|
|
|
|
|
print $t->Tputs('ce'); # clear line |
|
169
|
|
|
|
|
|
|
|
|
170
|
0
|
|
|
|
|
|
print $me->{ML}; # reverse video |
|
171
|
0
|
|
|
|
|
|
$me->prompt(); |
|
172
|
0
|
|
|
|
|
|
print $me->{NO}; # normal video |
|
173
|
|
|
|
|
|
|
|
|
174
|
0
|
|
|
|
|
|
my $q = getc(); |
|
175
|
|
|
|
|
|
|
|
|
176
|
0
|
|
|
|
|
|
print $t->Tgoto('cm', 0, $me->{L}); # bottom left |
|
177
|
0
|
|
|
|
|
|
print $t->Tputs('ce'); # clear line |
|
178
|
|
|
|
|
|
|
|
|
179
|
0
|
|
|
|
|
|
$me->{msg} = ''; |
|
180
|
0
|
|
0
|
|
|
|
my $f = $me->{fnc}->{lc($q)} || \&beep; |
|
181
|
0
|
|
|
|
|
|
$f->($me); |
|
182
|
|
|
|
|
|
|
} |
|
183
|
|
|
|
|
|
|
} |
|
184
|
|
|
|
|
|
|
}; |
|
185
|
|
|
|
|
|
|
|
|
186
|
0
|
|
|
|
|
|
system('stty icanon echo'); |
|
187
|
0
|
|
|
|
|
|
$| = $sp; |
|
188
|
|
|
|
|
|
|
|
|
189
|
0
|
0
|
0
|
|
|
|
if( $@ && !ref $@ ){ |
|
190
|
0
|
|
|
|
|
|
die $@; |
|
191
|
|
|
|
|
|
|
} |
|
192
|
0
|
|
|
|
|
|
return; |
|
193
|
|
|
|
|
|
|
} |
|
194
|
|
|
|
|
|
|
|
|
195
|
|
|
|
|
|
|
*less = \&more; |
|
196
|
|
|
|
|
|
|
*page = \&more; |
|
197
|
|
|
|
|
|
|
|
|
198
|
0
|
|
|
0
|
0
|
|
sub beep { print "\a" } |
|
199
|
|
|
|
|
|
|
|
|
200
|
|
|
|
|
|
|
# display a prompt, etc |
|
201
|
|
|
|
|
|
|
sub prompt { |
|
202
|
0
|
|
|
0
|
0
|
|
my $me = shift; |
|
203
|
|
|
|
|
|
|
|
|
204
|
0
|
0
|
|
|
|
|
my $pct = ($me->{nl} > 1) ? 100*$me->{end}/($me->{nl}-1) : 100; |
|
205
|
0
|
0
|
|
|
|
|
my $p = sprintf "[more] %d%% %s %s", $pct, |
|
|
|
0
|
|
|
|
|
|
|
206
|
|
|
|
|
|
|
($me->{start} ? ($me->{end}==$me->{nl}-1) ? 'Bottom' : '' : 'Top'), $me->{msg}; |
|
207
|
|
|
|
|
|
|
|
|
208
|
0
|
|
|
|
|
|
my $p2 = " =down =back =help =quit"; |
|
209
|
|
|
|
|
|
|
|
|
210
|
0
|
|
|
|
|
|
$p .= ' ' x ($me->{cols} - 2 - length($p) - length($p2)); |
|
211
|
|
|
|
|
|
|
|
|
212
|
0
|
|
|
|
|
|
print $p,$p2; |
|
213
|
|
|
|
|
|
|
} |
|
214
|
|
|
|
|
|
|
|
|
215
|
|
|
|
|
|
|
sub done { |
|
216
|
0
|
|
|
0
|
0
|
|
die \ 'foo'; |
|
217
|
|
|
|
|
|
|
} |
|
218
|
|
|
|
|
|
|
|
|
219
|
|
|
|
|
|
|
# put a box around some text |
|
220
|
|
|
|
|
|
|
sub box_text { |
|
221
|
0
|
|
|
0
|
0
|
|
my $me = shift; |
|
222
|
0
|
|
|
|
|
|
my $txt = shift; |
|
223
|
0
|
|
|
|
|
|
my $l; |
|
224
|
|
|
|
|
|
|
|
|
225
|
0
|
|
|
|
|
|
my @l = split /\n/, $txt; |
|
226
|
0
|
0
|
|
|
|
|
foreach (@l){ $l = length($_) if length($_) > $l }; |
|
|
0
|
|
|
|
|
|
|
|
227
|
0
|
|
|
|
|
|
my $b = '+' . '=' x ($l + 2) . '+'; |
|
228
|
0
|
|
|
|
|
|
my $o = join('', map { "| $_" . (' 'x($l-length($_))) ." |\n" } @l); |
|
|
0
|
|
|
|
|
|
|
|
229
|
|
|
|
|
|
|
|
|
230
|
0
|
|
|
|
|
|
"$b\n$o$b\n"; |
|
231
|
|
|
|
|
|
|
} |
|
232
|
|
|
|
|
|
|
|
|
233
|
|
|
|
|
|
|
# provide help to user |
|
234
|
|
|
|
|
|
|
sub help { |
|
235
|
0
|
|
|
0
|
0
|
|
my $me = shift; |
|
236
|
|
|
|
|
|
|
|
|
237
|
0
|
|
|
|
|
|
my $help = $me->box_text(<
|
|
238
|
|
|
|
|
|
|
q quit h help |
|
239
|
|
|
|
|
|
|
/ search |
|
240
|
|
|
|
|
|
|
space page down b page up |
|
241
|
|
|
|
|
|
|
enter line down y line up |
|
242
|
|
|
|
|
|
|
d half page down u half page up |
|
243
|
|
|
|
|
|
|
0 goto top g goto bottom |
|
244
|
|
|
|
|
|
|
< scroll left > scroll right |
|
245
|
|
|
|
|
|
|
|
|
246
|
|
|
|
|
|
|
press any key to continue |
|
247
|
|
|
|
|
|
|
EOH |
|
248
|
|
|
|
|
|
|
; |
|
249
|
|
|
|
|
|
|
|
|
250
|
0
|
|
|
|
|
|
$me->disp_menu( $help ); |
|
251
|
0
|
|
|
|
|
|
getc(); |
|
252
|
0
|
|
|
|
|
|
$me->remove_menu(); |
|
253
|
|
|
|
|
|
|
|
|
254
|
|
|
|
|
|
|
} |
|
255
|
|
|
|
|
|
|
|
|
256
|
|
|
|
|
|
|
# display a popup menu (or other text) |
|
257
|
|
|
|
|
|
|
sub disp_menu { |
|
258
|
0
|
|
|
0
|
0
|
|
my $me = shift; |
|
259
|
0
|
|
|
|
|
|
my $menu = shift; |
|
260
|
0
|
|
|
|
|
|
my $t = $me->{term}; |
|
261
|
|
|
|
|
|
|
|
|
262
|
0
|
|
|
|
|
|
my $nl = @{[split /\n/, $menu]}; |
|
|
0
|
|
|
|
|
|
|
|
263
|
0
|
|
|
|
|
|
$me->{menu_nl} = $nl; |
|
264
|
|
|
|
|
|
|
|
|
265
|
0
|
|
|
|
|
|
print $t->Tgoto('cm', 0, $me->{L} - $nl); # move |
|
266
|
0
|
|
|
|
|
|
print $me->{MN}; # set color |
|
267
|
|
|
|
|
|
|
|
|
268
|
0
|
|
|
|
|
|
my $x = $t->Tgoto('RI', 0,4); # 4 transparent spaces |
|
269
|
0
|
|
|
|
|
|
$menu =~ s/^\s*/$x/gm; |
|
270
|
0
|
|
|
|
|
|
print $menu; |
|
271
|
0
|
|
|
|
|
|
print $me->{NO}; # normal color |
|
272
|
|
|
|
|
|
|
|
|
273
|
|
|
|
|
|
|
} |
|
274
|
|
|
|
|
|
|
|
|
275
|
|
|
|
|
|
|
# remove popup and repaint |
|
276
|
|
|
|
|
|
|
sub remove_menu { |
|
277
|
0
|
|
|
0
|
0
|
|
my $me = shift; |
|
278
|
0
|
|
|
|
|
|
my $t = $me->{term}; |
|
279
|
|
|
|
|
|
|
|
|
280
|
0
|
|
|
|
|
|
my $s = $me->{end} - $me->{menu_nl} + 1; |
|
281
|
0
|
|
|
|
|
|
foreach my $n ($s .. $me->{end}){ |
|
282
|
0
|
|
|
|
|
|
print $t->Tgoto('cm', 0, $n - $me->{start}); # move |
|
283
|
0
|
|
|
|
|
|
print $t->Tputs('ce'); # clear |
|
284
|
0
|
|
|
|
|
|
$me->line($n); |
|
285
|
|
|
|
|
|
|
} |
|
286
|
|
|
|
|
|
|
} |
|
287
|
|
|
|
|
|
|
|
|
288
|
|
|
|
|
|
|
# refresh screen |
|
289
|
|
|
|
|
|
|
sub refresh { |
|
290
|
0
|
|
|
0
|
0
|
|
my $me = shift; |
|
291
|
0
|
|
|
|
|
|
my $t = $me->{term}; |
|
292
|
|
|
|
|
|
|
|
|
293
|
0
|
|
|
|
|
|
print $t->Tputs('cl'); # home, clear |
|
294
|
0
|
|
|
|
|
|
for my $n ($me->{start} .. $me->{end}){ |
|
295
|
0
|
|
|
|
|
|
print $t->Tgoto('cm', 0, $n - $me->{start}); # move |
|
296
|
0
|
|
|
|
|
|
print $t->Tputs('ce'); # clear line |
|
297
|
0
|
|
|
|
|
|
$me->line($n); |
|
298
|
|
|
|
|
|
|
} |
|
299
|
|
|
|
|
|
|
} |
|
300
|
|
|
|
|
|
|
|
|
301
|
|
|
|
|
|
|
sub prline { |
|
302
|
0
|
|
|
0
|
0
|
|
my $me = shift; |
|
303
|
0
|
|
|
|
|
|
my $line = shift; |
|
304
|
|
|
|
|
|
|
|
|
305
|
0
|
|
|
|
|
|
my $len = length($line); |
|
306
|
0
|
|
|
|
|
|
$line = substr($line, $me->{left}, $me->{cols}); |
|
307
|
0
|
0
|
|
|
|
|
if( $len - $me->{left} > $me->{cols} ){ |
|
308
|
0
|
|
|
|
|
|
substr($line, -1, 1, "\$"); |
|
309
|
|
|
|
|
|
|
} |
|
310
|
|
|
|
|
|
|
|
|
311
|
0
|
0
|
|
|
|
|
if( $me->{search} ne '' ){ |
|
312
|
0
|
|
|
|
|
|
my $s = $me->{HI}; |
|
313
|
0
|
|
|
|
|
|
my $e = $me->{NO}; |
|
314
|
0
|
|
|
|
|
|
$line =~ s/($me->{search})/$s$1$e/g; |
|
315
|
|
|
|
|
|
|
} |
|
316
|
0
|
|
|
|
|
|
print $line; |
|
317
|
|
|
|
|
|
|
|
|
318
|
|
|
|
|
|
|
} |
|
319
|
|
|
|
|
|
|
|
|
320
|
|
|
|
|
|
|
sub line { |
|
321
|
0
|
|
|
0
|
0
|
|
my $me = shift; |
|
322
|
0
|
|
|
|
|
|
my $n = shift; |
|
323
|
|
|
|
|
|
|
|
|
324
|
0
|
|
|
|
|
|
$me->prline( $me->{l}[$n] ); |
|
325
|
|
|
|
|
|
|
} |
|
326
|
|
|
|
|
|
|
|
|
327
|
|
|
|
|
|
|
sub down_lines { |
|
328
|
0
|
|
|
0
|
0
|
|
my $me = shift; |
|
329
|
0
|
|
|
|
|
|
my $n = shift; |
|
330
|
0
|
|
|
|
|
|
my $t = $me->{term}; |
|
331
|
|
|
|
|
|
|
|
|
332
|
0
|
|
|
|
|
|
for (1 .. $n){ |
|
333
|
0
|
0
|
|
|
|
|
if( $me->{end} >= $me->{nl}-1 ){ |
|
334
|
0
|
|
|
|
|
|
print "\a"; |
|
335
|
0
|
|
|
|
|
|
last; |
|
336
|
|
|
|
|
|
|
}else{ |
|
337
|
|
|
|
|
|
|
# why? because some terminals have bugs... |
|
338
|
0
|
|
|
|
|
|
print $t->Tgoto('cm', 0, $me->{L} ); # move |
|
339
|
0
|
|
|
|
|
|
print $t->Tputs('sf'); # scroll |
|
340
|
0
|
|
|
|
|
|
print $t->Tgoto('cm', 0, $me->{L} - 1); # move |
|
341
|
0
|
|
|
|
|
|
print $t->Tputs('ce'); # clear line |
|
342
|
|
|
|
|
|
|
|
|
343
|
0
|
|
|
|
|
|
$me->line( ++$me->{end} ); |
|
344
|
0
|
|
|
|
|
|
$me->{start} ++; |
|
345
|
|
|
|
|
|
|
} |
|
346
|
|
|
|
|
|
|
} |
|
347
|
|
|
|
|
|
|
} |
|
348
|
|
|
|
|
|
|
|
|
349
|
|
|
|
|
|
|
sub downhalf { |
|
350
|
0
|
|
|
0
|
0
|
|
my $me = shift; |
|
351
|
0
|
|
|
|
|
|
$me->down_lines( $me->{L} / 2 ); |
|
352
|
|
|
|
|
|
|
} |
|
353
|
|
|
|
|
|
|
|
|
354
|
|
|
|
|
|
|
sub downpage { |
|
355
|
0
|
|
|
0
|
0
|
|
my $me = shift; |
|
356
|
0
|
|
|
|
|
|
$me->down_lines( $me->{L} ); |
|
357
|
|
|
|
|
|
|
} |
|
358
|
|
|
|
|
|
|
|
|
359
|
|
|
|
|
|
|
sub downline { |
|
360
|
0
|
|
|
0
|
0
|
|
my $me = shift; |
|
361
|
0
|
|
|
|
|
|
$me->down_lines( 1 ); |
|
362
|
|
|
|
|
|
|
} |
|
363
|
|
|
|
|
|
|
|
|
364
|
|
|
|
|
|
|
sub up_lines { |
|
365
|
0
|
|
|
0
|
0
|
|
my $me = shift; |
|
366
|
0
|
|
|
|
|
|
my $n = shift; |
|
367
|
0
|
|
|
|
|
|
my $t = $me->{term}; |
|
368
|
|
|
|
|
|
|
|
|
369
|
0
|
|
|
|
|
|
for (1 .. $n){ |
|
370
|
0
|
0
|
|
|
|
|
if( $me->{start} <= 0 ){ |
|
371
|
0
|
|
|
|
|
|
print "\a"; |
|
372
|
0
|
|
|
|
|
|
last; |
|
373
|
|
|
|
|
|
|
}else{ |
|
374
|
0
|
|
|
|
|
|
print $t->Tgoto('cm',0,0); # move |
|
375
|
0
|
|
|
|
|
|
print $t->Tputs('sr'); # scroll back |
|
376
|
0
|
|
|
|
|
|
$me->line( --$me->{start} ); |
|
377
|
0
|
|
|
|
|
|
$me->{end} --; |
|
378
|
|
|
|
|
|
|
} |
|
379
|
|
|
|
|
|
|
} |
|
380
|
|
|
|
|
|
|
|
|
381
|
0
|
|
|
|
|
|
print $t->Tgoto('cm',0,$me->{L}); # goto bottom |
|
382
|
|
|
|
|
|
|
} |
|
383
|
|
|
|
|
|
|
|
|
384
|
|
|
|
|
|
|
sub uppage { |
|
385
|
0
|
|
|
0
|
0
|
|
my $me = shift; |
|
386
|
0
|
|
|
|
|
|
$me->up_lines( $me->{L} ); |
|
387
|
|
|
|
|
|
|
} |
|
388
|
|
|
|
|
|
|
|
|
389
|
|
|
|
|
|
|
sub upline { |
|
390
|
0
|
|
|
0
|
0
|
|
my $me = shift; |
|
391
|
0
|
|
|
|
|
|
$me->up_lines( 1 ); |
|
392
|
|
|
|
|
|
|
} |
|
393
|
|
|
|
|
|
|
|
|
394
|
|
|
|
|
|
|
sub uphalf { |
|
395
|
0
|
|
|
0
|
0
|
|
my $me = shift; |
|
396
|
0
|
|
|
|
|
|
$me->up_lines( $me->{L} / 2 ); |
|
397
|
|
|
|
|
|
|
} |
|
398
|
|
|
|
|
|
|
|
|
399
|
|
|
|
|
|
|
sub to_top { |
|
400
|
0
|
|
|
0
|
0
|
|
my $me = shift; |
|
401
|
|
|
|
|
|
|
|
|
402
|
0
|
|
|
|
|
|
$me->{start} = 0; |
|
403
|
0
|
|
|
|
|
|
$me->{end} = $me->{L} - 1; |
|
404
|
0
|
|
|
|
|
|
$me->refresh(); |
|
405
|
|
|
|
|
|
|
} |
|
406
|
|
|
|
|
|
|
|
|
407
|
|
|
|
|
|
|
sub to_bott { |
|
408
|
0
|
|
|
0
|
0
|
|
my $me = shift; |
|
409
|
|
|
|
|
|
|
|
|
410
|
0
|
|
|
|
|
|
$me->{start} = $me->{nl} - $me->{L}; |
|
411
|
0
|
0
|
|
|
|
|
$me->{start} = 0 if $me->{start} < 0; |
|
412
|
0
|
|
|
|
|
|
$me->{end} = $me->{start} + $me->{L} - 1; |
|
413
|
0
|
|
|
|
|
|
$me->refresh(); |
|
414
|
|
|
|
|
|
|
} |
|
415
|
|
|
|
|
|
|
|
|
416
|
|
|
|
|
|
|
sub move_right { |
|
417
|
0
|
|
|
0
|
0
|
|
my $me = shift; |
|
418
|
|
|
|
|
|
|
|
|
419
|
0
|
|
|
|
|
|
$me->{left} += 8; |
|
420
|
0
|
|
|
|
|
|
$me->refresh(); |
|
421
|
|
|
|
|
|
|
} |
|
422
|
|
|
|
|
|
|
|
|
423
|
|
|
|
|
|
|
sub move_left { |
|
424
|
0
|
|
|
0
|
0
|
|
my $me = shift; |
|
425
|
|
|
|
|
|
|
|
|
426
|
0
|
|
|
|
|
|
$me->{left} -= 8; |
|
427
|
0
|
0
|
|
|
|
|
$me->{left} = 0 if $me->{left} < 0; |
|
428
|
0
|
|
|
|
|
|
$me->refresh(); |
|
429
|
|
|
|
|
|
|
} |
|
430
|
|
|
|
|
|
|
|
|
431
|
|
|
|
|
|
|
sub search { |
|
432
|
0
|
|
|
0
|
0
|
|
my $me = shift; |
|
433
|
0
|
|
|
|
|
|
my $t = $me->{term}; |
|
434
|
|
|
|
|
|
|
|
|
435
|
|
|
|
|
|
|
# get pattern |
|
436
|
0
|
|
|
|
|
|
my $prev = $me->{search}; |
|
437
|
0
|
|
|
|
|
|
$me->{search} = ''; |
|
438
|
|
|
|
|
|
|
|
|
439
|
0
|
|
|
|
|
|
print $t->Tgoto('cm', 0, $me->{L}); # move bottom |
|
440
|
0
|
|
|
|
|
|
print $t->Tputs('ce'); # clear line |
|
441
|
0
|
|
|
|
|
|
print $me->{SE}; # set color |
|
442
|
0
|
|
|
|
|
|
print "/"; |
|
443
|
|
|
|
|
|
|
|
|
444
|
0
|
|
|
|
|
|
while(1){ |
|
445
|
0
|
|
|
|
|
|
my $l = getc(); |
|
446
|
0
|
0
|
0
|
|
|
|
last if $l eq "\n" || $l eq "\r"; |
|
447
|
0
|
0
|
0
|
|
|
|
if( $l eq "\e" || !defined($l) ){ |
|
448
|
0
|
|
|
|
|
|
$me->{search} = ''; |
|
449
|
0
|
|
|
|
|
|
last; |
|
450
|
|
|
|
|
|
|
} |
|
451
|
0
|
0
|
0
|
|
|
|
if( $l eq "\b" || $l eq "\177" || $l eq '#' ){ |
|
|
|
|
0
|
|
|
|
|
|
452
|
0
|
0
|
|
|
|
|
print "\b \b" if $me->{search} ne ''; |
|
453
|
0
|
|
|
|
|
|
substr($me->{search}, -1, 1, ''); |
|
454
|
0
|
|
|
|
|
|
next; |
|
455
|
|
|
|
|
|
|
} |
|
456
|
0
|
|
|
|
|
|
print $l; |
|
457
|
0
|
|
|
|
|
|
$me->{search} .= $l; |
|
458
|
|
|
|
|
|
|
} |
|
459
|
0
|
|
|
|
|
|
print $me->{NO}; # normal color |
|
460
|
0
|
|
|
|
|
|
print $t->Tgoto('cm', 0, $me->{L}); # move bottom |
|
461
|
0
|
|
|
|
|
|
print $t->Tputs('ce'); # clear line |
|
462
|
0
|
0
|
|
|
|
|
return if $me->{search} eq ''; |
|
463
|
|
|
|
|
|
|
|
|
464
|
0
|
0
|
0
|
|
|
|
$me->{search} = $prev if $me->{search} eq '/' && $prev; |
|
465
|
|
|
|
|
|
|
|
|
466
|
0
|
|
|
|
|
|
for my $n ( $me->{start} .. $me->{nl}-1 ){ |
|
467
|
0
|
0
|
|
|
|
|
next unless $me->{l}[$n] =~ /$me->{search}/; |
|
468
|
|
|
|
|
|
|
|
|
469
|
0
|
|
|
|
|
|
$me->{start} = $n; |
|
470
|
0
|
0
|
|
|
|
|
$me->{start} = 0 if $me->{nl} < $me->{L} - 1; |
|
471
|
0
|
|
|
|
|
|
$me->{end} = $me->{start} + $me->{L} - 1; |
|
472
|
|
|
|
|
|
|
|
|
473
|
0
|
0
|
0
|
|
|
|
if( $me->{end} > $me->{nl} - 1 && $me->{start} ){ |
|
474
|
0
|
|
|
|
|
|
my $x = $me->{end} - $me->{nl} + 1; |
|
475
|
0
|
0
|
|
|
|
|
$x = $me->{start} if $x > $me->{start}; |
|
476
|
0
|
|
|
|
|
|
$me->{start} -= $x; |
|
477
|
0
|
|
|
|
|
|
$me->{end} -= $x; |
|
478
|
|
|
|
|
|
|
} |
|
479
|
|
|
|
|
|
|
|
|
480
|
0
|
|
|
|
|
|
$me->refresh(); |
|
481
|
0
|
|
|
|
|
|
return; |
|
482
|
|
|
|
|
|
|
} |
|
483
|
|
|
|
|
|
|
# not found |
|
484
|
0
|
|
|
|
|
|
print "\a"; |
|
485
|
0
|
|
|
|
|
|
my $m = $me->box_text( 'Not Found' ); |
|
486
|
0
|
|
|
|
|
|
$me->disp_menu($m); |
|
487
|
0
|
|
|
|
|
|
sleep 1; |
|
488
|
0
|
|
|
|
|
|
$me->remove_menu(); |
|
489
|
0
|
|
|
|
|
|
return; |
|
490
|
|
|
|
|
|
|
|
|
491
|
|
|
|
|
|
|
} |
|
492
|
|
|
|
|
|
|
|
|
493
|
|
|
|
|
|
|
|
|
494
|
|
|
|
|
|
|
sub dumb_mode { |
|
495
|
0
|
|
|
0
|
0
|
|
my $me = shift; |
|
496
|
0
|
|
|
|
|
|
my $end = 0; |
|
497
|
|
|
|
|
|
|
|
|
498
|
0
|
|
|
|
|
|
while(1){ |
|
499
|
0
|
|
|
|
|
|
for my $i (1 .. $me->{rows} - 1){ |
|
500
|
0
|
0
|
|
|
|
|
last if $end >= $me->{nl}; |
|
501
|
0
|
|
|
|
|
|
print $me->{l}[$end++], "\n"; |
|
502
|
|
|
|
|
|
|
} |
|
503
|
|
|
|
|
|
|
|
|
504
|
0
|
|
|
|
|
|
print "--more [dumb]--"; |
|
505
|
0
|
|
|
|
|
|
my $a = getc(); |
|
506
|
0
|
|
|
|
|
|
print "\b \b"x15; |
|
507
|
|
|
|
|
|
|
|
|
508
|
0
|
0
|
|
|
|
|
return if $a eq 'q'; |
|
509
|
0
|
0
|
|
|
|
|
return if $end >= $me->{nl}; |
|
510
|
|
|
|
|
|
|
} |
|
511
|
|
|
|
|
|
|
} |
|
512
|
|
|
|
|
|
|
|
|
513
|
|
|
|
|
|
|
|
|
514
|
|
|
|
|
|
|
|
|
515
|
|
|
|
|
|
|
=head1 FEATURES |
|
516
|
|
|
|
|
|
|
|
|
517
|
|
|
|
|
|
|
This code uses termcap. If the termcap entry for your ancient esoteric |
|
518
|
|
|
|
|
|
|
terminal is wrong or incomplete, this module may either fill your screen |
|
519
|
|
|
|
|
|
|
with unintelligible gibberish, or drop back to a feature-free mode. |
|
520
|
|
|
|
|
|
|
|
|
521
|
|
|
|
|
|
|
=head1 SEE ALSO |
|
522
|
|
|
|
|
|
|
|
|
523
|
|
|
|
|
|
|
Term::Cap, termcap(5), more(1), less(1) |
|
524
|
|
|
|
|
|
|
Yellowstone National Park |
|
525
|
|
|
|
|
|
|
|
|
526
|
|
|
|
|
|
|
=head1 AUTHOR |
|
527
|
|
|
|
|
|
|
|
|
528
|
|
|
|
|
|
|
Jeff Weisberg - http://www.tcp4me.com |
|
529
|
|
|
|
|
|
|
|
|
530
|
|
|
|
|
|
|
=cut |
|
531
|
|
|
|
|
|
|
; |