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

Contents of /iselect.pl

Parent Directory Parent Directory | Revision Log Revision Log


Revision 11 - (show annotations)
Thu Oct 25 15:19:51 2007 UTC (12 years, 7 months ago) by dpavlin
File MIME type: text/plain
File size: 4255 byte(s)
- make enter produce message
- different random data
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 $data .= ( rand(10) < 5 ? '{s}' : '' ) . "foobar $_\n" foreach ( 1 .. 300 );
27
28 $data .= "\n--EOF--";
29
30 my $scr;
31
32 # leave sane terminal if script dies
33 $SIG{__DIE__} = sub {
34 eval { system('stty sane'); };
35 };
36
37
38 my @lines = split(/\n/, $data);
39
40 my $top_screen_line = 0; # offset in original text
41 my $pos = 0;
42
43 # default: select first line
44 my $sel_pos = 0;
45 my $status_text = '';
46 my $error_text = '';
47
48 my $status_lines = 3;
49
50 # find which lines are selectable in input file
51 my $selectable_line;
52
53 for my $l (0 .. $#lines) {
54 if ($lines[$l] =~ s/^{s}//) {
55 $selectable_line->{$l}++;
56 }
57 }
58
59 # select first selectable line
60
61 if ( $selectable_line ) {
62 $pos = $sel_pos = (sort { $a <=> $b } keys %$selectable_line)[0];
63 warn "selected first selectable line $sel_pos";
64 }
65
66 sub full_line {
67 my $t = shift;
68 $t = '' unless defined $t;
69 return $t . (" " x ($scr->cols - length($t)));
70 }
71
72 sub chunk {
73 my $t = shift;
74 cluck "expected line" unless defined $t;
75 return substr($t,0,$scr->cols);
76 }
77
78 sub redraw_line {
79 my ($l,$line) = @_;
80
81 if ( defined $selectable_line->{ $l + $top_screen_line } ) {
82 $scr->at($l,0)->bold()->puts( full_line( chunk($line) ) )->normal();
83 } else {
84 $scr->at($l,0)->puts( full_line( chunk($line) ) );
85 }
86 }
87
88 sub redraw {
89 for my $l (0 .. $scr->rows - $status_lines) {
90 my $line = $lines[ $l + $top_screen_line ];
91 redraw_line( $l, $line );
92 last if ($l == $#lines);
93 }
94 selected(0);
95 }
96
97 sub status {
98 my $pcnt = int(($pos || 0) * 100 / ($#lines || 1));
99 my $pos_txt = sprintf('%d, %d%% ',$pos,$pcnt);
100
101 $scr->at($scr->rows - $status_lines + 1,0)->reverse()->puts(
102 sprintf(' %-'.($scr->cols - length($pos_txt) - 2).'s ',$status_text)
103 .$pos_txt)->normal();
104 $scr->at($scr->rows - $status_lines + 2,0)->puts(
105 sprintf('%-'.$scr->cols.'s', $error_text)
106 );
107 }
108
109 sub selected {
110 my $d = shift || 0;
111
112 my $screen_line = $pos - $top_screen_line;
113
114 redraw_line( $screen_line, $lines[$pos] );
115
116 my $last_screen_line = $scr->rows - $status_lines;
117
118 if ( $d < 0 && $screen_line == 0 ) {
119 if ( $pos > 0 ) {
120 $top_screen_line--;
121 $pos--;
122 } else {
123 $error_text = "Already at Begin.";
124 }
125 redraw;
126 } elsif ( $d > 0 && $screen_line == $last_screen_line ) {
127 if ( $pos < $#lines ) {
128 $top_screen_line++;
129 $pos++;
130 } else {
131 $error_text = "Already at End.";
132 }
133 redraw;
134 } else {
135 $pos += $d;
136 }
137
138 my $line = $lines[$pos];
139 if ( defined $selectable_line->{ $pos } ) {
140 $scr->at($pos - $top_screen_line,0)->reverse->bold()->puts( full_line( chunk($line) ) )->normal();
141 $sel_pos = $pos;
142 } else {
143 $scr->at($pos - $top_screen_line,0)->reverse->puts( full_line( chunk($line) ) );
144 $sel_pos = -1;
145 }
146 status;
147 }
148
149 $scr = new Term::Screen || die "can't init Term::Screen";
150 $scr->clrscr()->noecho();
151 redraw;
152 selected;
153
154 while(my $key = $scr->getch()) {
155
156 $error_text = "";
157
158 my $lines_on_screen = $scr->rows - $status_lines;
159
160 if ($key eq 'ku') {
161 selected( -1 );
162 } elsif ($key eq 'kd') {
163 selected( +1 );
164 } elsif ($key eq 'pgup' ) {
165 # first line on screen?
166 if ( $pos == $top_screen_line ) {
167 $top_screen_line -= $lines_on_screen;
168 $top_screen_line = 0 if $top_screen_line < 0;
169 redraw;
170 }
171 selected( -( $pos - $top_screen_line ) );
172 } elsif ($key eq 'pgdn' ) {
173 # last line on screen?
174 if ( $pos - $top_screen_line == $lines_on_screen ) {
175 $top_screen_line += $lines_on_screen;
176 $top_screen_line = $#lines - $lines_on_screen if $top_screen_line >= $#lines - $lines_on_screen;
177 redraw;
178 }
179 selected( $top_screen_line + $lines_on_screen - $pos );
180 }
181
182 $status_text = sprintf("pos: %-3d sel_pos: %-3d top_screen_line: %-3d", $pos, $sel_pos, $top_screen_line );
183 if ( length($key) > 1 ) {
184 $status_text .= " key: $key";
185 } else {
186 $status_text .= sprintf("key: %s [%03d][%02x]", $key =~ m/\w/ ? $key : '?' , ord($key), ord($key) );
187 }
188
189 # CTRL+L
190 redraw if ord($key) eq 0x0c;
191
192 # Enter
193 if ( ord($key) eq 0x0d && $sel_pos > 0 ) {
194 $error_text = "execute: " . $lines[ $sel_pos ];
195 }
196
197 exit if (lc($key) eq 'q');
198
199 status;
200
201 }
202
203 $scr->clrscr();

Properties

Name Value
svn:executable *

  ViewVC Help
Powered by ViewVC 1.1.26