WISH: just for fun, do shade and tint with XRender.
WISH: support tex fonts
+ - perl: implement additional hook: line_update, add_lines.
+ - perl: urxvt::line now can set via ->t and ->r.
+
6.3 Wed Jan 4 22:37:10 CET 2006
- SECURITY FIX: on systems using openpty, permissions were
not correctly updated on the tty device and were left as
src/rxvtperl.xs
src/perl/example-refresh-hooks
+src/perl/example-filter-input
src/perl/digital-clock
src/perl/selection
src/perl/mark-urls
if (want_refresh)
{
+ if (SHOULD_INVOKE (HOOK_LINE_UPDATE))
+ {
+ int row = -view_start;
+
+ while (row > -nsaved && ROW (row - 1).is_longer ())
+ --row;
+
+ while (row < -view_start + nrow)
+ {
+ int start_row = row;
+ line_t *l;
+
+ do
+ {
+ l = &ROW (row);
+
+ if (!(l->f & LINE_FILTERED))
+ {
+ // line not filtered, mark it as filtered
+ l->f |= LINE_FILTERED;
+ while (l->is_longer ())
+ {
+ l = &ROW (++row);
+ l->f |= LINE_FILTERED;
+ }
+
+ // and filter it
+ HOOK_INVOKE ((this, HOOK_LINE_UPDATE, DT_INT, start_row, DT_END));
+
+ break;
+ }
+ }
+ while (l->is_longer ());
+
+ row++;
+ }
+
+ }
+
scr_refresh (refresh_type);
scrollbar_show (1);
#ifdef USE_XIM
focus = 1;
want_refresh = 1;
- PERL_INVOKE ((this, HOOK_FOCUS_OUT, DT_END));
+ HOOK_INVOKE ((this, HOOK_FOCUS_OUT, DT_END));
#if USE_XIM
if (Input_Context != NULL)
focus = 0;
want_refresh = 1;
- PERL_INVOKE ((this, HOOK_FOCUS_OUT, DT_END));
+ HOOK_INVOKE ((this, HOOK_FOCUS_OUT, DT_END));
#if ENABLE_FRILLS || ISO_14755
if (iso14755buf)
if (ev.button != MEvent.button)
MEvent.clicks = 0;
- if (!PERL_INVOKE ((this, HOOK_MOUSE_CLICK, DT_XEVENT, &ev, DT_END)))
+ if (!HOOK_INVOKE ((this, HOOK_MOUSE_CLICK, DT_XEVENT, &ev, DT_END)))
switch (ev.button)
{
case Button1:
// scr_add_lines only works for nlines <= nrow - 1.
if (nlines >= nrow - 1)
{
- if (!PERL_INVOKE ((this, HOOK_ADD_LINES, DT_USTRING_LEN, buf, str - buf, DT_END)))
+ if (!HOOK_INVOKE ((this, HOOK_ADD_LINES, DT_USTRING_LEN, buf, str - buf, DT_END)))
scr_add_lines (buf, nlines, str - buf);
nlines = 0;
ch = next_char ();
}
- if (!PERL_INVOKE ((this, HOOK_ADD_LINES, DT_USTRING_LEN, buf, str - buf, DT_END)))
+ if (!HOOK_INVOKE ((this, HOOK_ADD_LINES, DT_USTRING_LEN, buf, str - buf, DT_END)))
scr_add_lines (buf, nlines, str - buf);
/*
#if ENABLE_PERL
case URxvt_perl:
- if (PERL_INVOKE ((this, HOOK_OSC_SEQ, DT_STRING, str, DT_END)))
+ if (HOOK_INVOKE ((this, HOOK_OSC_SEQ, DT_STRING, str, DT_END)))
; // no responses yet
break;
#endif
def (VIEW_CHANGE)
def (SCROLL_BACK)
- def (TTY_ACTIVITY)
+ def (LINE_UPDATE)
def (ADD_LINES)
def (OSC_SEQ)
if (strncmp (str, "command:", 8) == 0)
rt->cmd_write (str + 8, strlen (str) - 8);
else if (strncmp (str, "perl:", 5) == 0)
- PERL_INVOKE((rt, HOOK_KEYBOARD_COMMAND, DT_STRING, str + 5, DT_END));
+ HOOK_INVOKE((rt, HOOK_KEYBOARD_COMMAND, DT_STRING, str + 5, DT_END));
else
rt->tt_write (str, strlen (str));
}
rxvt_term::~rxvt_term ()
{
- PERL_INVOKE ((this, HOOK_DESTROY, DT_END));
+ HOOK_INVOKE ((this, HOOK_DESTROY, DT_END));
termlist.erase (find (termlist.begin (), termlist.end(), this));
|| (rs[Rs_perl_eval] && *rs[Rs_perl_eval]))
{
rxvt_perl.init ();
- PERL_INVOKE ((this, HOOK_INIT, DT_END));
+ HOOK_INVOKE ((this, HOOK_INIT, DT_END));
}
#endif
check_ev.start ();
- PERL_INVOKE ((this, HOOK_START, DT_END));
+ HOOK_INVOKE ((this, HOOK_START, DT_END));
return true;
}
--- /dev/null
+#! perl
+
+# same url as used in "selection"
+my $url =
+ qr{(
+ (?:https?|ftp|news|mailto|file)://[ab-zA-Z0-9\-\@;\/?:&=%\$_.+!*\x27(),~]+
+ [ab-zA-Z0-9\-\@;\/?:&=%\$_+!*\x27(),~] # do not include a trailing dot, its wrong too often
+ )}x;
+
+sub on_add_lines {
+ my ($term, $str) = @_;
+
+ while ($str =~ $url) {
+ # found a url, first output preceding text
+ $term->scr_add_lines (substr $str, 0, $-[1], "");
+ # then toggle underline
+ $term->rstyle ($term->rstyle ^ urxvt::RS_Uline);
+ # now output the url
+ $term->scr_add_lines (substr $str, 0, $+[1] - $-[1], "");
+ # toggle undelrine again
+ $term->rstyle ($term->rstyle ^ urxvt::RS_Uline);
+ }
+
+ # output trailing text
+ $term->scr_add_lines ($str);
+
+ 1
+}
+
[ab-zA-Z0-9\-\@;\/?:&=%\$_+!*\x27(),~] # do not include a trailing dot, its wrong too often
)}x;
-sub on_add_lines {
- my ($term, $str) = @_;
-
- while ($str =~ $url) {
- # found a url, first output preceding text
- $term->scr_add_lines (substr $str, 0, $-[1], "");
- # then toggle underline
- $term->rstyle ($term->rstyle ^ urxvt::RS_Uline);
- # now output the url
- $term->scr_add_lines (substr $str, 0, $+[1] - $-[1], "");
- # toggle undelrine again
- $term->rstyle ($term->rstyle ^ urxvt::RS_Uline);
- }
+sub on_line_update {
+ my ($term, $row) = @_;
+
+ # fetch the line that has changed
+ my $line = $term->line ($row);
+ my $text = $line->t;
+
+ # find all urls (if any)
+ while ($text =~ /$url/g) {
+ my $rend = $line->r;
- # output trailing text
- $term->scr_add_lines ($str);
+ # mark all characters as underlined. we _must_ not toggle underline,
+ # as we might get called on an already-marked url.
+ $_ |= urxvt::RS_Uline
+ for @{$rend}[ $-[1] .. $+[1] - 1];
+
+ $line->r ($rend);
+ }
- 1
+ ()
}
#define RXVTPERL_H_
#if ENABLE_PERL
+# define SHOULD_INVOKE(htype) rxvt_perl.should_invoke [htype]
+# define HOOK_INVOKE(args) rxvt_perl.invoke args
#include "rxvt.h"
-#define PERL_INVOKE(args) rxvt_perl.invoke args
-
enum data_type {
DT_END,
DT_INT,
void init ();
bool invoke (rxvt_term *term, hook_type htype, ...);
+ void line_update (rxvt_term *term);
};
extern struct rxvt_perl_interp rxvt_perl;
#else
+# define SHOULD_INVOKE(htype) false
# define PERL_INVOKE(args) false
#endif
THIS->want_refresh = 1;
void
-rxvt_term::ROW_t (int row_number, SV *new_text = 0, int start_col = 0)
+rxvt_term::ROW_t (int row_number, SV *new_text = 0, int start_col = 0, int start_ofs = 0, int max_len = MAX_COLS)
PPCODE:
{
if (!IN_RANGE_EXC (row_number, -THIS->nsaved, THIS->nrow))
{
wchar_t *wstr = sv2wcs (new_text);
- int len = wcslen (wstr);
+ int len = min (wcslen (wstr) - start_ofs, max_len);
if (!IN_RANGE_INC (start_col, 0, THIS->ncol - len))
{
for (int col = start_col; col < start_col + len; col++)
{
- l.t [col] = wstr [col - start_col];
+ l.t [col] = wstr [start_ofs + col - start_col];
l.r [col] = SET_FONT (l.r [col], THIS->fontset [GET_STYLE (l.r [col])]->find_font (l.t [col]));
}
}
void
-rxvt_term::ROW_r (int row_number, SV *new_rend = 0, int start_col = 0)
+rxvt_term::ROW_r (int row_number, SV *new_rend = 0, int start_col = 0, int start_ofs = 0, int max_len = MAX_COLS)
PPCODE:
{
if (!IN_RANGE_EXC (row_number, -THIS->nsaved, THIS->nrow))
croak ("new_rend must be arrayref");
AV *av = (AV *)SvRV (new_rend);
- int len = av_len (av) + 1;
+ int len = min (av_len (av) + 1 - start_ofs, max_len);
if (!IN_RANGE_INC (start_col, 0, THIS->ncol - len))
croak ("new_rend array extends beyond horizontal margins");
for (int col = start_col; col < start_col + len; col++)
{
- rend_t r = SvIV (*av_fetch (av, col - start_col, 1)) & ~RS_fontMask;
+ rend_t r = SvIV (*av_fetch (av, start_ofs + col - start_col, 1)) & ~RS_fontMask;
l.r [col] = SET_FONT (r, THIS->fontset [GET_STYLE (r)]->find_font (l.t [col]));
}
tt_winch ();
- PERL_INVOKE ((this, HOOK_RESET, DT_END));
+ HOOK_INVOKE ((this, HOOK_RESET, DT_END));
}
/* ------------------------------------------------------------------------- */
{
nsaved = min (nsaved + count, saveLines);
- PERL_INVOKE ((this, HOOK_SCROLL_BACK, DT_INT, count, DT_INT, nsaved, DT_END));
+ HOOK_INVOKE ((this, HOOK_SCROLL_BACK, DT_INT, count, DT_INT, nsaved, DT_END));
term_start = (term_start + count) % total_rows;
{
if (view_start != oldviewstart)
{
- PERL_INVOKE ((this, HOOK_VIEW_CHANGE, DT_INT, view_start, DT_END));
+ HOOK_INVOKE ((this, HOOK_VIEW_CHANGE, DT_INT, view_start, DT_END));
want_refresh = 1;
num_scr -= (view_start - oldviewstart);
}
}
- PERL_INVOKE ((this, HOOK_REFRESH_BEGIN, DT_END));
+ HOOK_INVOKE ((this, HOOK_REFRESH_BEGIN, DT_END));
#if ENABLE_OVERLAY
scr_swap_overlay ();
#endif
#if ENABLE_OVERLAY
scr_swap_overlay ();
#endif
- PERL_INVOKE ((this, HOOK_REFRESH_END, DT_END));
+ HOOK_INVOKE ((this, HOOK_REFRESH_END, DT_END));
/*
* G: cleanup cursor and display outline cursor if necessary
if (selection.clicks == 4)
return; /* nothing selected, go away */
- if (PERL_INVOKE ((this, HOOK_SEL_MAKE, DT_LONG, (long)tm, DT_END)))
+ if (HOOK_INVOKE ((this, HOOK_SEL_MAKE, DT_LONG, (long)tm, DT_END)))
return;
i = (selection.end.row - selection.beg.row + 1) * (ncol + 1);
selection.len = ofs;
selection.text = (wchar_t *)rxvt_realloc (new_selection_text, (ofs + 1) * sizeof (wchar_t));
- if (PERL_INVOKE ((this, HOOK_SEL_GRAB, DT_LONG, (long)tm, DT_END)))
+ if (HOOK_INVOKE ((this, HOOK_SEL_GRAB, DT_LONG, (long)tm, DT_END)))
return;
selection_grab (tm);
if (ROWCOL_IS_AFTER (selection.end, selection.beg))
selection.end.col--;
- if (!PERL_INVOKE ((this, HOOK_SEL_EXTEND, DT_END)))
+ if (!HOOK_INVOKE ((this, HOOK_SEL_EXTEND, DT_END)))
{
selection_delimit_word (UP, &selection.beg, &selection.beg);
selection_delimit_word (DN, &selection.end, &selection.end);
term => $self,
beg => $beg,
end => $end,
+ ncol => $self->ncol,
len => ($end - $beg) * $self->ncol + $self->ROW_l ($end),
}, urxvt::line::
}
sub urxvt::line::t {
my ($self) = @_;
- substr +(join "", map $self->{term}->ROW_t ($_), $self->{beg} .. $self->{end}),
- 0, $self->{len}
+ if (@_ > 1)
+ {
+ $self->{term}->ROW_t ($_, $_[1], 0, ($_ - $self->{beg}) * $self->{ncol}, $self->{ncol})
+ for $self->{beg} .. $self->{end};
+ }
+
+ defined wantarray &&
+ substr +(join "", map $self->{term}->ROW_t ($_), $self->{beg} .. $self->{end}),
+ 0, $self->{len}
}
sub urxvt::line::r {
my ($self) = @_;
- my $rend = [
- map @{ $self->{term}->ROW_r ($_) }, $self->{beg} .. $self->{end}
- ];
- $#$rend = $self->{len} - 1;
- $rend
+ if (@_ > 1)
+ {
+ $self->{term}->ROW_r ($_, $_[1], 0, ($_ - $self->{beg}) * $self->{ncol}, $self->{ncol})
+ for $self->{beg} .. $self->{end};
+ }
+
+ if (defined wantarray) {
+ my $rend = [
+ map @{ $self->{term}->ROW_r ($_) }, $self->{beg} .. $self->{end}
+ ];
+ $#$rend = $self->{len} - 1;
+ return $rend;
+ }
+
+ ()
}
sub urxvt::line::beg { $_[0]{beg} }
sub urxvt::line::offset_of {
my ($self, $row, $col) = @_;
- ($row - $self->{beg}) * $self->{term}->ncol + $col
+ ($row - $self->{beg}) * $self->{ncol} + $col
}
sub urxvt::line::coord_of {
use integer;
(
- $offset / $self->{term}->ncol + $self->{beg},
- $offset % $self->{term}->ncol
+ $offset / $self->{ncol} + $self->{beg},
+ $offset % $self->{ncol}
)
}