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

Comparing rxvt-unicode/src/perl/selection (file contents):
Revision 1.36 by root, Wed Jan 25 15:33:43 2006 UTC vs.
Revision 1.58 by root, Sat May 17 13:38:23 2014 UTC

1#! perl 1#! perl
2
3#:META:RESOURCE:%.pattern-0:string:first selection pattern
4
5=head1 NAME
6
7selection - more intelligent selection (enabled by default)
8
9=head1 DESCRIPTION
10
11This extension tries to be more intelligent when the user extends
12selections (double-click and further clicks). Right now, it tries to
13select words, urls and complete shell-quoted arguments, which is very
14convenient, too, if your F<ls> supports C<--quoting-style=shell>.
15
16A double-click usually selects the word under the cursor, further clicks
17will enlarge the selection.
18
19The selection works by trying to match a number of regexes and displaying
20them in increasing order of length. You can add your own regexes by
21specifying resources of the form:
22
23 URxvt.selection.pattern-0: perl-regex
24 URxvt.selection.pattern-1: perl-regex
25 ...
26
27The index number (0, 1...) must not have any holes, and each regex must
28contain at least one pair of capturing parentheses, which will be used for
29the match. For example, the following adds a regex that matches everything
30between two vertical bars:
31
32 URxvt.selection.pattern-0: \\|([^|]+)\\|
33
34Another example: Programs I use often output "absolute path: " at the
35beginning of a line when they process multiple files. The following
36pattern matches the filename (note, there is a single space at the very
37end):
38
39 URxvt.selection.pattern-0: ^(/[^:]+):\
40
41You can look at the source of the selection extension to see more
42interesting uses, such as parsing a line from beginning to end.
43
44This extension also offers following bindable keyboard commands:
45
46=over 4
47
48=item rot13
49
50Rot-13 the selection when activated. Used via keyboard trigger:
51
52 URxvt.keysym.C-M-r: perl:selection:rot13
53
54=back
55
56=cut
2 57
3sub on_user_command { 58sub on_user_command {
4 my ($self, $cmd) = @_; 59 my ($self, $cmd) = @_;
5 60
6 $cmd eq "selection:rot13" 61 $cmd eq "selection:rot13"
7 and $self->selection (map { y/A-Za-z/N-ZA-Mn-za-m/; $_ } $self->selection); 62 and $self->selection (map { y/A-Za-z/N-ZA-Mn-za-m/; $_ } $self->selection);
8 63
9 () 64 ()
65}
66
67sub on_keyboard_dispatch {
68 &on_user_command;
10} 69}
11 70
12sub on_init { 71sub on_init {
13 my ($self) = @_; 72 my ($self) = @_;
14 73
17 push @{ $self->{patterns} }, qr{\G [\Q$res\E[:space:]]* ([^\Q$res\E[:space:]]+) }x; 76 push @{ $self->{patterns} }, qr{\G [\Q$res\E[:space:]]* ([^\Q$res\E[:space:]]+) }x;
18 } 77 }
19 78
20 for (my $idx = 0; defined (my $res = $self->x_resource ("selection.pattern-$idx")); $idx++) { 79 for (my $idx = 0; defined (my $res = $self->x_resource ("selection.pattern-$idx")); $idx++) {
21 $res = $self->locale_decode ($res); 80 $res = $self->locale_decode ($res);
22 utf8::encode $res;
23 push @{ $self->{patterns} }, qr/$res/; 81 push @{ $self->{patterns} }, qr/$res/;
24 } 82 }
83
84 $self->{enabled} = 1;
85
86 push @{ $self->{term}{option_popup_hook} }, sub {
87 ("new selection" => $self->{enabled}, sub { $self->{enabled} = shift })
88 };
25 89
26 () 90 ()
27} 91}
28 92
29# "find interesting things"-patterns 93# "find interesting things"-patterns
30my @mark_patterns = ( 94my @mark_patterns = (
95# qr{ ([[:word:]]+) }x,
96 qr{ ([^[:space:]]+) }x,
97
31 # common types of "parentheses" 98 # common types of "parentheses"
99 qr{ (?<![^[:space:]]) [`'] ([^`']+) [`'] (?![^[:space:]]) }x,
32 qr{ (?<![^[:space:]]) ‘ ([^‘’]+) ’ (?![^[:space]]) }x, 100 qr{ (?<![^[:space:]]) ‘ ([^‘’]+) ’ (?![^[:space:]]) }x,
33 qr{ (?<![^[:space:]]) ` ([^`']+) ' (?![^[:space]]) }x, 101 qr{ (?<![^[:space:]]) ([^“”]+) (?![^[:space:]]) }x,
102
103 qr{ (?<![^[:space:]]) (' [^[:space:]] [^']* ') }x,
104 qr{ (' [^']* [^[:space:]] ') (?![^[:space:]]) }x,
105 qr{ (?<![^[:space:]]) (` [^[:space:]] [^']* ') }x,
106 qr{ (` [^']* [^[:space:]] ') (?![^[:space:]]) }x,
34 qr{ (?<![^[:space:]]) (" [^[:space:]] [^"]* ") }x, 107 qr{ (?<![^[:space:]]) (" [^[:space:]] [^"]* ") }x,
35 qr{ (" [^"]* [^[:space:]] ") (?![^[:space]]) }x, 108 qr{ (" [^"]* [^[:space:]] ") (?![^[:space:]]) }x,
36 qr{ \< ([^<>[:space:]]+) \> }x, 109
37 qr{ \{ ([^{}[:space:]]+) \} }x, 110 qr{ \{ ([^\{\}]+) \} }x,
38 qr{ \[ ([^{}[:space:]]+) \] }x,
39 qr{ \( ([^()[:space:]]+) \) }x, 111 qr{ \( ([^\(\)]+) \) }x,
112 qr{ \[ ([^\[\]]+) \] }x,
113 qr{ \< ([^\<\>]+) \> }x,
40 114
41 # urls, just a heuristic 115 # urls, just a heuristic
42 qr{( 116 qr{(
43 (?:https?|ftp|news|mailto|file)://[ab-zA-Z0-9\-\@;\/?:&=%\$_.+!*\x27(),~]+ 117 (?:https?://|ftp://|news://|mailto:|file://|\bwww\.)[ab-zA-Z0-9\-\@;\/?:&=%\$_.+!*\x27(),~#]+
44 [ab-zA-Z0-9\-\@;\/?:&=%\$_+!*\x27()~] # exclude some trailing characters (heuristic) 118 [ab-zA-Z0-9\-\@;\/?:&=%\$_+*()~] # exclude some trailing characters (heuristic)
45 )}x, 119 )}x,
46 120
47 # shell-like argument quoting, basically always matches 121 # shell-like argument quoting, basically always matches
48 qr{\G [\ \t|&;<>()]* ( 122 qr{\G [\ \t|&;<>()]* (
49 (?: 123 (?:
62); 136);
63 137
64sub on_sel_extend { 138sub on_sel_extend {
65 my ($self, $time) = @_; 139 my ($self, $time) = @_;
66 140
141 $self->{enabled}
142 or return;
143
67 my ($row, $col) = $self->selection_mark; 144 my ($row, $col) = $self->selection_mark;
68 my $line = $self->line ($row); 145 my $line = $self->line ($row);
69 my $text = $line->t; 146 my $text = $line->t;
70 my $markofs = $line->offset_of ($row, $col); 147 my $markofs = $line->offset_of ($row, $col);
71 my $curlen = $line->offset_of ($self->selection_end) 148 my $curlen = $line->offset_of ($self->selection_end)
72 - $line->offset_of ($self->selection_beg); 149 - $line->offset_of ($self->selection_beg);
73 150
74 my @matches; 151 my @matches;
75 152
76 if ($markofs < $line->l) { 153 if ($markofs < $line->l) {
77 # convert markofs form character to UTF-8 offset space
78 {
79 my $prefix = substr $text, 0, $markofs;
80 utf8::encode $prefix;
81 $markofs = length $prefix;
82 }
83
84 # not doing matches in unicode mode helps speed
85 # enourmously here. working in utf-8 should be
86 # equivalent due to the magic of utf-8 encoding.
87 utf8::encode $text;
88 study $text; # _really_ helps, too :) 154 study $text; # _really_ helps, too :)
89 155
90 for my $regex (@mark_patterns, @{ $self->{patterns} }) { 156 for my $regex (@mark_patterns, @{ $self->{patterns} }) {
91 while ($text =~ /$regex/g) { 157 while ($text =~ /$regex/g) {
92 if ($-[1] <= $markofs and $markofs <= $+[1]) { 158 if ($-[1] <= $markofs and $markofs <= $+[1]) {
112 for (sort { $a->[1] <=> $b->[1] or $b->[0] <=> $a->[0] } @matches) { 178 for (sort { $a->[1] <=> $b->[1] or $b->[0] <=> $a->[0] } @matches) {
113 my ($ofs, $len) = @$_; 179 my ($ofs, $len) = @$_;
114 180
115 next if $len <= $curlen; 181 next if $len <= $curlen;
116 182
117 # convert back from UTF-8 offset space to character space
118 {
119 my $length = substr "$text ", $ofs, $len;
120 utf8::decode $length;
121 $len = length $length;
122 }
123 {
124 my $prefix = substr $text, 0, $ofs;
125 utf8::decode $prefix;
126 $ofs = length $prefix;
127 }
128
129 $self->selection_beg ($line->coord_of ($ofs)); 183 $self->selection_beg ($line->coord_of ($ofs));
130 $self->selection_end ($line->coord_of ($ofs + $len)); 184 $self->selection_end ($line->coord_of ($ofs + $len));
131 return 1; 185 return 1;
132 } 186 }
133 187

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines