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.34 by root, Mon Jan 23 23:13:03 2006 UTC vs.
Revision 1.60 by sf-exg, Sat May 31 08:33:47 2014 UTC

1#! perl 1#! perl
2 2
3sub on_keyboard_command { 3#:META:RESOURCE:%.pattern-0:string:first selection pattern
4 my ($self, $cmd) = @_;
5 4
6 $cmd eq "selection:rot13" 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 the following actions:
45
46=over 4
47
48=item rot13
49
50Rot-13 the selection when activated.
51
52Example:
53
54 URxvt.keysym.C-M-r: selection:rot13
55
56=back
57
58=cut
59
60sub on_action {
61 my ($self, $action) = @_;
62
63 $action eq "rot13"
7 and $self->selection (map { y/A-Za-z/N-ZA-Mn-za-m/; $_ } $self->selection); 64 and $self->selection (map { y/A-Za-z/N-ZA-Mn-za-m/; $_ } $self->selection);
8 65
9 () 66 ()
10} 67}
11 68
12sub on_init { 69sub on_init {
13 my ($self) = @_; 70 my ($self) = @_;
14 71
72 if (defined (my $res = $self->resource ("cutchars"))) {
73 $res = $self->locale_decode ($res);
74 push @{ $self->{patterns} }, qr{\G [\Q$res\E[:space:]]* ([^\Q$res\E[:space:]]+) }x;
75 }
76
15 for (my $idx = 0; defined (my $res = $self->x_resource ("selection.pattern-$idx")); $idx++) { 77 for (my $idx = 0; defined (my $res = $self->x_resource ("selection.pattern-$idx")); $idx++) {
16 $res = $self->locale_decode ($res); 78 $res = $self->locale_decode ($res);
17 utf8::encode $res;
18 push @{ $self->{patterns} }, qr/$res/; 79 push @{ $self->{patterns} }, qr/$res/;
19 } 80 }
81
82 $self->{enabled} = 1;
83
84 push @{ $self->{term}{option_popup_hook} }, sub {
85 ("new selection" => $self->{enabled}, sub { $self->{enabled} = shift })
86 };
20 87
21 () 88 ()
22} 89}
23 90
24# "find interesting things"-patterns 91# "find interesting things"-patterns
25my @mark_patterns = ( 92my @mark_patterns = (
93# qr{ ([[:word:]]+) }x,
94 qr{ ([^[:space:]]+) }x,
95
26 # common types of "parentheses" 96 # common types of "parentheses"
97 qr{ (?<![^[:space:]]) [`'] ([^`']+) [`'] (?![^[:space:]]) }x,
27 qr{ (?<![^[:space:]]) ‘ ([^‘’]+) ’ (?![^[:space]]) }x, 98 qr{ (?<![^[:space:]]) ‘ ([^‘’]+) ’ (?![^[:space:]]) }x,
28 qr{ (?<![^[:space:]]) ` ([^`']+) ' (?![^[:space]]) }x, 99 qr{ (?<![^[:space:]]) ([^“”]+) (?![^[:space:]]) }x,
100
101 qr{ (?<![^[:space:]]) (' [^[:space:]] [^']* ') }x,
102 qr{ (' [^']* [^[:space:]] ') (?![^[:space:]]) }x,
103 qr{ (?<![^[:space:]]) (` [^[:space:]] [^']* ') }x,
104 qr{ (` [^']* [^[:space:]] ') (?![^[:space:]]) }x,
29 qr{ (?<![^[:space:]]) (" [^[:space:]] [^"]* ") }x, 105 qr{ (?<![^[:space:]]) (" [^[:space:]] [^"]* ") }x,
30 qr{ (" [^"]* [^[:space:]] ") (?![^[:space]]) }x, 106 qr{ (" [^"]* [^[:space:]] ") (?![^[:space:]]) }x,
31 qr{ \< ([^<>[:space:]]+) \> }x, 107
32 qr{ \{ ([^{}[:space:]]+) \} }x, 108 qr{ \{ ([^\{\}]+) \} }x,
33 qr{ \[ ([^{}[:space:]]+) \] }x,
34 qr{ \( ([^()[:space:]]+) \) }x, 109 qr{ \( ([^\(\)]+) \) }x,
110 qr{ \[ ([^\[\]]+) \] }x,
111 qr{ \< ([^\<\>]+) \> }x,
35 112
36 # urls, just a heuristic 113 # urls, just a heuristic
37 qr{( 114 qr{(
38 (?:https?|ftp|news|mailto|file)://[ab-zA-Z0-9\-\@;\/?:&=%\$_.+!*\x27(),~]+ 115 (?:https?://|ftp://|news://|mailto:|file://|\bwww\.)[ab-zA-Z0-9\-\@;\/?:&=%\$_.+!*\x27(),~#]+
39 [ab-zA-Z0-9\-\@;\/?:&=%\$_+!*\x27()~] # exclude some trailing characters (heuristic) 116 [ab-zA-Z0-9\-\@;\/?:&=%\$_+*()~] # exclude some trailing characters (heuristic)
40 )}x, 117 )}x,
41 118
42 # shell-like argument quoting, basically always matches 119 # shell-like argument quoting, basically always matches
43 qr{\G [\ \t|&;<>()]* ( 120 qr{\G [\ \t|&;<>()]* (
44 (?: 121 (?:
57); 134);
58 135
59sub on_sel_extend { 136sub on_sel_extend {
60 my ($self, $time) = @_; 137 my ($self, $time) = @_;
61 138
139 $self->{enabled}
140 or return;
141
62 my ($row, $col) = $self->selection_mark; 142 my ($row, $col) = $self->selection_mark;
63 my $line = $self->line ($row); 143 my $line = $self->line ($row);
64 my $text = $line->t; 144 my $text = $line->t;
65 my $markofs = $line->offset_of ($row, $col); 145 my $markofs = $line->offset_of ($row, $col);
66 my $curlen = $line->offset_of ($self->selection_end) 146 my $curlen = $line->offset_of ($self->selection_end)
67 - $line->offset_of ($self->selection_beg); 147 - $line->offset_of ($self->selection_beg);
68 148
69 my @matches; 149 my @matches;
70 150
71 if ($markofs < $line->l) { 151 if ($markofs < $line->l) {
72 # convert markofs form character to UTF-8 offset space
73 {
74 my $prefix = substr $text, 0, $markofs;
75 utf8::encode $prefix;
76 $markofs = length $prefix;
77 }
78
79 # not doing matches in unicode mode helps speed
80 # enourmously here. working in utf-8 should be
81 # equivalent due to the magic of utf-8 encoding.
82 utf8::encode $text;
83 study $text; # _really_ helps, too :) 152 study $text; # _really_ helps, too :)
84 153
85 for my $regex (@mark_patterns, @{ $self->{patterns} }) { 154 for my $regex (@mark_patterns, @{ $self->{patterns} }) {
86 while ($text =~ /$regex/g) { 155 while ($text =~ /$regex/g) {
87 if ($-[1] <= $markofs and $markofs <= $+[1]) { 156 if ($-[1] <= $markofs and $markofs <= $+[1]) {
107 for (sort { $a->[1] <=> $b->[1] or $b->[0] <=> $a->[0] } @matches) { 176 for (sort { $a->[1] <=> $b->[1] or $b->[0] <=> $a->[0] } @matches) {
108 my ($ofs, $len) = @$_; 177 my ($ofs, $len) = @$_;
109 178
110 next if $len <= $curlen; 179 next if $len <= $curlen;
111 180
112 # convert back from UTF-8 offset space to character space
113 {
114 my $length = substr "$text ", $ofs, $len;
115 utf8::decode $length;
116 $len = length $length;
117 }
118 {
119 my $prefix = substr $text, 0, $ofs;
120 utf8::decode $prefix;
121 $ofs = length $prefix;
122 }
123
124 $self->selection_beg ($line->coord_of ($ofs)); 181 $self->selection_beg ($line->coord_of ($ofs));
125 $self->selection_end ($line->coord_of ($ofs + $len)); 182 $self->selection_end ($line->coord_of ($ofs + $len));
126 return 1; 183 return 1;
127 } 184 }
128 185

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines