--- CHANGES~ 2012-12-02 13:25:21.000000000 -0500
+++ CHANGES 2018-10-13 10:31:21.542338452 -0400
@@ -1,2 +1,11 @@
+1.50 2018-10-13
+
+ Add support for continuous input.
+
+ Add work-around for screen's incomplete TERMCAP.
+
+ Add auto-detection of screen speed and dimensions. RT #101235
+
1.02
- divide by zero
+
+ divide by zero. RT #80192
--- META.yml~ 2012-12-02 13:31:30.000000000 -0500
+++ META.yml 2018-10-13 10:23:22.778199272 -0400
@@ -1,9 +1,10 @@
--- #YAML:1.0
name: Term-Pager
-version: 1.02
+version: 1.50
abstract: Page through text, a screenful at a time, like more or less
author:
- Jeff Weisberg <
http://www.tcp4me.com/>
+ - Jerrad Pierce
license: unknown
distribution_type: module
configure_requires:
@@ -12,6 +13,8 @@
ExtUtils::MakeMaker: 0
requires:
Term::Cap: 0
+recommends:
+ Term::ReadKey 0
no_index:
directory:
- t
--- Pager.pm~ 2012-12-02 13:25:16.000000000 -0500
+++ Pager.pm 2018-10-13 10:29:28.328818862 -0400
@@ -5,7 +5,7 @@
# Created: 2004-Jun-03 10:24 (EDT)
# Function: pager like more/less
#
-# $Id: Pager.pm,v 1.4 2012/12/02 18:06:46 jaw Exp $
+# $Id: Pager.pm,v 1.5 2018/10/13 $
=head1 NAME
@@ -13,6 +13,7 @@
=head1 SYNOPSIS
+ use Term:ReadKey; #Optional, but recommended
use Term::Pager;
my $t = Term::Pager->new( rows => 25, cols => 80 );
@@ -22,8 +23,8 @@
=head1 DESCRIPTION
This is a module for paging through text one screenful at a time.
-It supports the features you expect, including backwards
-movement and searching. It uses the keys you expect.
+It supports the features you expect, including backwards movement
+and searching. It uses the keys you expect.
=head1 USAGE
@@ -36,20 +37,21 @@
=over 4
-=item C<rows>
+=item I<rows>
-The number of rows on your terminal.
-This defaults to 25.
+The number of rows on your terminal. The terminal is queried directly
+with Term::ReadKey if loaded or C<stty>, and if these fail it defaults to 25.
-=item C<cols>
+=item I<cols>
-The number of columns on your terminal.
-This defaults to 80.
+The number of columns on your terminal. The terminal is queried directly
+with Term::ReadKey if loaded or C<stty>, and if these fail it defaults to 80.
-=item C<speed>
+=item I<speed>
-The speed (baud rate) of your terminal. Will default
-to a sensible value.
+The speed (baud rate) of your terminal. The terminal is queried directly
+with Term::ReadKey if loaded or C<stty>, and if these fail it defaults a
+sensible value.
=back
@@ -64,18 +66,72 @@
$t->add_text( $text );
+To continuously add text to the pager, you must setup your own event loop,
+and indicate to C<more> that it should relinquish control e.g;
+
+ while( eval{ $t->more(RT=>.05) } ){
+ ...
+ $t->add_text("More text to page");
+ }
+
+The eval block captures the exception thrown upon termination of the pager
+so that your own program may continue. The I<RT> parameter indicates that you
+wish to provide content in real time, and the value is passed to
+L<Term::ReadKey/ReadKey> as the maximum blocking time per keypress. Values
+should be between 0 and 1, with larger values trading greater interface
+responsiveness for slight delays in output. A value of -1 may also be used
+to request non-blocking polls, but likely will not behave as you would hope.
+
+IF Term::ReadKey IS NOT LOADED, SCREEN UPDATES WILL ONLY OCCUR ON KEYPRESS
+IF RT IS TRUE.
+
=cut
;
package Term::Pager;
-$VERSION = '1.02';
+$VERSION = '1.50';
use Term::Cap;
+#use Term::ReadKey;
use strict;
+#Stubs for ReadKey functions that we fill in with code refs if it's not loaded
+sub ReadMode;
+sub ReadKey;
+
sub new {
my $class = shift;
my %param = @_;
+ local $ENV{TERM} = $ENV{TERM};
+
+ my %dims = (cols => 80, rows => 25);
+ if( defined($Term::ReadKey::VERSION) ){
+ Term::ReadKey->import();
+ my @Tsize = Term::ReadKey::GetTerminalSize(*STDOUT);
+ $dims{rows} = $Tsize[1] if $Tsize[1];
+ $dims{cols} = $Tsize[0] if $Tsize[0];
+ $param{speed} ||= (Term::ReadKey::GetSpeed())[1];
+ }
+ else{
+ *ReadMode = sub{
+ if( $_[0] == 3 ){
+ system('stty -icanon -echo min 1'); }
+ elsif( $_[0] == 0 ){
+ system('stty icanon echo'); }
+ };
+ *ReadKey = sub{ getc() };
+ if( `stty` =~ /speed/ ){
+ my @Tsize = split(/s+/, `stty size`);
+ $dims{rows} = $Tsize[0] if $Tsize[0];
+ $dims{cols} = $Tsize[1] if $Tsize[1];
+ $dims{speed} = `stty size`;
+ }
+ }
+
+ #screen is vt100 compatible but does not list sf?!
+ if( $ENV{TERM} eq 'screen' && $ENV{TERMCAP} !~ /sf/ ){
+ $ENV{TERM} = 'vt100';
+ }
my $t = Term::Cap->Tgetent({ OSPEED => ($param{speed} || 38400) });
my $dumbp;
@@ -88,8 +144,8 @@
my $me = bless {
# default values
term => $t,
- cols => 80,
- rows => 25,
+ start => 0,
+ %dims,
dumbp => $dumbp,
# if the termcap entries don't exist, nothing bad will happen
@@ -116,20 +172,25 @@
'?' => \&help,
'0' => \&to_top,
'g' => \&to_bott,
- '$' => \&to_bott, # '
+ '$' => \&to_bott,
'/' => \&search,
'<' => \&move_left,
'>' => \&move_right,
};
+ $me->{end} = ($me->{L} = $me->{rows} - 1) - 1;
+ $me->{sp} = $|;
+
$me;
}
sub add_text {
- my $me = shift;
- my $tx = shift;
+ return unless defined($_[1]);
- $me->{text} .= $tx;
+ my $me = shift;
+ push @{$me->{l}}, map{split /\n/} @_;
+ $me->{nl} = @{ $me->{l} };
+ $me->refresh();
}
sub add_func {
@@ -142,54 +203,45 @@
sub more {
my $me = shift;
- my $sp = $|;
+ my %param = @_;
+ $me->{RT} = $param{RT};
my $t = $me->{term};
- $me->{L} = $me->{rows} - 1;
- $me->{l} = [ split /\n/, $me->{text} ];
- $me->{nl}= @{ $me->{l} };
-
- $me->{start} = 0;
- $me->{end} = $me->{L} - 1;
$SIG{INT} = $SIG{QUIT} = \&done;
- system('stty -icanon -echo min 1');
+ ReadMode 3;
$| = 1;
- eval {
- if( $me->{dumbp} ){
- $me->dumb_mode();
- }else{
- print $me->{NO};
- $me->refresh();
-
- while(1){
- print $t->Tgoto('cm', 0, $me->{L}); # bottom left
- print $t->Tputs('ce'); # clear line
+ if( $me->{dumbp} ){
+ $me->dumb_mode();
+ }else{
+ print $me->{NO};
+ if( defined($me->{text}) ){
+ $me->add_text( $me->{text} );
+ undef( $me->{text} );
+ }
- print $me->{ML}; # reverse video
- $me->prompt();
- print $me->{NO}; # normal video
- my $q = getc();
+ while( 1 ){
+ print $t->Tgoto('cm', 0, $me->{L}); # bottom left
+ print $t->Tputs('ce'); # clear line
+
+ print $me->{ML}; # reverse video
+ $me->prompt();
+ print $me->{NO}; # normal video
- print $t->Tgoto('cm', 0, $me->{L}); # bottom left
- print $t->Tputs('ce'); # clear line
+ my $q = ReadKey($param{RT});
- $me->{msg} = '';
+ $me->{msg} = '';
+ if( defined $q){
my $f = $me->{fnc}->{lc($q)} || \&beep;
$f->($me);
}
- }
- };
-
- system('stty icanon echo');
- $| = $sp;
- if( $@ && !ref $@ ){
- die $@;
+ return 1 if $param{RT};
+ }
}
- return;
+ $me->done();
}
*less = \&more;
@@ -201,7 +253,7 @@
sub prompt {
my $me = shift;
- my $pct = ($me->{nl} > 1) ? 100*$me->{end}/($me->{nl}-1) : 100;
+ my $pct = ($me->{nl} > $me->{end}) ? 100*$me->{end}/($me->{nl}-1) : 100;
my $p = sprintf "[more] %d%% %s %s", $pct,
($me->{start} ? ($me->{end}==$me->{nl}-1) ? 'Bottom' : '' : 'Top'), $me->{msg};
@@ -213,7 +265,11 @@
}
sub done {
- die \ 'foo';
+ my $me = shift;
+
+ ReadMode 0;
+ $| = $me->{sp};
+ $me->{RT} ? die : exit 0;
}
# put a box around some text
@@ -331,7 +387,7 @@
for (1 .. $n){
if( $me->{end} >= $me->{nl}-1 ){
- print "\a";
+ &beep;
last;
}else{
# why? because some terminals have bugs...
@@ -368,7 +424,7 @@
for (1 .. $n){
if( $me->{start} <= 0 ){
- print "\a";
+ &beep;
last;
}else{
print $t->Tgoto('cm',0,0); # move
@@ -481,7 +537,7 @@
return;
}
# not found
- print "\a";
+ &beep;
my $m = $me->box_text( 'Not Found' );
$me->disp_menu($m);
sleep 1;
@@ -520,12 +576,15 @@
=head1 SEE ALSO
- Term::Cap, termcap(5), more(1), less(1)
+ Term::Cap, Term::ReadKey, termcap(5), stty(1), more(1), less(1)
Yellowstone National Park
-=head1 AUTHOR
+=head1 AUTHORS
Jeff Weisberg -
http://www.tcp4me.com
+ Jerrad Pierce
+
=cut
- ;
+
+1;