/[iselect]/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 /iselect.pl

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

revision 1 by dpavlin, Thu Oct 25 11:22:18 2007 UTC revision 6 by dpavlin, Thu Oct 25 13:24:02 2007 UTC
# Line 2  Line 2 
2    
3  use strict;  use strict;
4  use Term::Screen;  use Term::Screen;
5    use Carp qw/confess/;
6  use Data::Dump qw/dump/;  use Data::Dump qw/dump/;
7    
8  my $data = <<'EOF';  my $data = <<'EOF';
9   First line   First line
10    
11  +first selectable  {s}first selectable
12  + second selectable  {s}second selectable
13    
14   a space....   a space....
15    
16                                      ...infinity and beyond                                      ...infinity and beyond
17    
18    
19  +foo  {s}foo
20  +bar  {s}bar
21    
22   bum   bum
23    
24  EOF  EOF
25    
26  open(my $ps, "ps ax |") || die "can't do ps ax: $!";  open(my $ps, "ps ax |") || die "can't do ps ax: $!";
27  while(<$ps>) {  while(<$ps>) {
28          $data .= '+'.$_;          $data .= '{s}'.$_;
29          $data .= ' '.$_;          $data .= $_;
30  }  }
31  close($ps);  close($ps);
32    
33    $data .= "\n--EOF--";
34    
35  my @lines = split(/\n/, $data);  my $scr;
36    
37  my $scr = new Term::Screen || die "can't init Term::Screen";  # leave sane terminal if script dies
38  $scr->clrscr()->noecho();  $SIG{__DIE__} = sub {
39        eval { system('stty sane'); };
40    };
41    
42    
43    my @lines = split(/\n/, $data);
44    
45  my $o = 0;      # offset in original text  my $top_screen_line = 0;        # offset in original text
46  my $pos = 0;  my $pos = 0;
47    
48    # default: select first line
49    my $sel_pos = 0;
50    my $status_text = '';
51    my $error_text = '';
52    
53    
54  # find which lines are selectable in input file  # find which lines are selectable in input file
55  my $selectable_line;  my $selectable_line;
56    
57  for my $l (0 .. $#lines) {  for my $l (0 .. $#lines) {
58          next if (length($lines[$l]) < 2);          if ($lines[$l] !~ s/^{s}//) {
         my $foo = ' ';  
         if ($lines[$l] !~ m/^\s/o) {  
59                  $selectable_line->{$l}++;                  $selectable_line->{$l}++;
                 $foo = '*';  
60          }          }
61          warn "$l: $foo $lines[$l]\n";  }
62    
63    # select first selectable line
64    
65    if ( $selectable_line ) {
66            $pos = $sel_pos = (sort { $a <=> $b } keys %$selectable_line)[0];
67            warn "selected first selectable line $sel_pos";
68  }  }
69    
70  sub full_line {  sub full_line {
71          my $t = shift;          my $t = shift;
72          my $l = length($t);          $t = '' unless defined $t;
73          return $t . (" " x ($scr->cols - length($t)));          return $t . (" " x ($scr->cols - length($t)));
74  }  }
75    
76  sub chunk {  sub chunk {
77          my $t = shift;          my $t = shift;
78          my $o = '';          return unless length($t) > 2;
79          $o = substr($t,1,$scr->cols) if length($t) > 1;          return substr($t,1,$scr->cols);
80          return $o . ( ' ' x ( $scr->cols - length($o) - 1 ) );  }
81    
82    sub redraw_line {
83            my ($l,$line) = @_;
84    
85            if ( defined $selectable_line->{ $l } ) {
86                    $scr->at($l,0)->bold()->puts( full_line( chunk($line) ) )->normal();
87            } else {
88                    $scr->at($l,0)->puts( full_line( chunk($line) ) );
89            }
90  }  }
91    
92  sub redraw {  sub redraw {
93          for my $l (0 .. $scr->rows) {          for my $l (0 .. $scr->rows - 3) {
94                  my $line = $lines[ $l + $o ] || '';                  my $line = $lines[ $l + $top_screen_line ];
95                  next if (length($line) < 2);                  redraw_line( $l, $line );
                 if (substr($line,0,1) !~ m/^\s/o) {  
                         $scr->at($l,0)->bold()->puts( full_line( chunk($line) ) )->normal();  
                 } else {  
                         $scr->at($l,0)->puts( full_line( chunk($line) ) );  
                 }  
96                  last if ($l == $#lines);                  last if ($l == $#lines);
97          }          }
98  }  }
99    
 # default: select first line  
 my $sel_pos = 0;  
 my $status_text = '';  
 my $error_text = '';  
 $pos = 0;  
   
100  sub status {  sub status {
101          my $pcnt = int(($pos || 0) * 100 / ($#lines || 1));          my $pcnt = int(($pos || 0) * 100 / ($#lines || 1));
102          my $pos_txt = sprintf('%d, %d%% ',$pos,$pcnt);          my $pos_txt = sprintf('%d, %d%% ',$pos,$pcnt);
# Line 95  sub status { Line 110  sub status {
110  }  }
111    
112  sub selected {  sub selected {
113          my $d = shift || return;          my $d = shift || 0;
114    
115          if ( $selectable_line->{ $pos } ) {          my $screen_line = $pos - $top_screen_line;
116                  $scr->at($pos-$o,0)->bold()->puts( chunk($lines[$pos]) )->normal();  
117          } else {          redraw_line( $screen_line, $lines[$pos] );
                 $scr->at($pos-$o,0)->puts( chunk($lines[$pos]) )->normal();  
         }  
         $pos += $d;  
118    
119          my $max_row = $scr->rows - 3;          my $last_screen_line = $scr->rows - 3;
120    
121          if ($pos < 1) {          if ( $d < 0 && $screen_line == 0 ) {
122                  $error_text = "Already at Begin.";                  if ( $pos > 0 ) {
123                  $pos = 0;                          $top_screen_line--;
124                            $pos--;
125                    } else {
126                            $error_text = "Already at Begin.";
127                    }
128                  redraw;                  redraw;
129          } elsif ($pos > $max_row) {          } elsif ( $d > 0 && $screen_line == $last_screen_line ) {
130                  $o = $pos - $max_row;   # put selected line on last                  if ( $pos <= $#lines ) {
131                  $error_text = "Already at End.";                          $top_screen_line++;
132                            $pos++;
133                    } else {
134                            $error_text = "Already at End.";
135                    }
136                  redraw;                  redraw;
137            } else {
138                    $pos += $d;
139          }          }
140    
141          $scr->at($pos-$o,0)->reverse()->puts(chunk($lines[$pos]))->normal();          my $line = $lines[$pos];
142            if ( defined $selectable_line->{ $pos } ) {
143                    $scr->at($pos - $top_screen_line,0)->reverse->bold()->puts( full_line( chunk($line) ) )->normal();
144                    $sel_pos = $pos;
145            } else {
146                    $scr->at($pos - $top_screen_line,0)->reverse->puts( full_line( chunk($line) ) );
147                    $sel_pos = -1;
148            }
149          status;          status;
150  }  }
151    
152  $status_text = "let's see does it work?";  $scr = new Term::Screen || die "can't init Term::Screen";
153    $scr->clrscr()->noecho();
154  redraw;  redraw;
155  selected;  selected;
156    
157  while(my $key = $scr->getch()) {  while(my $key = $scr->getch()) {
158    
         $status_text = "key: $key pos: $pos sel_pos: $sel_pos";  
159          $error_text = "";          $error_text = "";
160    
161            my $lines_on_screen = $scr->rows - 3;
162    
163          if ($key eq 'ku') {          if ($key eq 'ku') {
164                  selected( -1 );                  selected( -1 );
165          } elsif ($key eq 'kd') {          } elsif ($key eq 'kd') {
166                  selected( +1 );                  selected( +1 );
167            } elsif ($key eq 'pgup' ) {
168                    # first line on screen?
169                    if ( $pos == $top_screen_line ) {
170                            $top_screen_line -= $lines_on_screen;
171                            $top_screen_line = 0;
172                            $pos = $top_screen_line;
173                            redraw;
174                            selected( $pos );
175                    } else {
176                            selected( -( $pos - $top_screen_line ) );
177                    }
178            } elsif ($key eq 'pgdn' ) {
179                    # last line on screen?
180                    if ( $pos - $top_screen_line == $lines_on_screen ) {
181                            $top_screen_line += $lines_on_screen;
182                            $top_screen_line = $#lines - $lines_on_screen if $top_screen_line > $#lines - $lines_on_screen;
183                            $pos = $top_screen_line;
184                            redraw;
185                            selected( $pos );
186                    } else {
187                            selected( $top_screen_line + $scr->rows - $pos - 3 );
188                    }
189            }
190    
191            $status_text = sprintf("pos: %-3d sel_pos: %-3d top_screen_line: %-3d", $pos, $sel_pos, $top_screen_line );
192            if ( length($key) > 1 ) {
193                    $status_text .= " key: $key";
194            } else {
195                    $status_text .= sprintf("key: %s [%03d][%02x]", $key =~ m/\w/ ? $key : '?' , ord($key), ord($key) );
196          }          }
197    
198          status;          status;
199    
200            redraw if lc($key) eq 'r';
201    
202          exit if (lc($key) eq 'q');          exit if (lc($key) eq 'q');
203  }  }
204    

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

  ViewVC Help
Powered by ViewVC 1.1.26