--- rxvt-unicode/src/perl/selection 2006/01/10 21:20:53 1.19 +++ rxvt-unicode/src/perl/selection 2006/01/17 13:07:16 1.27 @@ -1,4 +1,57 @@ #! perl +use Digest::MD5 qw/md5_hex/; + +my $timers = {}; +my $pastebin_cmd; +my $pastebin_url; + +sub on_start { + my ($self) = @_; + $pastebin_cmd = + (urxvt::untaint $self->x_resource ("selection-pastebin-cmd")) + or "scp -p % ruth:/var/www/www.ta-sa.org/files/txt/"; + + $pastebin_url = + (urxvt::untaint $self->x_resource ("selection-pastebin-url")) + or "http://www.ta-sa.org/files/txt/"; + (); +} + +sub upload_paste { + my ($self) = @_; + + my $txt = $self->selection; + my $h = md5_hex ($txt); + + my $fn = "/tmp/$h.txt"; + + my $msg = "uploaded $h.txt"; + + if (open my $o, ">" . $fn) { + print $o $txt; + close $o; + } else { + $msg = "couldn't write $fn: $!"; + } + + my $cmd = $pastebin_cmd; + $cmd =~ s/%/$fn/; + unless (system ($cmd) == 0) { + $msg = "couldn't upload, '$cmd' failed"; + } + + $self->selection ($pastebin_url . "$h.txt"); + + my $ov = $timers->{ov} = $self->overlay (-1, 0, length ($msg), 1, urxvt::OVERLAY_RSTYLE, 0); + $ov->set (0, 0, $msg); + + $timers->{t1} = + urxvt::timer + ->new + ->start ((int urxvt::NOW) + 5) # make sure we update "on" the second + ->interval (1) + ->cb (sub { delete $timers->{ov}; delete $timers->{t1}; }); +} sub on_keyboard_command { my ($self, $cmd) = @_; @@ -6,23 +59,42 @@ $cmd eq "selection:rot13" and $self->selection (map { y/A-Za-z/N-ZA-Mn-za-m/; $_ } $self->selection); + $cmd eq "selection:remote-pastebin" + and upload_paste ($self); + + () +} + +sub on_init { + my ($self) = @_; + + for (my $idx = 0; defined (my $res = $self->x_resource ("selection.pattern-$idx")); $idx++) { + no re 'eval'; # just to be sure + $res = utf8::encode $self->locale_decode ($res); + push @{ $self->{patterns} }, qr/$res/; + } + () } # "find interetsing things"-patterns my @mark_patterns = ( + # common types of "parentheses" + qr{ (?[:space:]]+) \> }x, + qr{ \{ ([^{}[:space:]]+) \} }x, + qr{ \[ ([^{}[:space:]]+) \] }x, + qr{ \( ([^()[:space:]]+) \) }x, + # urls, just a heuristic qr{( (?:https?|ftp|news|mailto|file)://[ab-zA-Z0-9\-\@;\/?:&=%\$_.+!*\x27(),~]+ [ab-zA-Z0-9\-\@;\/?:&=%\$_+!*\x27()~] # exclude some trailing characters (heuristic) )}x, - # common "parentheses" - qr{(?:^|\s) ‘ ([^‘’]+?) ’ (?:\s|\)|$)}x, - qr{(?:^|\s) ` ([^`']+?) ' (?:\s|\)|$)}x, - qr{ \{ ([^{}]+?) \} }x, - qr{ \[ ([^{}]+?) \] }x, - # shell-like argument quoting, basically always matches qr{\G [\ \t|&;<>()] *( (?: @@ -41,16 +113,26 @@ ); sub on_sel_extend { - my ($self) = @_; + my ($self, $time) = @_; my ($row, $col) = $self->selection_mark; my $line = $self->line ($row); - my $offset = $line->offset_of ($row, $col); my $text = $line->t; + my $markofs = $line->offset_of ($row, $col); + my $curlen = $line->offset_of ($self->selection_end) + - $line->offset_of ($self->selection_beg); + + my @matches; + + # not doing matches in unicode mode helps speed + # enourmously here. working in utf-8 should be + # equivalent due to the magic of utf-8 encoding. + utf8::encode $text; + study $text; # _really_ helps, too :) - for my $regex (@mark_patterns) { + for my $regex (@mark_patterns, @{ $self->{patterns} }) { while ($text =~ /$regex/g) { - if ($-[1] <= $offset and $offset <= $+[1]) { + if ($-[1] <= $markofs and $markofs <= $+[1]) { my $ofs = $-[1]; my $match = $1; @@ -61,12 +143,23 @@ } } - $self->selection_beg ($line->coord_of ($ofs)); - $self->selection_end ($line->coord_of ($ofs + length $match)); - return 1; + push @matches, [$ofs, length $match]; } } } + # whole line + push @matches, [0, ($line->end - $line->beg + 1) * $self->ncol]; + + for (sort { $a->[1] <=> $b->[1] or $b->[0] <=> $a->[0] } @matches) { + my ($ofs, $len) = @$_; + + next if $len <= $curlen; + + $self->selection_beg ($line->coord_of ($ofs)); + $self->selection_end ($line->coord_of ($ofs + $len)); + return 1; + } + () }