url-select: Unset underline flag after partial redraw

This fixes the behaviour where after redraw of only parts of the line
the underline flag was still being set even though the new line doesn't
match anymore. This can be simulated for example by starting an editor,
typing a URL and changing e.g. the http:// part to xttp:// without
changing the line length (vim: rx) where the part beginning with ttp://
keeps being underlined.

This commit sets the 3rd custom rendition bit (starting at 0) of a cell
iff the underline was being added as a result of the cell being part of
a match. If so, on a line update these underline flags get cleared again
(together with the custom rendition bit) to be then re-set after a
(possible) successful match.
This commit is contained in:
Sebastian Schmidt 2015-03-23 18:50:05 +01:00
parent 10c64a552f
commit cc8e579de0

View File

@ -27,6 +27,10 @@
use strict;
# The custom rendition bit to use for marking the cell as being underlined
# by us so we can unset it again after a line has changed.
use constant UNDERLINED => 1<<3; # arbitrarily chosen in hope of no collision
sub on_start {
my ($self) = @_;
@ -94,18 +98,31 @@ sub line_update {
my $text = $line->t;
my $rend = $line->r;
# clear all underlines that were set by us
for (@$rend) {
if (urxvt::GET_CUSTOM($_) & UNDERLINED) {
$_ = urxvt::SET_CUSTOM($_, urxvt::GET_CUSTOM($_)
& ~UNDERLINED) & ~urxvt::RS_Uline;
}
}
for my $pattern (@{$self->{pattern}}) {
while ($text =~ /$pattern/g) {
my $url = $&;
my ($beg, $end) = ($-[0], $+[0] - 1);
for (@{$rend}[$beg .. $end]) {
$_ |= urxvt::RS_Uline;
unless ($_ & urxvt::RS_Uline) {
$_ = urxvt::SET_CUSTOM($_, urxvt::GET_CUSTOM($_)
| UNDERLINED);
$_ |= urxvt::RS_Uline;
}
}
$line->r($rend);
}
}
$line->r($rend);
()
}