--- iselect.pl 2007/10/25 11:22:18 1 +++ bin/iselect.pl 2007/10/25 17:24:33 14 @@ -1,143 +1,44 @@ #!/usr/bin/perl -w use strict; -use Term::Screen; + +use blib; + +use Term::ISelect; use Data::Dump qw/dump/; my $data = <<'EOF'; First line -+first selectable -+ second selectable +{s}first selectable +{s}second selectable a space.... ...infinity and beyond -+foo -+bar +{s}foo +{s}bar bum -EOF -open(my $ps, "ps ax |") || die "can't do ps ax: $!"; -while(<$ps>) { - $data .= '+'.$_; - $data .= ' '.$_; -} -close($ps); - - -my @lines = split(/\n/, $data); - -my $scr = new Term::Screen || die "can't init Term::Screen"; -$scr->clrscr()->noecho(); - -my $o = 0; # offset in original text -my $pos = 0; +EOF -# find which lines are selectable in input file -my $selectable_line; +$data .= ( rand(10) < 5 ? '{s}' : '' ) . "foobar $_\n" foreach ( 1 .. 300 ); -for my $l (0 .. $#lines) { - next if (length($lines[$l]) < 2); - my $foo = ' '; - if ($lines[$l] !~ m/^\s/o) { - $selectable_line->{$l}++; - $foo = '*'; - } - warn "$l: $foo $lines[$l]\n"; -} - -sub full_line { - my $t = shift; - my $l = length($t); - return $t . (" " x ($scr->cols - length($t))); -} - -sub chunk { - my $t = shift; - my $o = ''; - $o = substr($t,1,$scr->cols) if length($t) > 1; - return $o . ( ' ' x ( $scr->cols - length($o) - 1 ) ); -} - -sub redraw { - for my $l (0 .. $scr->rows) { - my $line = $lines[ $l + $o ] || ''; - next if (length($line) < 2); - 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) ) ); - } - last if ($l == $#lines); - } -} - -# default: select first line -my $sel_pos = 0; -my $status_text = ''; -my $error_text = ''; -$pos = 0; - -sub status { - my $pcnt = int(($pos || 0) * 100 / ($#lines || 1)); - my $pos_txt = sprintf('%d, %d%% ',$pos,$pcnt); +$data .= "\n--EOF--"; - $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 || return; - - if ( $selectable_line->{ $pos } ) { - $scr->at($pos-$o,0)->bold()->puts( chunk($lines[$pos]) )->normal(); - } else { - $scr->at($pos-$o,0)->puts( chunk($lines[$pos]) )->normal(); - } - $pos += $d; - - my $max_row = $scr->rows - 3; - - if ($pos < 1) { - $error_text = "Already at Begin."; - $pos = 0; - redraw; - } elsif ($pos > $max_row) { - $o = $pos - $max_row; # put selected line on last - $error_text = "Already at End."; - redraw; - } - - $scr->at($pos-$o,0)->reverse()->puts(chunk($lines[$pos]))->normal(); - status; -} - -$status_text = "let's see does it work?"; -redraw; -selected; - -while(my $key = $scr->getch()) { - - $status_text = "key: $key pos: $pos sel_pos: $sel_pos"; - $error_text = ""; - - if ($key eq 'ku') { - selected( -1 ); - } elsif ($key eq 'kd') { - selected( +1 ); - } - - status; +my @lines = split(/\n/, $data); +warn "lines = ", dump( @lines ); - exit if (lc($key) eq 'q'); -} +my $iselect = Term::ISelect->new({ + lines => [ @lines ], +}); + +$iselect->loop( + sub { + warn "## ",dump(@_); + }, +); -$scr->clrscr();