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

Comparing rxvt-unicode/src/perl/matcher (file contents):
Revision 1.14 by root, Sat May 17 13:34:35 2014 UTC vs.
Revision 1.18 by sf-exg, Sun Jun 1 11:47:20 2014 UTC

1#! perl 1#! perl
2 2
3# Author: Tim Pope <rxvt-unicodeNOSPAM@tpope.org> 3# Author: Tim Pope <rxvt-unicodeNOSPAM@tpope.org>
4# Bob Farrell <robertanthonyfarrell@gmail.com> 4# Bob Farrell <robertanthonyfarrell@gmail.com>
5 5
6#:META:X_RESOURCE:%.launcher:string:default launcher command 6#:META:RESOURCE:%.launcher:string:default launcher command
7#:META:X_RESOURCE:%.button:string:the button, yeah 7#:META:RESOURCE:%.button:string:the button, yeah
8#:META:X_RESOURCE:%.pattern.:string:extra pattern to match 8#:META:RESOURCE:%.pattern.:string:extra pattern to match
9#:META:X_RESOURCE:%.launcher.:string:custom launcher for pattern 9#:META:RESOURCE:%.launcher.:string:custom launcher for pattern
10#:META:X_RESOURCE:%.rend.:string:custom rednition for pattern 10#:META:RESOURCE:%.rend.:string:custom rednition for pattern
11 11
12=head1 NAME 12=head1 NAME
13 13
14matcher - match strings in terminal output and change their rendition 14matcher - match strings in terminal output and change their rendition
15 15
17 17
18Uses per-line display filtering (C<on_line_update>) to underline text 18Uses per-line display filtering (C<on_line_update>) to underline text
19matching a certain pattern and make it clickable. When clicked with the 19matching a certain pattern and make it clickable. When clicked with the
20mouse button specified in the C<matcher.button> resource (default 2, or 20mouse button specified in the C<matcher.button> resource (default 2, or
21middle), the program specified in the C<matcher.launcher> resource 21middle), the program specified in the C<matcher.launcher> resource
22(default, the C<urlLauncher> resource, C<sensible-browser>) will be started 22(default, the C<url-launcher> resource, C<sensible-browser>) will be started
23with the matched text as first argument. The default configuration is 23with the matched text as first argument. The default configuration is
24suitable for matching URLs and launching a web browser, like the 24suitable for matching URLs and launching a web browser, like the
25former "mark-urls" extension. 25former "mark-urls" extension.
26 26
27The default pattern to match URLs can be overridden with the 27The default pattern to match URLs can be overridden with the
60 }x; 60 }x;
61 61
62sub on_key_press { 62sub on_key_press {
63 my ($self, $event, $keysym, $octets) = @_; 63 my ($self, $event, $keysym, $octets) = @_;
64 64
65 if (! $self->{showing} ) { 65 return unless $self->{overlay};
66 return; 66
67 } 67 delete $self->{overlay};
68 68
69 my $i = ($keysym == 96 ? 0 : $keysym - 48); 69 my $i = ($keysym == 96 ? 0 : $keysym - 48);
70 if (($i > scalar(@{$self->{urls}})) || ($i < 0)) { 70 if ($i >= 0 && $i < @{ $self->{matches} }) {
71 $self->matchlist(); 71 my @exec = @{ $self->{matches}[$i] };
72 return; 72 shift @exec;
73 $self->exec_async (@exec);
74 }
75
73 } 76 1
74
75 my @args = ($self->{urls}[ -$i-1 ]);
76 $self->matchlist();
77
78 $self->exec_async( $self->{launcher}, @args );
79} 77}
80 78
81# backwards compat 79# backwards compat
82sub on_user_command { 80sub on_user_command {
83 my ($self, $cmd) = @_; 81 my ($self, $cmd) = @_;
96 () 94 ()
97} 95}
98 96
99sub matchlist { 97sub matchlist {
100 my ($self) = @_; 98 my ($self) = @_;
101 if ( $self->{showing} ) { 99
102 $self->{url_overlay}->hide;
103 $self->{showing} = 0;
104 return;
105 }
106 @{$self->{urls}} = (); 100 @{ $self->{matches} } = ();
107 my $line; 101 my $row = $self->nrow - 1;
108 for (my $i = 0; $i < $self->nrow; $i ++) { 102 while ($row >= 0 && @{ $self->{matches} } < 10) {
109 $line = $self->line($i); 103 my $line = $self->line ($row);
110 next if ($line->beg != $i); 104 my $text = $line->t;
111 for my $url ($self->get_urls_from_line($line->t)) { 105
112 if (scalar(@{$self->{urls}}) == 10) { 106 # FIXME: code duplicated from 'command_for'
113 shift @{$self->{urls}}; 107 for my $matcher (@{$self->{matchers}}) {
108 my $launcher = $matcher->[1] || $self->{launcher};
109 while ($text =~ /$matcher->[0]/g) {
110 my $match = substr ($text, $-[0], $+[0] - $-[0]);
111 my @beg = @-;
112 my @end = @+;
113 my @exec;
114
115 if ($launcher !~ /\$/) {
116 @exec = ($launcher, $match);
117 } else {
118 @exec = map { s/\$(\d+)|\$\{(\d+)\}/
119 substr ($text, $beg[$1 || $2], $end[$1 || $2] - $beg[$1 || $2])
120 /egx; $_ } split /\s+/, $launcher;
114 } 121 }
115 push @{$self->{urls}}, $url; 122
123 push @{ $self->{matches} }, [ $match, @exec ];
124 }
116 } 125 }
126
127 $row = $line->beg - 1;
117 } 128 }
118 129
119 if (! scalar(@{$self->{urls}})) { 130 return unless @{ $self->{matches} };
120 return;
121 }
122 131
123 my $max = 0; 132 my $width = 0;
124 my $i = scalar( @{$self->{urls}} ) - 1 ;;
125 133
126 my @temp = ();
127
128 for my $url (@{$self->{urls}}) {
129 my $url = "$i-$url";
130 my $xpos = 0;
131
132 if ($self->ncol + (length $url) >= $self->ncol) {
133 $url = substr( $url, 0, $self->ncol );
134 }
135
136 push @temp, $url;
137
138 if( length $url > $max ) {
139 $max = length $url;
140 }
141
142 $i--;
143 }
144
145 @temp = reverse @temp;
146
147 $self->{url_overlay} = $self->overlay(0, 0, $max, scalar( @temp ), urxvt::OVERLAY_RSTYLE, 2);
148 my $i = 0; 134 my $i = 0;
149 for my $url (@temp) { 135 for my $match (@{ $self->{matches} }) {
150 $self->{url_overlay}->set( 0, $i, $url, [(urxvt::OVERLAY_RSTYLE) x length $url]); 136 my $text = $match->[0];
151 $self->{showing} = 1; 137 my $w = $self->strwidth ("$i-$text");
138
139 $width = $w if $w > $width;
152 $i++; 140 $i++;
153 } 141 }
142
143 $width = $self->ncol - 2 if $width > $self->ncol - 2;
144
145 $self->{overlay} = $self->overlay (0, 0, $width, scalar (@{ $self->{matches} }), urxvt::OVERLAY_RSTYLE, 2);
146 my $i = 0;
147 for my $match (@{ $self->{matches} }) {
148 my $text = $match->[0];
149
150 $self->{overlay}->set (0, $i, "$i-$text");
151 $i++;
152 }
154 153
155} 154}
156 155
157sub most_recent { 156sub most_recent {
158 my ($self) = shift; 157 my ($self) = shift;
190sub on_start { 189sub on_start {
191 my ($self) = @_; 190 my ($self) = @_;
192 191
193 $self->{launcher} = $self->my_resource ("launcher") || $self->x_resource("url-launcher") || "sensible-browser"; 192 $self->{launcher} = $self->my_resource ("launcher") || $self->x_resource("url-launcher") || "sensible-browser";
194 193
195 $self->{urls} = []; 194 $self->{matches} = [];
196 $self->{showing} = 0;
197 $self->{button} = 2; 195 $self->{button} = 2;
198 $self->{state} = 0; 196 $self->{state} = 0;
199 if($self->{argv}[0] || $self->my_resource ("button")) { 197 if($self->{argv}[0] || $self->my_resource ("button")) {
200 my @mods = split '', $self->{argv}[0] || $self->my_resource ("button"); 198 my @mods = split '', $self->{argv}[0] || $self->my_resource ("button");
201 for my $mod (@mods) { 199 for my $mod (@mods) {
224 unshift @matchers, [qr($res)x,$launcher,$rend]; 222 unshift @matchers, [qr($res)x,$launcher,$rend];
225 } 223 }
226 $self->{matchers} = \@matchers; 224 $self->{matchers} = \@matchers;
227 225
228 () 226 ()
229}
230
231sub get_urls_from_line {
232 my ($self, $line) = @_;
233 my @urls;
234 for my $matcher (@{$self->{matchers}}) {
235 while ($line =~ /$matcher->[0]/g) {
236 push @urls, substr( $line, $-[0], $+[0] - $-[0] );
237 }
238 }
239 return @urls;
240} 227}
241 228
242sub on_line_update { 229sub on_line_update {
243 my ($self, $row) = @_; 230 my ($self, $row) = @_;
244 231
330 317
331 if($row == $event->{row} && abs($col-$event->{col}) < 2 318 if($row == $event->{row} && abs($col-$event->{col}) < 2
332 && join("\x00", @$cmd) eq join("\x00", $self->command_for($row,$col))) { 319 && join("\x00", @$cmd) eq join("\x00", $self->command_for($row,$col))) {
333 if($self->valid_button($event)) { 320 if($self->valid_button($event)) {
334 321
335 $self->exec_async (@$cmd); 322 $self->exec_async (@$cmd);
336 323
337 } 324 }
338 } 325 }
339 326
340 1; 327 1;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines