ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/rxvt-unicode/src/perl/searchable-scrollback
Revision: 1.9
Committed: Tue Jan 10 04:24:52 2006 UTC (18 years, 4 months ago) by root
Branch: MAIN
Changes since 1.8: +1 -1 lines
Log Message:
*** empty log message ***

File Contents

# Content
1 #! perl
2
3 # this extension implements scrollback buffer search
4
5 sub on_init {
6 my ($self) = @_;
7
8 my $hotkey = $self->{argv}[0] || "M-s";
9
10 $self->parse_keysym ($hotkey, "perl:searchable-scrollback:start")
11 or warn "unable to register '$hotkey' as scrollback search start hotkey\n";
12
13 ()
14 }
15
16 sub on_keyboard_command {
17 my ($self, $cmd) = @_;
18
19 $cmd eq "searchable-scrollback:start"
20 and $self->enter;
21
22 ()
23 }
24
25 sub msg {
26 my ($self, $msg) = @_;
27
28 $self->{overlay} = $self->overlay (0, -1, $self->ncol, 1, urxvt::OVERLAY_RSTYLE, 0);
29 $self->{overlay}->set (0, 0, $self->special_encode ($msg));
30 }
31
32 sub enter {
33 my ($self) = @_;
34
35 return if $self->{overlay};
36
37 $self->{history} = [];
38 $self->{view_start} = $self->view_start;
39 $self->{pty_ev_events} = $self->pty_ev_events (urxvt::EVENT_NONE);
40
41 $self->enable (
42 key_press => \&key_press,
43 tt_write => \&tt_write,
44 refresh_begin => \&refresh,
45 refresh_end => \&refresh,
46 );
47
48 $self->{manpage_overlay} = $self->overlay (0, -2, $self->ncol, 1, urxvt::OVERLAY_RSTYLE, 0);
49 $self->{manpage_overlay}->set (0, 0, "scrollback search, see man ${urxvt::RXVTNAME}perl");
50
51 $self->idle;
52 }
53
54 sub leave {
55 my ($self) = @_;
56
57 $self->disable ("key_press", "tt_write", "refresh_begin", "refresh_end");
58 $self->pty_ev_events ($self->{pty_ev_events});
59
60 delete $self->{manpage_overlay};
61 delete $self->{overlay};
62 delete $self->{history};
63 }
64
65 sub idle {
66 my ($self) = @_;
67
68 $self->msg ("escape=exit, enter=accept, /=start search, n=next, p=previous, G=bottom");
69
70 delete $self->{in_search};
71 }
72
73 sub search {
74 my ($self, $offset) = @_;
75
76 my $row = -$self->view_start + ($self->nrow >> 1) + $offset;
77
78 delete $self->{found};
79
80 my $search = $self->special_encode ($self->{search});
81
82 no re 'eval'; # just to be sure
83 my $re = qr/$search/;
84
85 while ($row > -$self->nsaved) {
86 my $line = $self->line ($row)
87 or last;
88
89 my $text = $line->t;
90 if ($text =~ /$re/g) {
91 do {
92 push @{ $self->{found} }, [$line->coord_of ($-[0]), $line->coord_of ($+[0])];
93 } while $text =~ /$re/g;
94
95 $self->view_start (-$row + ($self->nrow >> 1));
96 last;
97 }
98
99 $row = $line->beg - 1;
100 }
101
102 $self->msg ("enter/type/backspace: /$self->{search}_"
103 . ($self->{found} ? "" : " (not found)"));
104 $self->scr_bell unless $self->{found};
105 }
106
107 sub refresh {
108 my ($self) = @_;
109
110 return unless $self->{found};
111
112 $self->scr_xor_span (@$_, urxvt::SET_FGCOLOR (urxvt::RS_RVid, 15))
113 for @{ $self->{found} };
114
115 ()
116 }
117
118 sub key_press {
119 my ($self, $event, $keysym, $string) = @_;
120
121 if (exists $self->{in_search}) {
122 if ($keysym == 0xff0d || $keysym == 0xff8d) {
123 $self->idle;
124 } elsif ($keysym == 0xff1b) {
125 $self->view_start ($self->{in_search});
126 $self->idle;
127 } elsif ($keysym == 0xff08) {
128 substr $self->{search}, -1, 1, "";
129 $self->search;
130 } elsif ($string ne "") {
131 return;
132 }
133
134 } else {
135 if ($keysym == 0xff0d || $keysym == 0xff8d) {
136 # TODO: set selection
137 $self->leave;
138 } elsif ($keysym == 0xff1b) {
139 $self->view_start ($self->{view_start});
140 $self->leave;
141 } elsif ($keysym == 0xff52) {
142 $self->view_start ($self->view_start + 1);
143 } elsif ($keysym == 0xff54) {
144 $self->view_start ($self->view_start - 1);
145 } elsif ($string eq "/") {
146 delete $self->{manpage_overlay};
147 $self->{in_search} = $self->view_start;
148 $self->search;
149 } elsif ($string eq "G") {
150 $self->{history} = [];
151 $self->view_start (0);
152 } elsif ($string eq "n") {
153 if ($self->{found} && @{ $self->{found} }) {
154 push @{ $self->{history} }, [$self->view_start, $self->{found}];
155 $self->search (-1);
156 $self->idle;
157 }
158 } elsif ($string eq "p" or $string eq "N") {
159 if (my $prev = pop @{ $self->{history} }) {
160 $self->view_start ($prev->[0]);
161 $self->{found} = $prev->[1];
162 $self->want_refresh;
163 }
164 } elsif ($string ne "") {
165 $self->scr_bell;
166 }
167 }
168
169 1
170 }
171
172 sub tt_write {
173 my ($self, $data) = @_;
174
175 $self->{search} .= $self->locale_decode ($data);
176 $self->search;
177
178 1
179 }
180
181