/[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

Contents of /bin/iselect.pl

Parent Directory Parent Directory | Revision Log Revision Log


Revision 7 - (show annotations)
Thu Oct 25 14:11:42 2007 UTC (16 years, 6 months ago) by dpavlin
Original Path: iselect.pl
File MIME type: text/plain
File size: 4077 byte(s)
- fixed pageup/down
- ctrl+l now redraws screen
1 #!/usr/bin/perl -w
2
3 use strict;
4 use Term::Screen;
5 use Carp qw/cluck/;
6 use Data::Dump qw/dump/;
7
8 my $data = <<'EOF';
9 First line
10
11 {s}first selectable
12 {s}second selectable
13
14 a space....
15
16 ...infinity and beyond
17
18
19 {s}foo
20 {s}bar
21
22 bum
23
24 EOF
25
26 open(my $ps, "ps ax |") || die "can't do ps ax: $!";
27 while(<$ps>) {
28 $data .= '{s}'.$_;
29 $data .= $_;
30 }
31 close($ps);
32
33 $data .= "\n--EOF--";
34
35 my $scr;
36
37 # leave sane terminal if script dies
38 $SIG{__DIE__} = sub {
39 eval { system('stty sane'); };
40 };
41
42
43 my @lines = split(/\n/, $data);
44
45 my $top_screen_line = 0; # offset in original text
46 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
55 my $selectable_line;
56
57 for my $l (0 .. $#lines) {
58 if ($lines[$l] !~ s/^{s}//) {
59 $selectable_line->{$l}++;
60 }
61 }
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 {
71 my $t = shift;
72 $t = '' unless defined $t;
73 return $t . (" " x ($scr->cols - length($t)));
74 }
75
76 sub chunk {
77 my $t = shift;
78 cluck "expected line" unless defined $t;
79 return substr($t,0,$scr->cols);
80 }
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 {
93 for my $l (0 .. $scr->rows - 3) {
94 my $line = $lines[ $l + $top_screen_line ];
95 redraw_line( $l, $line );
96 last if ($l == $#lines);
97 }
98 selected(0);
99 }
100
101 sub status {
102 my $pcnt = int(($pos || 0) * 100 / ($#lines || 1));
103 my $pos_txt = sprintf('%d, %d%% ',$pos,$pcnt);
104
105 $scr->at($scr->rows - 2,0)->reverse()->puts(
106 sprintf(' %-'.($scr->cols - length($pos_txt) - 2).'s ',$status_text)
107 .$pos_txt)->normal();
108 $scr->at($scr->rows - 1,0)->puts(
109 sprintf('%-'.$scr->cols.'s', $error_text)
110 );
111 }
112
113 sub selected {
114 my $d = shift || 0;
115
116 my $screen_line = $pos - $top_screen_line;
117
118 redraw_line( $screen_line, $lines[$pos] );
119
120 my $last_screen_line = $scr->rows - 3;
121
122 if ( $d < 0 && $screen_line == 0 ) {
123 if ( $pos > 0 ) {
124 $top_screen_line--;
125 $pos--;
126 } else {
127 $error_text = "Already at Begin.";
128 }
129 redraw;
130 } elsif ( $d > 0 && $screen_line == $last_screen_line ) {
131 if ( $pos < $#lines ) {
132 $top_screen_line++;
133 $pos++;
134 } else {
135 $error_text = "Already at End.";
136 }
137 redraw;
138 } else {
139 $pos += $d;
140 }
141
142 my $line = $lines[$pos];
143 if ( defined $selectable_line->{ $pos } ) {
144 $scr->at($pos - $top_screen_line,0)->reverse->bold()->puts( full_line( chunk($line) ) )->normal();
145 $sel_pos = $pos;
146 } else {
147 $scr->at($pos - $top_screen_line,0)->reverse->puts( full_line( chunk($line) ) );
148 $sel_pos = -1;
149 }
150 status;
151 }
152
153 $scr = new Term::Screen || die "can't init Term::Screen";
154 $scr->clrscr()->noecho();
155 redraw;
156 selected;
157
158 while(my $key = $scr->getch()) {
159
160 $error_text = "";
161
162 my $lines_on_screen = $scr->rows - 3;
163
164 if ($key eq 'ku') {
165 selected( -1 );
166 } elsif ($key eq 'kd') {
167 selected( +1 );
168 } elsif ($key eq 'pgup' ) {
169 # first line on screen?
170 if ( $pos == $top_screen_line ) {
171 $top_screen_line -= $lines_on_screen;
172 $top_screen_line = 0 if $top_screen_line < 0;
173 redraw;
174 }
175 selected( -( $pos - $top_screen_line ) );
176 } elsif ($key eq 'pgdn' ) {
177 # last line on screen?
178 if ( $pos - $top_screen_line == $lines_on_screen ) {
179 $top_screen_line += $lines_on_screen;
180 $top_screen_line = $#lines - $lines_on_screen if $top_screen_line >= $#lines - $lines_on_screen;
181 redraw;
182 }
183 selected( $top_screen_line + $lines_on_screen - $pos );
184 }
185
186 $status_text = sprintf("pos: %-3d sel_pos: %-3d top_screen_line: %-3d", $pos, $sel_pos, $top_screen_line );
187 if ( length($key) > 1 ) {
188 $status_text .= " key: $key";
189 } else {
190 $status_text .= sprintf("key: %s [%03d][%02x]", $key =~ m/\w/ ? $key : '?' , ord($key), ord($key) );
191 }
192
193 status;
194
195 # CTRL+L
196 redraw if ord($key) eq 0x0c;
197
198 exit if (lc($key) eq 'q');
199 }
200
201 $scr->clrscr();

Properties

Name Value
svn:executable *

  ViewVC Help
Powered by ViewVC 1.1.26