--- rxvt-unicode/src/urxvt.pm 2011/01/07 21:55:28 1.191 +++ rxvt-unicode/src/urxvt.pm 2012/06/10 13:58:05 1.217 @@ -22,7 +22,7 @@ Every time a terminal object gets created, extension scripts specified via the C resource are loaded and associated with it. -Scripts are compiled in a 'use strict' and 'use utf8' environment, and +Scripts are compiled in a 'use strict "vars"' and 'use utf8' environment, and thus must be encoded as UTF-8. Each script will only ever be loaded once, even in @@RXVT_NAME@@d, where @@ -261,14 +261,16 @@ with numbered patterns, in a manner similar to the "selection" extension. The launcher can also be overridden on a per-pattern basis. -It is possible to activate the most recently seen match from the keyboard. -Simply bind a keysym to "perl:matcher" as seen in the example below. +It is possible to activate the most recently seen match or a list of matches +from the keyboard. Simply bind a keysym to "perl:matcher:last" or +"perl:matcher:list" as seen in the example below. Example configuration: URxvt.perl-ext: default,matcher URxvt.urlLauncher: sensible-browser - URxvt.keysym.C-Delete: perl:matcher + URxvt.keysym.C-Delete: perl:matcher:last + URxvt.keysym.M-Delete: perl:matcher:list URxvt.matcher.button: 1 URxvt.matcher.pattern.1: \\bwww\\.[\\w-]+\\.[\\w./?&@#-]*[\\w/-] URxvt.matcher.pattern.2: \\B(/\\S+?):(\\d+)(?=:|$) @@ -400,6 +402,14 @@ Displays a confirmation dialog when a paste containing at least a full line is detected. +=item bell-command + +Runs the command specified by the C resource when +a bell event occurs. For example, the following pops up a notification +bubble with the text "Beep, Beep" using notify-send: + + URxvt.bell-command: notify-send "Beep, Beep" + =back =head1 API DOCUMENTATION @@ -438,12 +448,18 @@ Either binary data or - more common - a text string encoded in a locale-specific way. +=item $keysym + +an integer that is a valid X11 keysym code. You can convert a string +into a keysym and viceversa by using C and +C. + =back =head2 Extension Objects Every perl extension is a perl class. A separate perl object is created -for each terminal, and each terminal has its own set of extenion objects, +for each terminal, and each terminal has its own set of extension objects, which are passed as the first parameter to hooks. So extensions can use their C<$self> object without having to think about clashes with other extensions or other terminals, with the exception of methods and members @@ -658,6 +674,13 @@ The event is simply the action string. This interface is assumed to change slightly in the future. +=item on_register_command $term, $keysym, $modifiermask, $string + +Called after parsing a keysym resource but before registering the +associated binding. If this hook returns TRUE the binding is not +registered. It can be used to modify a binding by calling +C. + =item on_resize_all_windows $term, $new_width, $new_height Called just after the new window size has been calculated, but before @@ -734,15 +757,15 @@ package urxvt; use utf8; -use strict; +use strict 'vars'; use Carp (); use Scalar::Util (); use List::Util (); our $VERSION = 1; our $TERM; -our @TERM_INIT; -our @TERM_EXT; +our @TERM_INIT; # should go, prevents async I/O etc. +our @TERM_EXT; # should go, prevents async I/O etc. our @HOOKNAME; our %HOOKTYPE = map +($HOOKNAME[$_] => $_), 0..$#HOOKNAME; our %OPTION; @@ -821,7 +844,7 @@ Returns all urxvt::term objects that exist in this process, regardless of whether they are started, being destroyed etc., so be careful. Only term objects that have perl extensions attached will be returned (because there -is no urxvt::term objet associated with others). +is no urxvt::term object associated with others). =item $time = urxvt::NOW @@ -922,6 +945,66 @@ no warnings 'utf8'; +sub parse_resource { + my ($term, $name, $isarg, $longopt, $flag, $value) = @_; + + $name =~ y/-/./ if $isarg; + + $term->scan_meta; + + my $r = $term->{meta}{resource}; + keys %$r; # reste iterator + while (my ($pattern, $v) = each %$r) { + if ( + $pattern =~ /\.$/ + ? $pattern eq substr $name, 0, length $pattern + : $pattern eq $name + ) { + $name = "$urxvt::RESCLASS.$name"; + + push @{ $term->{perl_ext_3} }, $v->[0]; + + if ($v->[1] eq "boolean") { + $term->put_option_db ($name, $flag ? "true" : "false"); + return 1; + } else { + $term->put_option_db ($name, $value); + return 1 + 2; + } + } + } + + 0 +} + +sub usage { + my ($term, $usage_type) = @_; + + $term->scan_meta; + + my $r = $term->{meta}{resource}; + + for my $pattern (sort keys %$r) { + my ($ext, $type, $desc) = @{ $r->{$pattern} }; + + $desc .= " (-pe $ext)"; + + if ($usage_type == 1) { + $pattern =~ y/./-/; + $pattern =~ s/-$/-.../g; + + if ($type eq "boolean") { + urxvt::log sprintf " -%-30s %s\n", "/+$pattern", $desc; + } else { + urxvt::log sprintf " -%-30s %s\n", "$pattern $type", $desc; + } + } else { + $pattern =~ s/\.$/.*/g; + urxvt::log sprintf " %-31s %s\n", "$pattern:", $type; + } + } +} + my $verbosity = $ENV{URXVT_PERL_VERBOSITY}; sub verbose { @@ -943,11 +1026,13 @@ verbose 3, "loading extension '$path' into package '$pkg'"; + (${"$pkg\::_NAME"} = $path) =~ s/^.*[\\\/]//; # hackish + open my $fh, "<:raw", $path or die "$path: $!"; my $source = - "package $pkg; use strict; use utf8; no warnings 'utf8';\n" + "package $pkg; use strict 'vars'; use utf8; no warnings 'utf8';\n" . "#line 1 \"$path\"\n{\n" . (do { local $/; <$fh> }) . "\n};\n1"; @@ -967,7 +1052,7 @@ my $htype = shift; if ($htype == 0) { # INIT - my @dirs = ((split /:/, $TERM->resource ("perl_lib")), "$LIBDIR/perl"); + my @dirs = $TERM->perl_libdirs; my %ext_arg; @@ -980,7 +1065,10 @@ $TERM->register_package ($_) for @pkg; } - for (grep $_, map { split /,/, $TERM->resource ("perl_ext_$_") } 1, 2) { + for ( + @{ delete $TERM->{perl_ext_3} }, + grep $_, map { split /,/, $TERM->resource ("perl_ext_$_") } 1, 2 + ) { if ($_ eq "default") { $ext_arg{$_} ||= [] for qw(selection option-popup selection-popup searchable-scrollback readline); } elsif (/^-(.*)$/) { @@ -1066,8 +1154,6 @@ ($mask, @color{qw(fg bg)}, \@failed) } -# urxvt::term::extension - package urxvt::term::extension; sub enable { @@ -1131,6 +1217,18 @@ bless \shift, urxvt::destroy_hook:: } +sub x_resource { + my ($self, $name) = @_; + $name =~ s/^%(\.|$)/$_[0]{_name}$1/; + $self->{term}->x_resource ($name) +} + +sub x_resource_boolean { + my ($self, $name) = @_; + $name =~ s/^%(\.|$)/$_[0]{_name}$1/; + $self->{term}->x_resource_boolean ($name) +} + package urxvt::anyevent; =head2 The C Class @@ -1138,9 +1236,10 @@ The sole purpose of this class is to deliver an interface to the C module - any module using it will work inside urxvt without further programming. The only exception is that you cannot wait on -condition variables, but non-blocking condvar use is ok. What this means -is that you cannot use blocking APIs, but the non-blocking variant should -work. +condition variables, but non-blocking condvar use is ok. + +In practical terms this means is that you cannot use blocking APIs, but +the non-blocking variant should work. =cut @@ -1209,6 +1308,7 @@ $_[0][1]->stop; } +# only needed for AnyEvent < 6 compatibility sub one_event { Carp::croak "AnyEvent->one_event blocking wait unsupported in urxvt, use a non-blocking API"; } @@ -1233,8 +1333,9 @@ @{"$pkg\::ISA"} = urxvt::term::extension::; my $proxy = bless { - _pkg => $pkg, - argv => $argv, + _pkg => $pkg, + _name => ${"$pkg\::_NAME"}, # hackish + argv => $argv, }, $pkg; Scalar::Util::weaken ($proxy->{term} = $self); @@ -1247,6 +1348,53 @@ } } +sub perl_libdirs { + map { split /:/ } + $_[0]->resource ("perl_lib"), + $ENV{URXVT_PERL_LIB}, + "$ENV{HOME}/.urxvt/ext", + "$LIBDIR/perl" +} + +sub scan_meta { + my ($self) = @_; + my @libdirs = perl_libdirs $self; + + return if $self->{meta_libdirs} eq join "\x00", @libdirs; + + my %meta; + + $self->{meta_libdirs} = join "\x00", @libdirs; + $self->{meta} = \%meta; + + for my $dir (reverse @libdirs) { + opendir my $fh, $dir + or next; + for my $ext (readdir $fh) { + $ext ne "." + and $ext ne ".." + and open my $fh, "<", "$dir/$ext" + or next; + + while (<$fh>) { + if (/^#:META:X_RESOURCE:(.*)/) { + my ($pattern, $type, $desc) = split /:/, $1; + $pattern =~ s/^%(\.|$)/$ext$1/g; # % in pattern == extension name + if ($pattern =~ /[^a-zA-Z0-9\-\.]/) { + warn "$dir/$ext: meta resource '$pattern' contains illegal characters (not alphanumeric nor . nor *)\n"; + } else { + $meta{resource}{$pattern} = [$ext, $type, $desc]; + } + } elsif (/^\s*(?:#|$)/) { + # skip other comments and empty lines + } else { + last; # stop parsing on first non-empty non-comment line + } + } + } + } +} + =item $term = new urxvt::term $envhashref, $rxvtname, [arg...] Creates a new terminal, very similar as if you had started it with system @@ -1310,12 +1458,13 @@ Here is a likely non-exhaustive list of option names, please see the source file F to see the actual list: - borderLess console cursorBlink cursorUnderline hold iconic insecure - intensityStyles jumpScroll loginShell mapAlert meta8 mouseWheelScrollPage - override-redirect pastableTabs pointerBlank reverseVideo scrollBar - scrollBar_floating scrollBar_right scrollTtyKeypress scrollTtyOutput - scrollWithBuffer secondaryScreen secondaryScroll skipBuiltinGlyphs - transparent tripleclickwords utmpInhibit visualBell + borderLess buffered console cursorBlink cursorUnderline hold iconic + insecure intensityStyles iso14755 iso14755_52 jumpScroll loginShell + mapAlert meta8 mouseWheelScrollPage override_redirect pastableTabs + pointerBlank reverseVideo scrollBar scrollBar_floating scrollBar_right + scrollTtyKeypress scrollTtyOutput scrollWithBuffer secondaryScreen + secondaryScroll skipBuiltinGlyphs skipScroll transparent tripleclickwords + urgentOnBell utmpInhibit visualBell =item $value = $term->resource ($name[, $newval]) @@ -1338,19 +1487,20 @@ are supported in every build, please see the source file F to see the actual list: - answerbackstring backgroundPixmap backspace_key boldFont boldItalicFont - borderLess chdir color cursorBlink cursorUnderline cutchars delete_key - display_name embed ext_bwidth fade font geometry hold iconName - imFont imLocale inputMethod insecure int_bwidth intensityStyles - italicFont jumpScroll lineSpace letterSpace loginShell mapAlert meta8 - modifier mouseWheelScrollPage name override_redirect pastableTabs path - perl_eval perl_ext_1 perl_ext_2 perl_lib pointerBlank pointerBlankDelay + answerbackstring backgroundPixmap backspace_key blendtype blurradius + boldFont boldItalicFont borderLess buffered chdir color cursorBlink + cursorUnderline cutchars delete_key depth display_name embed ext_bwidth + fade font geometry hold iconName iconfile imFont imLocale inputMethod + insecure int_bwidth intensityStyles iso14755 iso14755_52 italicFont + jumpScroll letterSpace lineSpace loginShell mapAlert meta8 modifier + mouseWheelScrollPage name override_redirect pastableTabs path perl_eval + perl_ext_1 perl_ext_2 perl_lib pointerBlank pointerBlankDelay preeditType print_pipe pty_fd reverseVideo saveLines scrollBar scrollBar_align scrollBar_floating scrollBar_right scrollBar_thickness scrollTtyKeypress scrollTtyOutput scrollWithBuffer scrollstyle - secondaryScreen secondaryScroll shade term_name title - transient_for transparent transparent_all tripleclickwords utmpInhibit - visualBell + secondaryScreen secondaryScroll shade skipBuiltinGlyphs skipScroll + term_name title transient_for transparent tripleclickwords urgentOnBell + utmpInhibit visualBell =cut @@ -1367,15 +1517,48 @@ same value as used by this instance of rxvt-unicode. Returns C if no resource with that pattern exists. +Extensions that define extra resource or command line arguments also need +to call this method to access their values. + +If the method is called on an extension object (basically, from an +extension), then the special prefix C<%.> will be replaced by the name of +the extension and a dot, and the lone string C<%> will be replcaed by the +extension name itself. This makes it possible to code extensions so you +can rename them and get a new set of commandline switches and resources +without having to change the actual code. + This method should only be called during the C hook, as there is only one resource database per display, and later invocations might return the wrong resources. -=item $success = $term->parse_keysym ($keysym_spec, $command_string) +=item $value = $term->x_resource_boolean ($pattern) + +Like C, above, but interprets the string value as a boolean +and returns C<1> for true values, C<0> for false values and C if +the resource or option isn't specified. + +You should always use this method to parse boolean resources. + +=cut + +sub x_resource_boolean { + my $res = &x_resource; + + $res =~ /^\s*(?:true|yes|on|1)\s*$/i ? 1 : defined $res && 0 +} + +=item $success = $term->parse_keysym ($key, $octets) -Adds a keymap translation exactly as specified via a resource. See the +Adds a key binding exactly as specified via a resource. See the C resource in the @@RXVT_NAME@@(1) manpage. +=item $term->register_command ($keysym, $modifiermask, $string) + +Adds a key binding. This is a lower level api compared to +C, as it expects a parsed key description, and can be +used only inside either the C hook, to add a binding, or the +C hook, to modify a parsed binding. + =item $rend = $term->rstyle ([$new_rstyle]) Return and optionally change the current rendition. Text that is output by @@ -1598,6 +1781,10 @@ $term->vt_emask_add (urxvt::PointerMotionMask); +=item $term->set_urgency ($set) + +Enable/disable the urgency hint on the toplevel window. + =item $term->focus_in =item $term->focus_out @@ -1923,6 +2110,10 @@ =item $term->XChangeInput ($window, $add_events[, $del_events]) +=item $keysym = $term->XStringToKeysym ($string) + +=item $string = $term->XKeysymToString ($keysym) + Various X or X-related functions. The C<$term> object only serves as the source of the display, otherwise those functions map more-or-less directly onto the X functions of the same name. @@ -2253,7 +2444,7 @@ =head1 AUTHOR - Marc Lehmann + Marc Lehmann http://software.schmorp.de/pkg/rxvt-unicode =cut