ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/rxvt-unicode/src/perl/searchable-scrollback
Revision: 1.3
Committed: Mon Jan 9 23:03:13 2006 UTC (18 years, 4 months ago) by root
Branch: MAIN
Changes since 1.2: +5 -2 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:enter")
11 or warn "unable to register '$hotkey' as scrollback search enter hotkey\n";
12
13 ()
14 }
15
16 sub on_keyboard_command {
17 my ($self, $cmd) = @_;
18
19 if ($cmd eq "searchable-scrollback:enter") {
20 $self->enter;
21 }
22
23 ()
24 }
25
26 sub msg {
27 my ($self, $msg) = @_;
28
29 $self->{overlay} = $self->overlay (0, -1, $self->ncol, 1, urxvt::OVERLAY_RSTYLE, 0);
30 $self->{overlay}->set (0, 0, $self->special_encode ($msg));
31 }
32
33 sub enter {
34 my ($self) = @_;
35
36 return if $self->{overlay};
37
38 $self->{pty_ev_events} = $self->pty_ev_events (urxvt::EVENT_NONE);
39 $self->{view_start} = $self->view_start;
40
41 $self->enable (
42 key_press => \&key_press,
43 refresh_begin => \&refresh,
44 refresh_end => \&refresh,
45 );
46
47 $self->idle;
48 }
49
50 sub leave {
51 my ($self) = @_;
52
53 delete $self->{overlay};
54
55 $self->disable ("key_press", "refresh_begin", "refresh_end");
56
57 $self->pty_ev_events ($self->{pty_ev_events});
58 $self->want_refresh;
59 }
60
61 sub idle {
62 my ($self) = @_;
63
64 $self->msg ("scrollback search, escape=exit, enter=accept, /=start search, n=next, p=previous, G=bottom");
65
66 delete $self->{in_search};
67 }
68
69 sub search {
70 my ($self) = @_;
71
72 my $row = -$self->view_start;
73
74 delete $self->{found};
75
76 no re 'eval'; # just to be sure
77 my $re = qr/$self->{search}/;
78
79 while ($row > -$self->nsaved) {
80 my $line = $self->line ($row)
81 or last;
82
83 my $text = $line->t;
84 if ($text =~ /$re/g) {
85 do {
86 push @{ $self->{found} }, [$line->coord_of ($-[0]), $line->coord_of ($+[0])];
87 } while $text =~ /$re/g;
88
89 $self->view_start (-$row + ($self->nrow >> 1));
90 last;
91 }
92
93 $row = $line->beg - 1;
94 }
95
96 $self->msg ("enter/type/backspace: /$self->{search}_"
97 . ($self->{found} ? "" : " (not found)"));
98 $self->scr_bell unless $self->{found};
99 }
100
101 sub refresh {
102 my ($self) = @_;
103
104 return unless $self->{found};
105
106 $self->scr_xor_span (@$_)
107 for @{ $self->{found} };
108
109 ()
110 }
111
112 sub key_press {
113 my ($self, $event, $keysym, $string) = @_;
114
115 if (exists $self->{in_search}) {
116 if ($keysym == 0xff0d || $keysym == 0xff8d) {
117 $self->idle;
118 } elsif ($keysym == 0xff1b) {
119 $self->view_start ($self->{in_search});
120 $self->idle;
121 } elsif ($keysym == 0xff08) {
122 substr $self->{search}, -1, 1, "";
123
124 $self->search;
125 } elsif ($string ne "") {
126 $self->{search} .= $string;
127
128 $self->search;
129 }
130 } else {
131 if ($keysym == 0xff0d || $keysym == 0xff8d) {
132 # OK
133 $self->leave;
134 } elsif ($keysym == 0xff1b) {
135 $self->view_start ($self->{view_start});
136 $self->leave;
137 } elsif ($keysym == 0xff52) {
138 $self->view_start ($self->view_start + 1);
139 } elsif ($keysym == 0xff54) {
140 $self->view_start ($self->view_start - 1);
141 } elsif ($string eq "/") {
142 $self->{in_search} = $self->view_start;
143 $self->search;
144 } elsif ($string eq "G") {
145 $self->view_start (0);
146 } elsif ($string eq "n") {
147 $self->search;
148 } elsif ($string eq "p") {
149 # TODO
150 } elsif ($string ne "") {
151 $self->scr_bell;
152 }
153 }
154
155 1
156 }
157
158