--- iselect.pl 2007/10/25 13:04:52 5 +++ iselect.pl 2007/10/25 13:24:02 6 @@ -30,6 +30,8 @@ } close($ps); +$data .= "\n--EOF--"; + my $scr; # leave sane terminal if script dies @@ -40,7 +42,7 @@ my @lines = split(/\n/, $data); -my $o = 0; # offset in original text +my $top_screen_line = 0; # offset in original text my $pos = 0; # default: select first line @@ -89,8 +91,7 @@ sub redraw { for my $l (0 .. $scr->rows - 3) { - my $line = $lines[ $l + $o ]; - next if (length($line) < 2); + my $line = $lines[ $l + $top_screen_line ]; redraw_line( $l, $line ); last if ($l == $#lines); } @@ -111,7 +112,7 @@ sub selected { my $d = shift || 0; - my $screen_line = $pos - $o; + my $screen_line = $pos - $top_screen_line; redraw_line( $screen_line, $lines[$pos] ); @@ -119,7 +120,7 @@ if ( $d < 0 && $screen_line == 0 ) { if ( $pos > 0 ) { - $o--; + $top_screen_line--; $pos--; } else { $error_text = "Already at Begin."; @@ -127,7 +128,7 @@ redraw; } elsif ( $d > 0 && $screen_line == $last_screen_line ) { if ( $pos <= $#lines ) { - $o++; + $top_screen_line++; $pos++; } else { $error_text = "Already at End."; @@ -139,10 +140,10 @@ my $line = $lines[$pos]; if ( defined $selectable_line->{ $pos } ) { - $scr->at($pos - $o,0)->reverse->bold()->puts( full_line( chunk($line) ) )->normal(); + $scr->at($pos - $top_screen_line,0)->reverse->bold()->puts( full_line( chunk($line) ) )->normal(); $sel_pos = $pos; } else { - $scr->at($pos - $o,0)->reverse->puts( full_line( chunk($line) ) ); + $scr->at($pos - $top_screen_line,0)->reverse->puts( full_line( chunk($line) ) ); $sel_pos = -1; } status; @@ -157,13 +158,37 @@ $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 offset: %-3d", $pos, $sel_pos, $o ); + $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 {