ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/rxvt-unicode/src/perl/searchable-scrollback
(Generate patch)

Comparing rxvt-unicode/src/perl/searchable-scrollback (file contents):
Revision 1.32 by root, Sat May 17 13:38:23 2014 UTC vs.
Revision 1.43 by root, Fri Dec 26 19:19:30 2014 UTC

1#! perl 1#! perl
2 2
3# this extension implements scrollback buffer search 3# this extension implements scrollback buffer search
4 4
5#:META:RESOURCE:%:string:activation hotkey keysym 5#:META:RESOURCE:%:string:activation hotkey keysym
6#:META:KEYSYM:M-s:searchable-scrollback:start
7 6
8=head1 NAME 7=head1 NAME
9 8
10searchable-scrollback<hotkey> - incremental scrollback search (enabled by default) 9searchable-scrollback - incremental scrollback search (enabled by default)
11 10
12=head1 DESCRIPTION 11=head1 DESCRIPTION
13 12
14Adds regex search functionality to the scrollback buffer, triggered 13Adds regex search functionality to the scrollback buffer, triggered by
15by a hotkey (default: C<M-s>). While in search mode, normal terminal 14the C<searchable-scrollback:start> action (bound to C<M-s> by
15default). While in search mode, normal terminal input/output is
16input/output is suspended and a regex is displayed at the bottom of the 16suspended and a regex is displayed at the bottom of the screen.
17screen.
18 17
19Inputting characters appends them to the regex and continues incremental 18Inputting characters appends them to the regex and continues incremental
20search. C<BackSpace> removes a character from the regex, C<Up> and C<Down> 19search. C<BackSpace> removes a character from the regex, C<Up> and C<Down>
21search upwards/downwards in the scrollback buffer, C<End> jumps to the 20search upwards/downwards in the scrollback buffer, C<End> jumps to the
22bottom. C<Escape> leaves search mode and returns to the point where search 21bottom. C<Escape> leaves search mode and returns to the point where search
33=cut 32=cut
34 33
35sub on_init { 34sub on_init {
36 my ($self) = @_; 35 my ($self) = @_;
37 36
37 # only for backwards compatibility
38 my $hotkey = $self->{argv}[0] 38 my $hotkey = $self->{argv}[0]
39 || $self->x_resource ("%") 39 || $self->x_resource ("%")
40 || "M-s"; 40 || "M-s";
41 41
42 $self->parse_keysym ($hotkey, "perl:searchable-scrollback:start") 42 $self->bind_action ($hotkey, "%:start")
43 or warn "unable to register '$hotkey' as scrollback search start hotkey\n"; 43 or warn "unable to register '$hotkey' as scrollback search start hotkey\n";
44 44
45 () 45 ()
46} 46}
47 47
48sub on_user_command { 48sub on_user_command {
49 my ($self, $cmd) = @_; 49 my ($self, $cmd) = @_;
50 50
51 $cmd eq "searchable-scrollback:start" 51 $cmd eq "searchable-scrollback:start"
52 and $self->enter;
53
54 ()
55}
56
57sub on_action {
58 my ($self, $action) = @_;
59
60 $action eq "start"
52 and $self->enter; 61 and $self->enter;
53 62
54 () 63 ()
55} 64}
56 65
90 $self->disable ("key_press", "tt_write", "refresh_begin", "refresh_end"); 99 $self->disable ("key_press", "tt_write", "refresh_begin", "refresh_end");
91 $self->pty_ev_events ($self->{pty_ev_events}); 100 $self->pty_ev_events ($self->{pty_ev_events});
92 101
93 delete $self->{manpage_overlay}; 102 delete $self->{manpage_overlay};
94 delete $self->{overlay}; 103 delete $self->{overlay};
95 delete $self->{history};
96 delete $self->{search}; 104 delete $self->{search};
105 delete $self->{found};
97} 106}
98 107
99sub idle { 108sub idle {
100 my ($self) = @_; 109 my ($self) = @_;
101 110
102 $self->msg ("(escape cancels) /$self->{search}█"); 111 $self->msg ("(escape cancels) /$self->{search}█");
103} 112}
104 113
105sub search { 114sub search {
106 my ($self, $dir) = @_; 115 my ($self, $dir, $row) = @_;
107
108 delete $self->{found};
109 my $row = $self->{row};
110 116
111 my $search = $self->special_encode ($self->{search}); 117 my $search = $self->special_encode ($self->{search});
112 118
113 no re 'eval'; # just to be sure 119 no re 'eval'; # just to be sure
114 if (my $re = eval { qr/$search/ }) { 120 if (my $re = eval { qr/$search/ }) {
116 my $line = $self->line ($row) 122 my $line = $self->line ($row)
117 or last; 123 or last;
118 124
119 my $text = $line->t; 125 my $text = $line->t;
120 if ($text =~ /$re/g) { 126 if ($text =~ /$re/g) {
127 delete $self->{found};
128
121 do { 129 do {
122 push @{ $self->{found} }, [$line->coord_of ($-[0]), $line->coord_of ($+[0])]; 130 push @{ $self->{found} }, [$line->coord_of ($-[0]), $line->coord_of ($+[0])];
123 } while $text =~ /$re/g; 131 } while $text =~ /$re/g;
124 132
125 $self->{row} = $row; 133 $self->{row} = $row;
126 $self->view_start (List::Util::min 0, $row - ($self->nrow >> 1)); 134 $self->view_start (List::Util::min 0, $row - ($self->nrow >> 1));
127 $self->want_refresh; 135 $self->want_refresh;
128 last; 136 return;
129 } 137 }
130 138
131 $row = $dir < 0 ? $line->beg - 1 : $line->end + 1; 139 $row = $dir < 0 ? $line->beg - 1 : $line->end + 1;
132 } 140 }
133 } 141 }
134 142
135 $self->scr_bell unless $self->{found}; 143 $self->scr_bell;
136} 144}
137 145
138sub refresh { 146sub refresh {
139 my ($self) = @_; 147 my ($self) = @_;
140 148
167 $self->leave; 175 $self->leave;
168 } elsif ($keysym == 0xff57) { # end 176 } elsif ($keysym == 0xff57) { # end
169 $self->{row} = $self->nrow - 1; 177 $self->{row} = $self->nrow - 1;
170 $self->view_start (0); 178 $self->view_start (0);
171 } elsif ($keysym == 0xff52) { # up 179 } elsif ($keysym == 0xff52) { # up
172 $self->{row}-- if $self->{row} > $self->top_row; 180 my $line = $self->line ($self->{row});
173 $self->search (-1); 181 $self->search (-1, $line->beg - 1)
182 if $line->beg > $self->top_row;
174 } elsif ($keysym == 0xff54) { # down 183 } elsif ($keysym == 0xff54) { # down
175 $self->{row}++ if $self->{row} < $self->nrow; 184 my $line = $self->line ($self->{row});
176 $self->search (+1); 185 $self->search (+1, $line->end + 1)
186 if $line->end < $self->nrow;
177 } elsif ($keysym == 0xff08) { # backspace 187 } elsif ($keysym == 0xff08) { # backspace
178 substr $self->{search}, -1, 1, ""; 188 substr $self->{search}, -1, 1, "";
179 $self->search; 189 $self->search (+1, $self->{row});
180 $self->idle; 190 $self->idle;
181 } elsif ($string !~ /[\x00-\x1f\x80-\xaf]/) { 191 } elsif ($string !~ /[\x00-\x1f\x80-\xaf]/) {
182 return; # pass to tt_write 192 return; # pass to tt_write
183 } 193 }
184 194
191 $self->{search} .= $self->locale_decode ($data); 201 $self->{search} .= $self->locale_decode ($data);
192 202
193 $self->{search} =~ s/^\(\?i\)// 203 $self->{search} =~ s/^\(\?i\)//
194 if $self->{search} =~ /^\(.*[[:upper:]]/; 204 if $self->{search} =~ /^\(.*[[:upper:]]/;
195 205
206 delete $self->{found};
196 $self->search (-1); 207 $self->search (-1, $self->{row});
197 $self->idle; 208 $self->idle;
198 209
199 1 210 1
200} 211}
201 212

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines