… | |
… | |
32 | |
32 | |
33 | It is possible to activate the most recently seen match or a list of matches |
33 | It is possible to activate the most recently seen match or a list of matches |
34 | from the keyboard. Simply bind a keysym to "matcher:last" or |
34 | from the keyboard. Simply bind a keysym to "matcher:last" or |
35 | "matcher:list" as seen in the example below. |
35 | "matcher:list" as seen in the example below. |
36 | |
36 | |
37 | The 'matcher:select' action enables a mode in which it is possible to |
37 | The C<matcher:select> action enables a mode in which it is possible to |
38 | iterate over the matches using the keyboard and either activate them |
38 | iterate over the matches using the keyboard and either activate them |
39 | or copy them to the clipboard. While the mode is active, normal terminal |
39 | or copy them to the clipboard. While the mode is active, normal terminal |
40 | input/output is suspended and the following bindings are recognized: |
40 | input/output is suspended and the following bindings are recognized: |
41 | |
41 | |
42 | =over 4 |
42 | =over |
43 | |
43 | |
44 | =item C<Up> |
44 | =item C<Up> |
45 | |
45 | |
46 | Search for a match upwards. |
46 | Search for a match upwards. |
47 | |
47 | |
… | |
… | |
68 | =item C<y> |
68 | =item C<y> |
69 | |
69 | |
70 | Copy the current match to the clipboard. |
70 | Copy the current match to the clipboard. |
71 | |
71 | |
72 | =back |
72 | =back |
|
|
73 | |
|
|
74 | It is also possible to cycle through the matches using a key |
|
|
75 | combination bound to the C<matcher:select> action. |
73 | |
76 | |
74 | Example: load and use the matcher extension with defaults. |
77 | Example: load and use the matcher extension with defaults. |
75 | |
78 | |
76 | URxvt.perl-ext: default,matcher |
79 | URxvt.perl-ext: default,matcher |
77 | |
80 | |
… | |
… | |
88 | =cut |
91 | =cut |
89 | |
92 | |
90 | my $url = |
93 | my $url = |
91 | qr{ |
94 | qr{ |
92 | (?:https?://|ftp://|news://|mailto:|file://|\bwww\.) |
95 | (?:https?://|ftp://|news://|mailto:|file://|\bwww\.) |
93 | [\w\-\@;\/?:&=%\$.+!*\x27,~#]* |
96 | [\w\-\@;\/?:&=%\$.+!*\x27,~#$urxvt::NOCHAR]* |
94 | ( |
97 | ( |
95 | \([\w\-\@;\/?:&=%\$.+!*\x27,~#]*\)| # Allow a pair of matched parentheses |
98 | \([\w\-\@;\/?:&=%\$.+!*\x27,~#$urxvt::NOCHAR]*\)| # Allow a pair of matched parentheses |
96 | [\w\-\@;\/?:&=%\$+*~] # exclude some trailing characters (heuristic) |
99 | [\w\-\@;\/?:&=%\$+*~] # exclude some trailing characters (heuristic) |
97 | )+ |
100 | )+ |
98 | }x; |
101 | }x; |
99 | |
102 | |
100 | sub matchlist_key_press { |
103 | sub matchlist_key_press { |
… | |
… | |
248 | } |
251 | } |
249 | } |
252 | } |
250 | |
253 | |
251 | my @defaults = ($url); |
254 | my @defaults = ($url); |
252 | my @matchers; |
255 | my @matchers; |
253 | for (my $idx = 0; defined (my $res = $self->my_resource ("pattern.$idx") || $defaults[$idx]); $idx++) { |
256 | for (my $idx = 0; defined (my $res = $self->locale_decode ($self->my_resource ("pattern.$idx")) || $defaults[$idx]); $idx++) { |
254 | $res = $self->locale_decode ($res); |
|
|
255 | utf8::encode $res; |
|
|
256 | my $launcher = $self->my_resource ("launcher.$idx"); |
257 | my $launcher = $self->my_resource ("launcher.$idx"); |
257 | $launcher =~ s/\$&|\$\{&\}/\${0}/g if $launcher; |
258 | $launcher =~ s/\$&|\$\{&\}/\${0}/g if $launcher; |
258 | my $rend = $self->parse_rend($self->my_resource ("rend.$idx")); |
259 | my $rend = $self->parse_rend($self->my_resource ("rend.$idx")); |
259 | unshift @matchers, [qr($res)x,$launcher,$rend]; |
260 | unshift @matchers, [qr($res)x,$launcher,$rend]; |
260 | } |
261 | } |
… | |
… | |
420 | if (@matches) { |
421 | if (@matches) { |
421 | @matches = sort { $a->[0] <=> $b->[0] or $a->[1] <=> $b->[1] } @matches; |
422 | @matches = sort { $a->[0] <=> $b->[0] or $a->[1] <=> $b->[1] } @matches; |
422 | $self->{matches} = \@matches; |
423 | $self->{matches} = \@matches; |
423 | $self->{cur_row} = $row; |
424 | $self->{cur_row} = $row; |
424 | $self->{id} = $dir < 0 ? @{ $self->{matches} } - 1 : 0; |
425 | $self->{id} = $dir < 0 ? @{ $self->{matches} } - 1 : 0; |
425 | $self->view_start (List::Util::min 0, $row - ($self->nrow >> 1)); |
426 | $self->view_start ($row - ($self->nrow >> 1)); |
426 | $self->want_refresh; |
427 | $self->want_refresh; |
427 | return; |
428 | return 1; |
428 | } |
429 | } |
429 | |
430 | |
430 | $row = $dir < 0 ? $line->beg - 1 : $line->end + 1; |
431 | $row = $dir < 0 ? $line->beg - 1 : $line->end + 1; |
431 | } |
432 | } |
432 | |
433 | |
433 | $self->scr_bell; |
434 | $self->scr_bell; |
|
|
435 | |
|
|
436 | () |
434 | } |
437 | } |
435 | |
438 | |
436 | sub select_refresh { |
439 | sub select_refresh { |
437 | my ($self) = @_; |
440 | my ($self) = @_; |
438 | |
441 | |
… | |
… | |
482 | } else { |
485 | } else { |
483 | my $line = $self->line ($self->{cur_row}); |
486 | my $line = $self->line ($self->{cur_row}); |
484 | $self->select_search (+1, $line->end + 1) |
487 | $self->select_search (+1, $line->end + 1) |
485 | if $line->end < $self->nrow; |
488 | if $line->end < $self->nrow; |
486 | } |
489 | } |
|
|
490 | } elsif ($self->lookup_keysym ($keysym, $event->{state}) eq "matcher:select") { |
|
|
491 | if ($self->{id} > 0) { |
|
|
492 | $self->{id}--; |
|
|
493 | $self->want_refresh; |
|
|
494 | } else { |
|
|
495 | my $line = $self->line ($self->{cur_row}); |
|
|
496 | $self->select_search (-1, $self->nrow - 1) |
|
|
497 | unless $self->select_search (-1, $line->beg - 1); |
|
|
498 | } |
487 | } |
499 | } |
488 | |
500 | |
489 | 1 |
501 | 1 |
490 | } |
502 | } |
491 | |
503 | |