/[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 11 by dpavlin, Thu Oct 25 15:19:51 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/cluck/;  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 27  $data .= ( rand(10) < 5 ? '{s}' : '' ) . Line 29  $data .= ( rand(10) < 5 ? '{s}' : '' ) .
29    
30  $data .= "\n--EOF--";  $data .= "\n--EOF--";
31    
32  my $scr;  Term::ISelect->screen(
33            sub {
34  # leave sane terminal if script dies                  warn "## ",dump(@_);
35  $SIG{__DIE__} = sub {          },
36      eval { system('stty sane'); };          split(/\n/, $data),
37  };  );
   
   
 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 = '';  
   
 my $status_lines = 3;  
   
 # 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;  
         cluck "expected line" unless defined $t;  
         return substr($t,0,$scr->cols);  
 }  
   
 sub redraw_line {  
         my ($l,$line) = @_;  
   
         if ( defined $selectable_line->{ $l + $top_screen_line } ) {  
                 $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 - $status_lines) {  
                 my $line = $lines[ $l + $top_screen_line ];  
                 redraw_line( $l, $line );  
                 last if ($l == $#lines);  
         }  
         selected(0);  
 }  
   
 sub status {  
         my $pcnt = int(($pos || 0) * 100 / ($#lines || 1));  
         my $pos_txt = sprintf('%d, %d%% ',$pos,$pcnt);  
           
         $scr->at($scr->rows - $status_lines + 1,0)->reverse()->puts(  
                 sprintf(' %-'.($scr->cols - length($pos_txt) - 2).'s ',$status_text)  
         .$pos_txt)->normal();  
         $scr->at($scr->rows - $status_lines + 2,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 - $status_lines;  
   
         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 - $status_lines;  
   
         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 if $top_screen_line < 0;  
                         redraw;  
                 }  
                 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;  
                         redraw;  
                 }  
                 selected( $top_screen_line + $lines_on_screen - $pos );  
         }  
   
         $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) );  
         }  
   
         # CTRL+L  
         redraw if ord($key) eq 0x0c;  
   
         # Enter  
         if ( ord($key) eq 0x0d && $sel_pos > 0 ) {  
                 $error_text = "execute: " . $lines[ $sel_pos ];  
         }  
   
         exit if (lc($key) eq 'q');  
   
         status;  
   
 }  
38    
 $scr->clrscr();  

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

  ViewVC Help
Powered by ViewVC 1.1.26