Hello,
I wanted to join this thread to say that I also have a version of
url-select that I've adapted to select wrapped URLs. I don't use panes
so there is no support for that, but there is support for lines
wrapped with '\' in Emacs, as well as lines which are wrapped with a
"\n" (as from curses-based applications). Also, patterns are grouped
into several "modes" - you can match whole lines, commands entered at
a prompt (">" or "$"), things that look like file names, or numbers,
as well as proper URLs. User can switch modes with various keys, e.g.
"P" for prompt strings, "U" for URLs, "F" for files. The matching
strings are underlined only while the extension is "active". I use my
modified url-select very often, mostly to copy commands I've entered
in readline-based applications, but also to copy URLs.
I haven't put it on Github or anything but can do so if anyone is
interested.
Frederick
On Sat, Mar 25, 2017 at 09:54:49PM +0200, Dimitrios Semitsoglou-Tsiapos wrote:
> Greetings Alex, list,
>
> I hope there's room for.. competing implementations, as a while ago I
> wrote a patch that does this, except it matches inside panes (eg
> tmux panes, mutt with sidebar and weechat with sidebars). For this I use
> regex delimiters, so it can be made to work with other applications as
> well. In short, delimiter pairs are found (even nested ones) and using
> their location, the patch works its way upward line by line and returns
> an array of coordinates.
>
> I would very much like to see what other applications that split URLs in
> a similar fashion look like so that I can add support for more out of the
> box. I am attaching a file of loosely compiled test cases, so you may
> add to it.
>
> Limitations:
>
> The main user-facing limitation is that because it is not possible to
> tell where a URL ends, the user has to click the last part of the URL
> they wish to open (eg the third line of a three-line URL).
>
> This also means that for very long URLs, this fills perl:matcher:list
> rather quickly.
>
> It currently relies on matches being /\S+/, therefore this won't work
> for those who match against filepaths with spaces for example. This
> can be worked around, but I believe it would be computationally
> costly.
>
> Editing a wrapped URL in eg, vim does not update correctly until you
> have vim redraw its last chunk. This can also be worked around, but
> I found that it will add a lot of complexity (we'd have to figure
> out if there have been an updates on any section of every URL and
> call the matcher very frequently on many lines) for little gain.
>
> Bonus:
>
> With this in place, you can have applications make use of it. For
> example, try this script[1] for making `lynx -dump` easier to use in
> mutt via your mailcap, by adding a column with clickable URLs.
>
>
> PS. In case there is no upstream interest for a patch this large,
> patches are also welcome on github[2].
>
> [1] https://github.com/dset0x/lynx-dump-url-columns
> [2] https://github.com/dset0x/rxvt-unicode/tree/matcher-delims
>
> --
> Best Regards,
> Dimitrios Semitsoglou-Tsiapos
>
> On Sat 25-Mar-17 04:27, Alex Efros wrote:
> > Hi!
> >
> > This patch was rewritten from scratch for rxvt-unicode-9.21.
> > This time it's really trivial, so, Marc, please reconsider merging it.
> >
> >
> > Also I've found several minor issues with original matcher plugin:
> >
> > > line 180:
> > my $i = 0;
> > Var shadowing, should be:
> > $i = 0;
> >
> > > sub most_recent {}
> > The problem is it doesn't actually run "recent". It runs "first match
> > returned by find_matches found in latest line with some matches" - which
> > in practice for end-user means "usually recent but sometimes random".
> > This function probably should call find_matches instead of command_for and
> > do sort { $b->[0] <=> $a->[0] or $b->[1] <=> $a->[1] } to find "recent".
> >
> > > line 304:
> > my $off = $line->offset_of ($row, $col) if defined $col;
> > Conditional my, which result in accessing global $off instead of local
> > later.
> >
> > > line 151:
> > while ($row >= 0 && @{ $self->{matches} } < 10) {
> > I'm not sure, but probably it should be
> > while ($row >= $self->top_row && @{ $self->{matches} } < 10) {
> >
> > --
> > WBR, Alex.
>
> > --- a/matcher 2017-03-24 17:56:41.529686962 +0200
> > +++ b/matcher 2017-03-25 04:08:06.579725267 +0200
> > @@ -3,6 +3,7 @@
> > # Author: Tim Pope <[email protected]>
> > # Bob Farrell <[email protected]>
> > # Emanuele Giaquinta
> > +# Alex Efros <[email protected]>
> >
> > #:META:RESOURCE:%.launcher:string:default launcher command
> > #:META:RESOURCE:%.button:string:the mouse button used to activate a match
> > @@ -150,7 +151,7 @@
> > $self->{matches} = [];
> > my $row = $self->nrow - 1;
> > while ($row >= 0 && @{ $self->{matches} } < 10) {
> > - my $line = $self->line ($row);
> > + my $line = $self->glued_line ($row);
> > my @matches = $self->find_matches ($row);
> >
> > for (sort { $b->[0] <=> $a->[0] or $b->[1] <=> $a->[1] } @matches) {
> > @@ -193,7 +194,7 @@
> > my $row = $self->nrow - 1;
> > my @exec;
> > while ($row >= $self->top_row) {
> > - my $line = $self->line ($row);
> > + my $line = $self->glued_line ($row);
> > @exec = $self->command_for($row);
> > last if(@exec);
> >
> > @@ -267,7 +268,7 @@
> > my ($self, $row) = @_;
> >
> > # fetch the line that has changed
> > - my $line = $self->line ($row);
> > + my $line = $self->glued_line ($row);
> > my $text = $line->t;
> > my $rend;
> >
> > @@ -299,7 +300,7 @@
> >
> > sub find_matches {
> > my ($self, $row, $col) = @_;
> > - my $line = $self->line ($row);
> > + my $line = $self->glued_line ($row);
> > my $text = $line->t;
> > my $off = $line->offset_of ($row, $col) if defined $col;
> >
> > @@ -413,7 +414,7 @@
> > my ($self, $dir, $row) = @_;
> >
> > while ($self->nrow > $row && $row >= $self->top_row) {
> > - my $line = $self->line ($row)
> > + my $line = $self->glued_line ($row)
> > or last;
> >
> > my @matches = $self->find_matches ($row);
> > @@ -471,7 +472,7 @@
> > $self->{id}--;
> > $self->want_refresh;
> > } else {
> > - my $line = $self->line ($self->{cur_row});
> > + my $line = $self->glued_line ($self->{cur_row});
> > $self->select_search (-1, $line->beg - 1)
> > if $line->beg > $self->top_row;
> > }
> > @@ -480,7 +481,7 @@
> > $self->{id}++;
> > $self->want_refresh;
> > } else {
> > - my $line = $self->line ($self->{cur_row});
> > + my $line = $self->glued_line ($self->{cur_row});
> > $self->select_search (+1, $line->end + 1)
> > if $line->end < $self->nrow;
> > }
> > @@ -489,4 +490,51 @@
> > 1
> > }
> >
> > +=item $line = $term->glued_line ($row_number)
> > +
> > +Create and return a new C<urxvt::line> object that stores information
> > +about the logical line that row C<$row_number> is part of. Unlike
> > +C<< $term->line >> this tries to handle logical lines which was broken to
> > +physical screen lines by ncurses/slang applications.
> > +
> > +=back
> > +
> > +=cut
> > +
> > +sub urxvt::term::glued_line {
> > + my ($self, $row) = @_;
> > +
> > + my $line = $self->line ($row);
> > + my $beg = $line->beg;
> > + my $end = $line->end;
> > + my $ncol= $self->ncol;
> > +
> > + # skip empty and multi-row (indication of non-ncurses output) lines
> > + return $line if $beg != $end || !$line->l;
> > +
> > + # join previous lines up to nearest line with space at EOL
> > + while ($beg > $self->top_row) {
> > + my $prevline = $self->line ($beg-1);
> > + return $line if $prevline->beg != $prevline->end;
> > + last if $prevline->l < $ncol || $prevline->t =~ /\s\z/;
> > + $beg--;
> > + }
> > + # join next lines up to nearest line with space at EOL
> > + if ($line->l == $ncol && $line->t =~ /\S\z/) {
> > + while ($self->nrow > $end+1) {
> > + my $nextline = $self->line (++$end);
> > + return $line if $nextline->beg != $nextline->end;
> > + last if $nextline->l < $ncol || $nextline->t =~ /\s\z/;
> > + }
> > + }
> > +
> > + bless {
> > + term => $self,
> > + beg => $beg,
> > + end => $end,
> > + ncol => $ncol,
> > + len => ($end - $beg) * $ncol + $self->ROW_l ($end),
> > + }, urxvt::line::
> > +}
> > +
> > # vim:set sw=3 sts=3 et:
>
> > _______________________________________________
> > rxvt-unicode mailing list
> > [email protected]
> > http://lists.schmorp.de/mailman/listinfo/rxvt-unicode
> diff --git a/src/perl/matcher b/src/perl/matcher
> index d991d68..d74ddc9 100644
> --- a/src/perl/matcher
> +++ b/src/perl/matcher
> @@ -3,12 +3,17 @@
> # Author: Tim Pope <[email protected]>
> # Bob Farrell <[email protected]>
> # Emanuele Giaquinta
> +# Dimitrios Semitsoglou-Tsiapos <[email protected]>
>
> #:META:RESOURCE:%.launcher:string:default launcher command
> #:META:RESOURCE:%.button:string:the mouse button used to activate a match
> #:META:RESOURCE:%.pattern.:string:extra pattern to match
> #:META:RESOURCE:%.launcher.:string:custom launcher for pattern
> #:META:RESOURCE:%.rend.:string:custom rendition for pattern
> +#:META:RESOURCE:%.multiline:boolean:toggle matcher for curses-like
> applications
> +#:META:RESOURCE:%.multiline.builtin:boolean:toggle use of builtin delimiters
> +#:META:RESOURCE:%.multiline.delim..left:string:left delimiting regex
> +#:META:RESOURCE:%.multiline.delim..right:string:right delimiting regex
>
> =head1 NAME
>
> @@ -30,6 +35,17 @@ C<matcher.pattern.0> resource, and additional patterns can
> be specified
> with numbered patterns, in a manner similar to the "selection" extension.
> The launcher can also be overridden on a per-pattern basis.
>
> +Additionally, matching within viewports drawn by curses-like applications can
> +be enabled by setting C<matcher.multiline> to C<true>. By default, tmux,
> mutt
> +and weechat windows are detected, but you may append to the regular
> expressions
> +that identify the viewports' boundaries via the
> +C<matcher.multiline.delim.n.left> and C<matcher.multiline.delim.n.right>
> +resources, where n is a positive integer. To disable the built-in delimiters
> +(see @default_delims), you may set C<matcher.multiline.builtin> to C<false>.
> +Important: Because there is no way to tell at which point a match ends if the
> +beginning of following line contains text, the user must click on the line
> +containing the last chunk of the desired match.
> +
> It is possible to activate the most recently seen match or a list of matches
> from the keyboard. Simply bind a keysym to "matcher:last" or
> "matcher:list" as seen in the example below.
> @@ -88,6 +104,15 @@ Example: use a custom configuration.
> URxvt.matcher.pattern.2: \\B(/\\S+?):(\\d+)(?=:|$)
> URxvt.matcher.launcher.2: gvim +$2 $1
>
> + ! enable multiline matching and add custom delimiter regexes
> + ! tip: use [\\ ] to avoid ending lines with " " if your editor strips
> them
> + URxvt.matcher.multiline: true
> + URxvt.matcher.multiline.builtin: true
> + URxvt.matcher.multiline.delim.0.left: <
> + URxvt.matcher.multiline.delim.0.right: >
> + URxvt.matcher.multiline.delim.1.left: \(
> + URxvt.matcher.multiline.delim.1.right: \)
> +
> =cut
>
> my $url =
> @@ -100,6 +125,115 @@ my $url =
> )+
> }x;
>
> +my @default_delims = (
> + # tmux / mutt
> + {left => '│', right => '│'},
> + {left => '^', right => '│'},
> + {left => '│', right => '$'},
> + # weechat
> + {left => '\ \|\ ', right => '\ │'},
> + {left => '\ \|\ ', right => '$'},
> +);
> +
> +# Append spaces to allow correct calculations in case of \n before $ncol
> +sub padded_line_t {
> + my ($self, $row) = @_;
> + my $line = $self->line($row);
> + my $line_t = $line->t;
> + return $line_t . (" " x ($self->{term}->ncol - length($line_t)));
> +}
> +
> +# Prepend the previous chunk of a match and get coords for the entire match
> +sub populate_prev {
> + my ($self, $frow, $box, $boxd, $pattern, $delims, $match, $row) = @_;
> +
> + my $line_t = padded_line_t($self, $row);
> + my $line_td = substr($line_t, $boxd->[0], $boxd->[1] - $boxd->[0]);
> + my @results;
> +
> + my $partial_pattern = # Given $line_td is:
> + qr{ # ^│foo http://s '(http:/│$
> + ^$delims->{left} # ^
> + (?<pre>.*?) # |<--------->|
> + (?<match>\S+) # |<---->|
> + $delims->{right}$ # ^
> + }x;
> +
> + if ($line_td =~ /$partial_pattern/g) {
> + # Keep $+{'pre'} so that the beginning offset don't need adjustment
> later
> + $match = $+{'pre'} . $+{'match'} . $match;
> + my $lp = length($+{'pre'});
> +
> + if (! $+{'pre'}) {
> + push @results, populate_prev(@_[0 .. $#_ - 2], $match, $row - 1);
> + }
> +
> + if ($match =~ /.{$lp}.*?($pattern)/x) {
> + use integer;
> +
> + my $box_width = ($box->[1] - $box->[0]);
> + my $off = $-[1];
> + return @results if $off >= $box_width; # $1 starts after $row
> +
> + my $last_c = length($1) + $off;
> + my $lines = ($last_c - 1) / $box_width;
> + return @results if $lines + $row != $frow; # $1 ends before $frow
> +
> + my @coords = (
> + [$box->[0], $box->[0] + (($last_c - 1) % $box_width)], # last
> line
> + ([$box->[0], $box->[1] - 1]) x ($lines - 1), # mid
> lines
> + [$box->[0] + $off, $box->[1] - 1], # first
> line
> + );
> + push @results, [$1, \@coords];
> + }
> + }
> + return @results;
> +}
> +
> +# The reason why we don't use a single regex to find these delims (while
> +# searching in `multiline_matches` for example) is because we need to grab
> all
> +# possible combinations.
> +sub delim_scopes {
> + my ($line_t, $pattern_delims) = @_;
> + # Given both delims are
> + my @areas; # "│" and $line_t is:
> + for my $delim (@{$pattern_delims}) { #
> + # │/schmorp.de/)'
> │examp│
> + while ($line_t =~ /$delim->{left}/g) { # ^^
> + my ($left_b, $left_e) = ($-[0], $+[0]); #
> + my $line_t_cont = substr($line_t, $left_e); #
> |<---$line_t_cont-----
> + #
> + while ($line_t_cont =~ /$delim->{right}/g) { # ^^
> ^^
> + my @boxd = ($left_b, $left_e + $+[0]); #
> |<-------@boxd->|---->|
> + my @box = ($left_e, $left_e + $-[0]); #
> |<------@box-->|--->|
> + push @areas, [\@boxd, \@box, $delim];
> + }
> +
> + }
> +
> + }
> + return @areas;
> +}
> +
> +# Fetch the match and coords of all multi-line matches ending on given row
> +# By not filtering $row < 1 we can do matches that start out of screen
> +sub multiline_matches {
> + my ($self, $row, $pattern) = @_;
> +
> + my $line_t = $self->padded_line_t($row);
> + my @results;
> +
> + for my $ds (delim_scopes($line_t, $self->{pattern_delims})) {
> + my ($boxd, $box, $delim) = @{$ds};
> + if (substr($line_t, $box->[0]) =~ /^\S+/) {
> + push @results, map {match => $_->[0], coords => $_->[1]},
> + $self->populate_prev($row, $box, $boxd, $pattern, $delim, $&,
> $row-1);
> + }
> + }
> +
> + return @results;
> +}
> +
> sub matchlist_key_press {
> my ($self, $event, $keysym, $octets) = @_;
>
> @@ -109,7 +243,7 @@ sub matchlist_key_press {
> my $i = ($keysym == 96 ? 0 : $keysym - 48);
> if ($i >= 0 && $i < @{ $self->{matches} }) {
> my @exec = @{ $self->{matches}[$i] };
> - $self->exec_async (@exec[5 .. $#exec]);
> + $self->exec_async (@exec[2 .. $#exec]);
> }
>
> 1
> @@ -170,7 +304,7 @@ sub matchlist {
>
> my $i = 0;
> for my $match (@{ $self->{matches} }) {
> - my $text = $match->[4];
> + my $text = $match->[1];
> my $w = $self->strwidth ("$i-$text");
>
> $width = $w if $w > $width;
> @@ -182,7 +316,7 @@ sub matchlist {
> $self->{overlay} = $self->overlay (0, 0, $width, scalar (@{
> $self->{matches} }), urxvt::OVERLAY_RSTYLE, 2);
> my $i = 0;
> for my $match (@{ $self->{matches} }) {
> - my $text = $match->[4];
> + my $text = $match->[1];
>
> $self->{overlay}->set (0, $i, "$i-$text");
> $i++;
> @@ -212,6 +346,10 @@ sub my_resource {
> $_[0]->x_resource ("%.$_[1]")
> }
>
> +sub my_resource_boolean {
> + $_[0]->x_resource_boolean ("%.$_[1]")
> +}
> +
> # turn a rendition spec in the resource into a sub that implements it on $_
> sub parse_rend {
> my ($self, $str) = @_;
> @@ -263,6 +401,26 @@ sub on_start {
> }
> $self->{matchers} = \@matchers;
>
> + my $multiline = $self->my_resource_boolean ("multiline");
> + my $builtin = $self->my_resource_boolean ("multiline.builtin");
> + if ($multiline) {
> + if ($builtin eq '' || $builtin) {
> + $self->{pattern_delims} = \@default_delims;
> + }
> + my @user_delims;
> + for (my $idx = 0; defined (my $delim_left = $self->my_resource
> ("multiline.delim.$idx.left")); $idx++) {
> + my $delim_right = $self->my_resource ("multiline.delim.$idx.right");
> + if (!defined($delim_right)) {
> + warn("multiline.delim.$idx.left has no matching delim.$idx.right
> resource. Skipping\n");
> + continue;
> + }
> + $delim_left = $self->locale_decode ($delim_left);
> + $delim_right = $self->locale_decode ($delim_right);
> + unshift @user_delims, { left => $delim_left, right => $delim_right
> };
> + }
> + push @{$self->{pattern_delims}}, @user_delims;
> + }
> +
> ()
> }
>
> @@ -277,7 +435,6 @@ sub on_line_update {
> # find all urls (if any)
> for my $matcher (@{$self->{matchers}}) {
> while ($text =~ /$matcher->[0]/g) {
> - #print "$&\n";
> $rend ||= $line->r;
>
> # mark all characters as underlined. we _must_ not toggle underline,
> @@ -289,6 +446,24 @@ sub on_line_update {
>
> $line->r ($rend) if $rend;
>
> + for my $matcher (@{$self->{matchers}}) {
> + for my $result ($self->multiline_matches($row, $matcher->[0])) {
> + my @coords = @{$result->{coords}};
> +
> + for my $i (0 .. $#coords) {
> + my $linex = $self->line($row - $i);
> + my $rendx = $linex->r;
> +
> + $rendx ||= $linex->r;
> + &{$matcher->[2]}
> + for (@{$rendx}[$coords[$i][0] .. $coords[$i][1]]);
> +
> + $linex->r($rendx);
> + }
> +
> + }
> + }
> +
> ()
> }
>
> @@ -326,11 +501,29 @@ sub find_matches {
> /egx; $_ } split /\s+/, $launcher;
> }
>
> - push @matches, [ $line->coord_of ($begin[0]), $line->coord_of
> ($end[0]), $match, @exec ];
> + my @spans = [($line->coord_of ($begin[0]), $line->coord_of
> ($end[0]))];
> + push @matches, [ \@spans, $match, @exec ];
> }
> }
> }
>
> + for my $matcher (@{$self->{matchers}}) {
> + my $launcher = $matcher->[1] || $self->{launcher};
> + for my $result ($self->multiline_matches($row, $matcher->[0])) {
> + my @coords = @{$result->{coords}};
> + my $match = $result->{match};
> + my @exec = $launcher !~ /\$/ ? ($launcher, $match) : undef;
> +
> + next if (defined($col) &&
> + !(@coords[0]->[0] <= $col && @coords[0]->[1] >= $col));
> +
> + my @spans = map [ $row - $_, $coords[$_]->[0],
> + $row - $_, $coords[$_]->[1] + 1 ], 0 .. $#coords;
> +
> + push @matches, [ \@spans, $match, @exec ];
> + }
> + }
> +
> @matches;
> }
>
> @@ -340,7 +533,7 @@ sub command_for {
> my @matches = $self->find_matches ($row, $col);
> if (@matches) {
> my @match = @{ $matches[0] };
> - return @match[5 .. $#match];
> + return @match[2 .. $#match];
> }
>
> ()
> @@ -443,8 +636,14 @@ sub select_refresh {
>
> return unless $self->{matches};
>
> - my $cur = $self->{matches}[$self->{id}];
> - $self->scr_xor_span (@$cur[0 .. 3], urxvt::RS_RVid);
> + my $cur = $self->{matches}[$self->{id}][0];
> +
> + for my $span (@$cur) {
> + my ($first_row, $first_col, $end_row, $end_col) = @$span;
> + for my $row ($first_row .. $end_row) {
> + $self->scr_xor_span ($first_row, $first_col, $end_row, $end_col,
> urxvt::RS_RVid);
> + }
> + }
>
> ()
> }
> @@ -455,12 +654,12 @@ sub select_key_press {
> if ($keysym == 0xff0d || $keysym == 0xff8d) { # enter
> if ($self->{matches}) {
> my @match = @{ $self->{matches}[$self->{id}] };
> - $self->exec_async (@match[5 .. $#match]);
> + $self->exec_async (@match[2 .. $#match]);
> }
> $self->select_leave;
> } elsif ($keysym == 0x79) { # y
> if ($self->{matches}) {
> - $self->selection ($self->{matches}[$self->{id}][4], 1);
> + $self->selection ($self->{matches}[$self->{id}][1], 1);
> $self->selection_grab (urxvt::CurrentTime, 1);
> }
> $self->select_leave;
> # tmux vertical panes
> # 1) cross-pane matches should be done (ie http://goog1), because there's no
> guarantee that '│' really means pane-change)
> # 2) resize your terminal for the last pane to match
>
> 0 user1@host12 $ 0 [0/415]│cd │0
> user7@host56 $ echo http://goog│1 www.google.com
> http://googlgeeeeeeeeeeeeeee│1 user9@host78 $ http://googoef
> 0 user2@host34 $ ~ │1 user3@host90 $ echo
> http://google.com│le.com/CDE/CDEFGHIJKLM │eeeeeeeeeeeeeeeeeeeeeee
> www.google.com │kjeflwjflwjflwkjeflwkjeflwjflwj
> │/ABC/abcdefghijklmnopqrstuvwxyzabcdefgh│
> │
> │flwkjflwejflwkjflwkj
> │ijk │
> │ │
> │1 user4@host12 $ echo http://google.com│0
> user8@host34 $ │ http://goog│ │
>
> │/CBA/ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGH│le.com/cde/cdefghijklm │ │
> │
> │IJK │
> │ │
> │1 user5@host56 $ echo 'http://google.co│
> │ │
> │m/bcd/bcdefghijklmnopqrstuvwxyzabcdefgh│
> │ │
> │ijkl' │
> │ │
> │0 user6@host78 $ echo ''''''''''''''│
> │ │
> │'''(http://google.com/BCD/BCDEFGHIJKLMN│
> │ │
> │OPQRSTUVWXYZABCDEFGHIJKL)''''''''''''''│
> │ │
> │''' │
> │ │
> │ │
> │ │
>
> # two urls beginning on the same line
>
> | AbcdEfgh, ijk https://lmnopq01rstu.com/ or
> (https://addons.mozilla.org │
> | /en-US/firefox/addon/add-on-compatibility-reporter/)
> │
>
>
> # "not" should be highlighted, but the user may exclude it by clicking on the
> previous line
>
> user1234567 | https://www.mozilla.org/en-U │
> | S/firefox/organizations/faq/ │
> user | not part of the url │
>
>
> # extra "│" before the end of the pane should not confuse the matcher
>
> user1234567 | https://www.mozilla.org/en-US/f │
> | irefox/organizations/faq/ │ │
>
> user1234567 | https://www.mozilla.org/en-S/f │ │
> | irefox/organizations/faq/ │ │
>
>
> # must be at least 6 matches
>
> │echo https://aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│
> │bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│
> │https://ccccccccccccccccccccccccccccccccccccccccccccccccc│
> │dddddddddddddddddddddddddddddddddddddddddddddddddddd │
>
>
> # Add extra matcher with delims < and > for this to work
>
> user1234567 <https://www.mozilla.org/en-S/f>
> <irefox/organizations/faq/ >
>
>
> # Very squeezed layout. Showoff.
>
> | Upload: │
> | abc-defghij-klmn │
> | op QRS https://t │
> | uvwxyza.org/abcd │
> | efg/HIJ/Klm-Nopq │
> | RST-1234 │
> | uvwx-5YZ78AB.c │
> | defghi.ca) jkl │
> | mnopqr #stuvwx │
> | http://www.yza │
> | bc.net/defghi_ │
> | jklmno.php?pqr │
> | s=tuvwxy&zabcd │
> | e_fg=9012345 │
> | <hijklmnop> ht │
> | tp://www.qrstu │
> | .net/vuwxyz_ab │
> | cdef.php?ghij= │
> | klmnop&qrstuv_ │
> | wx=67890123 │
> | <-- yzab │
> _______________________________________________
> rxvt-unicode mailing list
> [email protected]
> http://lists.schmorp.de/mailman/listinfo/rxvt-unicode
_______________________________________________
rxvt-unicode mailing list
[email protected]
http://lists.schmorp.de/mailman/listinfo/rxvt-unicode