/[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 4 by dpavlin, Thu Oct 25 12:45:18 2007 UTC bin/iselect.pl revision 12 by dpavlin, Thu Oct 25 15:50:56 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);  
   
 my $scr;  
   
 # leave sane terminal if script dies  
 $SIG{__DIE__} = sub {  
     eval { system('stty sane'); };  
 };  
   
   
 my @lines = split(/\n/, $data);  
   
 my $o = 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 + $o ];  
                 next if (length($line) < 2);  
                 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);  
           
         $scr->at($scr->rows - 2,0)->reverse()->puts(  
                 sprintf(' %-'.($scr->cols - length($pos_txt) - 2).'s ',$status_text)  
         .$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 - $o;  
   
         redraw_line( $screen_line, $lines[$pos] );  
   
         my $last_screen_line = $scr->rows - 3;  
   
         if ( $d < 0 && $screen_line == 0 ) {  
                 if ( $pos > 0 ) {  
                         $o--;  
                 } else {  
                         $error_text = "Already at Begin.";  
                 }  
                 redraw;  
         } elsif ( $d > 0 && $screen_line == $last_screen_line ) {  
                 if ( $pos <= $#lines ) {  
                         $o++;  
                 } else {  
                         $error_text = "Already at End.";  
                 }  
                 redraw;  
         } else {  
                 $pos += $d;  
         }  
   
         my $line = $lines[$pos];  
         if ( defined $selectable_line->{ $pos } ) {  
                 $scr->at($pos - $o,0)->reverse->bold()->puts( full_line( chunk($line) ) )->normal();  
                 $sel_pos = $pos;  
         } else {  
                 $scr->at($pos - $o,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 = "";  
   
         if ($key eq 'ku') {  
                 selected( -1 );  
         } elsif ($key eq 'kd') {  
                 selected( +1 );  
         }  
   
         $status_text = sprintf("pos: %-3d sel_pos: %-3d top offset: %-3d", $pos, $sel_pos, $o );  
         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;  
29    
30          redraw if lc($key) eq 'r';  $data .= "\n--EOF--";
31    
32          exit if (lc($key) eq 'q');  Term::ISelect->screen(
33  }          sub {
34                    warn "## ",dump(@_);
35            },
36            split(/\n/, $data),
37    );
38    
 $scr->clrscr();  

Legend:
Removed from v.4  
changed lines
  Added in v.12

  ViewVC Help
Powered by ViewVC 1.1.26