/[iselect]/bin/iselect.pl
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /bin/iselect.pl

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

iselect.pl revision 6 by dpavlin, Thu Oct 25 13:24:02 2007 UTC bin/iselect.pl revision 18 by dpavlin, Thu Oct 25 19:32:24 2007 UTC
# Line 1  Line 1 
1  #!/usr/bin/perl -w  #!/usr/bin/perl -w
2    
3  use strict;  use strict;
4  use Term::Screen;  
5  use Carp qw/confess/;  use blib;
6    
7    use Term::ISelect;
8  use Data::Dump qw/dump/;  use Data::Dump qw/dump/;
9    
10  my $data = <<'EOF';  my $data = <<'EOF';
# Line 23  my $data = <<'EOF'; Line 25  my $data = <<'EOF';
25    
26  EOF  EOF
27    
28  open(my $ps, "ps ax |") || die "can't do ps ax: $!";  $data .= ( rand(10) < 5 ? '{s}' : '' ) . "foobar $_\n" foreach ( 1 .. 300 );
 while(<$ps>) {  
         $data .= '{s}'.$_;  
         $data .= $_;  
 }  
 close($ps);  
29    
30  $data .= "\n--EOF--";  $data .= "\n--EOF--";
   
 my $scr;  
   
 # leave sane terminal if script dies  
 $SIG{__DIE__} = sub {  
     eval { system('stty sane'); };  
 };  
   
   
 my @lines = split(/\n/, $data);  
   
 my $top_screen_line = 0;        # offset in original text  
 my $pos = 0;  
   
 # default: select first line  
 my $sel_pos = 0;  
 my $status_text = '';  
 my $error_text = '';  
   
   
 # find which lines are selectable in input file  
 my $selectable_line;  
   
 for my $l (0 .. $#lines) {  
         if ($lines[$l] !~ s/^{s}//) {  
                 $selectable_line->{$l}++;  
         }  
 }  
   
 # select first selectable line  
   
 if ( $selectable_line ) {  
         $pos = $sel_pos = (sort { $a <=> $b } keys %$selectable_line)[0];  
         warn "selected first selectable line $sel_pos";  
 }  
   
 sub full_line {  
         my $t = shift;  
         $t = '' unless defined $t;  
         return $t . (" " x ($scr->cols - length($t)));  
 }  
   
 sub chunk {  
         my $t = shift;  
         return unless length($t) > 2;  
         return substr($t,1,$scr->cols);  
 }  
   
 sub redraw_line {  
         my ($l,$line) = @_;  
   
         if ( defined $selectable_line->{ $l } ) {  
                 $scr->at($l,0)->bold()->puts( full_line( chunk($line) ) )->normal();  
         } else {  
                 $scr->at($l,0)->puts( full_line( chunk($line) ) );  
         }  
 }  
   
 sub redraw {  
         for my $l (0 .. $scr->rows - 3) {  
                 my $line = $lines[ $l + $top_screen_line ];  
                 redraw_line( $l, $line );  
                 last if ($l == $#lines);  
         }  
 }  
   
 sub status {  
         my $pcnt = int(($pos || 0) * 100 / ($#lines || 1));  
         my $pos_txt = sprintf('%d, %d%% ',$pos,$pcnt);  
31                    
32          $scr->at($scr->rows - 2,0)->reverse()->puts(  my @lines = split(/\n/, $data);
33                  sprintf(' %-'.($scr->cols - length($pos_txt) - 2).'s ',$status_text)  #warn "lines = ", dump( @lines );
         .$pos_txt)->normal();  
         $scr->at($scr->rows - 1,0)->puts(  
                 sprintf('%-'.$scr->cols.'s', $error_text)  
         );  
 }  
   
 sub selected {  
         my $d = shift || 0;  
   
         my $screen_line = $pos - $top_screen_line;  
   
         redraw_line( $screen_line, $lines[$pos] );  
   
         my $last_screen_line = $scr->rows - 3;  
   
         if ( $d < 0 && $screen_line == 0 ) {  
                 if ( $pos > 0 ) {  
                         $top_screen_line--;  
                         $pos--;  
                 } else {  
                         $error_text = "Already at Begin.";  
                 }  
                 redraw;  
         } elsif ( $d > 0 && $screen_line == $last_screen_line ) {  
                 if ( $pos <= $#lines ) {  
                         $top_screen_line++;  
                         $pos++;  
                 } else {  
                         $error_text = "Already at End.";  
                 }  
                 redraw;  
         } else {  
                 $pos += $d;  
         }  
   
         my $line = $lines[$pos];  
         if ( defined $selectable_line->{ $pos } ) {  
                 $scr->at($pos - $top_screen_line,0)->reverse->bold()->puts( full_line( chunk($line) ) )->normal();  
                 $sel_pos = $pos;  
         } else {  
                 $scr->at($pos - $top_screen_line,0)->reverse->puts( full_line( chunk($line) ) );  
                 $sel_pos = -1;  
         }  
         status;  
 }  
   
 $scr = new Term::Screen || die "can't init Term::Screen";  
 $scr->clrscr()->noecho();  
 redraw;  
 selected;  
   
 while(my $key = $scr->getch()) {  
   
         $error_text = "";  
   
         my $lines_on_screen = $scr->rows - 3;  
   
         if ($key eq 'ku') {  
                 selected( -1 );  
         } elsif ($key eq 'kd') {  
                 selected( +1 );  
         } elsif ($key eq 'pgup' ) {  
                 # first line on screen?  
                 if ( $pos == $top_screen_line ) {  
                         $top_screen_line -= $lines_on_screen;  
                         $top_screen_line = 0;  
                         $pos = $top_screen_line;  
                         redraw;  
                         selected( $pos );  
                 } else {  
                         selected( -( $pos - $top_screen_line ) );  
                 }  
         } elsif ($key eq 'pgdn' ) {  
                 # last line on screen?  
                 if ( $pos - $top_screen_line == $lines_on_screen ) {  
                         $top_screen_line += $lines_on_screen;  
                         $top_screen_line = $#lines - $lines_on_screen if $top_screen_line > $#lines - $lines_on_screen;  
                         $pos = $top_screen_line;  
                         redraw;  
                         selected( $pos );  
                 } else {  
                         selected( $top_screen_line + $scr->rows - $pos - 3 );  
                 }  
         }  
   
         $status_text = sprintf("pos: %-3d sel_pos: %-3d top_screen_line: %-3d", $pos, $sel_pos, $top_screen_line );  
         if ( length($key) > 1 ) {  
                 $status_text .= " key: $key";  
         } else {  
                 $status_text .= sprintf("key: %s [%03d][%02x]", $key =~ m/\w/ ? $key : '?' , ord($key), ord($key) );  
         }  
   
         status;  
   
         redraw if lc($key) eq 'r';  
34    
35          exit if (lc($key) eq 'q');  my $iselect = Term::ISelect->new({
36  }          lines => [ @lines ],
37    });
38    
39    $iselect->loop(
40            sub {
41                    warn "## ",dump(@_);
42            },
43    );
44    
 $scr->clrscr();  

Legend:
Removed from v.6  
changed lines
  Added in v.18

  ViewVC Help
Powered by ViewVC 1.1.26