--- rxvt-unicode/src/urxvt.pm 2014/10/10 14:32:32 1.240 +++ rxvt-unicode/src/urxvt.pm 2021/07/14 12:39:57 1.263 @@ -45,8 +45,14 @@ URxvt.perl-ext-common: default,selection-autotransform -Extensions that add command line parameters or resources on their own are -loaded automatically when used. +Extensions may add additional resources and C, i.e., methods +which can be bound to a key and invoked by the user. An extension can +define the resources it support using so called META comments, +described below. Similarly to builtin resources, extension resources +can also be specified on the command line as long options (with C<.> +replaced by C<->), in which case the corresponding extension is loaded +automatically. For this to work the extension B define META +comments for its resources. =head1 API DOCUMENTATION @@ -108,6 +114,28 @@ Additional methods only supported for extension objects are described in the C section below. +=head2 META comments + +Rxvt-unicode recognizes special meta comments in extensions that define +different types of metadata. These comments are scanned whenever a +terminal is created and are typically used to autoload extensions when +their resources or command line parameters are used. + +Currently, it recognises only one such comment: + +=over 4 + +=item #:META:RESOURCE:name:type:desc + +The RESOURCE comment defines a resource used by the extension, where +C is the resource name, C is the resource type, C +or C, and C is the resource description. + +The extension will be autoloaded when this resource is specified or used +as a command line parameter. + +=back + =head2 Hooks The following subroutines can be declared in extension files, and will be @@ -283,6 +311,14 @@ Called just after the screen gets redrawn. See C. +=item on_action $term, $string + +Called whenever an action is invoked for the corresponding extension +(e.g. via a C builtin action bound to a key, see +description of the B resource in the urxvt(1) manpage). The +event is simply the action string. Note that an action event is always +associated to a single extension. + =item on_user_command $term, $string *DEPRECATED* Called whenever a user-configured event is being activated (e.g. via @@ -483,6 +519,18 @@ Various constants for use in X calls and event processing. +=item urxvt::PrivMode_132, PrivMode_132OK, PrivMode_rVideo, PrivMode_relOrigin, +PrivMode_Screen, PrivMode_Autowrap, PrivMode_aplCUR, PrivMode_aplKP, +PrivMode_HaveBackSpace, PrivMode_BackSpace, PrivMode_ShiftKeys, +PrivMode_VisibleCursor, PrivMode_MouseX10, PrivMode_MouseX11, +PrivMode_scrollBar, PrivMode_TtyOutputInh, PrivMode_Keypress, +PrivMode_smoothScroll, PrivMode_vt52, PrivMode_LFNL, PrivMode_MouseBtnEvent, +PrivMode_MouseAnyEvent, PrivMode_BracketPaste, PrivMode_ExtMouseUTF8, +PrivMode_ExtMouseUrxvt, PrivMode_BlinkingCursor, PrivMode_mouse_report, +PrivMode_Default + +Constants for checking DEC private modes. + =back =head2 RENDITION @@ -557,22 +605,28 @@ sub parse_resource { my ($term, $name, $isarg, $longopt, $flag, $value) = @_; - $name =~ y/-/./ if $isarg; - $term->scan_extensions; + # iterating over all resources has quadratic time overhead + # overall, maybe this could be optimised? my $r = $term->{meta}{resource}; keys %$r; # reset iterator - while (my ($pattern, $v) = each %$r) { - if ( - $pattern =~ /\.$/ - ? $pattern eq substr $name, 0, length $pattern - : $pattern eq $name - ) { - $name = "$urxvt::RESCLASS.$name"; + while (my ($k, $v) = each %$r) { + my $pattern = $k; + $pattern =~ y/./-/ if $isarg; + my $prefix = $name; + my $suffix; + if ($pattern =~ /\-$/) { + $prefix = substr $name, 0, length $pattern; + $suffix = substr $name, length $pattern; + } + if ($pattern eq $prefix) { + $name = "$urxvt::RESCLASS.$k$suffix"; push @{ $term->{perl_ext_3} }, $v->[0]; + return 1 unless $isarg; + if ($v->[1] eq "boolean") { $term->put_option_db ($name, $flag ? "true" : "false"); return 1; @@ -677,15 +731,13 @@ } for ( - grep $_, map { split /,/, $TERM->resource ("perl_ext_$_") } 1, 2 + @{ 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 readline), - @{ delete $TERM->{perl_ext_3} }, - map $_->[0], values %{ $TERM->{meta}{binding} }; + for qw(selection option-popup selection-popup readline searchable-scrollback confirm-paste); for ($TERM->_keysym_resources) { next if /^(?:string|command|builtin|builtin-string|perl)/; @@ -707,13 +759,6 @@ } } - # now register default key bindings - for my $ext (sort keys %ext_arg) { - while (my ($k, $v) = each %{ $TERM->{meta}{ext}{$ext}{binding} }) { - $TERM->bind_action ($k, "$v->[0]:$v->[1]"); - } - } - for my $ext (sort keys %ext_arg) { my @files = grep -f $_, map "$_/$ext", @dirs; @@ -943,16 +988,25 @@ bless \%disable, "urxvt::extension::on_disable" } +=item $self->bind_action ($hotkey, $action) + =item $self->x_resource ($pattern) =item $self->x_resource_boolean ($pattern) -These methods support an additional C<%> prefix when called on an -extension object - see the description of these methods in the -C class for details. +These methods support an additional C<%> prefix for C<$action> or +C<$pattern> when called on an extension object, compared to the +C methods of the same name - see the description of these +methods in the C class for details. =cut +sub bind_action { + my ($self, $hotkey, $action) = @_; + $action =~ s/^%:/$_[0]{_name}:/; + $self->{term}->bind_action ($hotkey, $action) +} + sub x_resource { my ($self, $name) = @_; $name =~ s/^%(\.|$)/$_[0]{_name}$1/; @@ -1102,20 +1156,30 @@ return if exists $self->{meta}; - my @libdirs = perl_libdirs $self; - -# return if $self->{meta_libdirs} eq join "\x00", @libdirs;#d# + my @urxvtdirs = perl_libdirs $self; +# my @cpandirs = grep -d, map "$_/URxvt/Ext", @INC; -# $self->{meta_libdirs} = join "\x00", @libdirs;#d# $self->{meta} = \my %meta; # first gather extensions - for my $dir (reverse @libdirs) { + + my $gather = sub { + my ($dir, $core) = @_; + opendir my $fh, $dir - or next; + or return; + for my $ext (readdir $fh) { $ext !~ /^\./ - and open my $fh, "<", "$dir/$ext" + or next; + + open my $fh, "<", "$dir/$ext" + or next; + + -f $fh + or next; + + $ext =~ s/\.uext$// or $core or next; my %ext = (dir => $dir); @@ -1129,9 +1193,6 @@ } else { $ext{resource}{$pattern} = [$ext, $type, $desc]; } - } elsif (/^#:META:BINDING:(.*)/) { - my ($keysym, $action) = split /:/, $1; - $ext{binding}{$keysym} = [$ext, $action]; } elsif (/^\s*(?:#|$)/) { # skip other comments and empty lines } else { @@ -1141,13 +1202,18 @@ $meta{ext}{$ext} = \%ext; } - } + }; + +# $gather->($_, 0) for @cpandirs; + $gather->($_, 1) for @urxvtdirs; + + # and now merge resources + + $meta{resource} = \my %resource; - # and now merge resources and bindings while (my ($k, $v) = each %{ $meta{ext} }) { #TODO: should check for extensions overriding each other - %{ $meta{resource} } = (%{ $meta{resource} }, %{ $v->{resource} }); - %{ $meta{binding} } = (%{ $meta{binding} }, %{ $v->{binding} }); + %resource = (%resource, %{ $v->{resource} }); } } @@ -1220,7 +1286,7 @@ pointerBlank reverseVideo scrollBar scrollBar_floating scrollBar_right scrollTtyKeypress scrollTtyOutput scrollWithBuffer secondaryScreen secondaryScroll skipBuiltinGlyphs skipScroll transparent tripleclickwords - urgentOnBell utmpInhibit visualBell + urgentOnBell utmpInhibit visualBell disablePasteBrackets =item $value = $term->resource ($name[, $newval]) @@ -1256,7 +1322,7 @@ scrollTtyKeypress scrollTtyOutput scrollWithBuffer scrollstyle secondaryScreen secondaryScroll shade skipBuiltinGlyphs skipScroll term_name title transient_for transparent tripleclickwords urgentOnBell - utmpInhibit visualBell + utmpInhibit visualBell rewrapMode disablePasteBrackets =cut @@ -1273,15 +1339,15 @@ 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. +Extensions that define extra resources 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 replaced 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. +can rename them and get a new set of 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 @@ -1303,11 +1369,31 @@ $res =~ /^\s*(?:true|yes|on|1)\s*$/i ? 1 : defined $res && 0 } -=item $success = $term->bind_action ($key, $octets) +=item $action = $term->lookup_keysym ($keysym, $state) + +Returns the action bound to key combination C<($keysym, $state)>, +if a binding for it exists, and C otherwise. + +=item $success = $term->bind_action ($key, $action) Adds a key binding exactly as specified via a C resource. See the C resource in the urxvt(1) manpage. +To add default bindings for actions, an extension should call C<< +->bind_action >> in its C hook for every such binding. Doing it +in the C hook allows users to override or remove the binding +again. + +Example: the C by default binds itself +on C, using C<< $self->bind_action >>, which calls C<< +$term->bind_action >>. + + sub init { + my ($self) = @_; + + $self->bind_action ("M-s" => "%:start"); + } + =item $rend = $term->rstyle ([$new_rstyle]) Return and optionally change the current rendition. Text that is output by @@ -1474,8 +1560,9 @@ Write the given text string to the screen, as if output by the application running inside the terminal. It may not contain command sequences (escape -codes), but is free to use line feeds, carriage returns and tabs. The -string is a normal text string, not in locale-dependent encoding. +codes - see C for that), but is free to use line feeds, +carriage returns and tabs. The string is a normal text string, not in +locale-dependent encoding. Normally its not a good idea to use this function, as programs might be confused by changes in cursor position or scrolling. Its useful inside a @@ -1493,9 +1580,10 @@ =item $term->tt_write ($octets) -Write the octets given in C<$octets> to the tty (i.e. as program input). To -pass characters instead of octets, you should convert your strings first -to the locale-specific encoding using C<< $term->locale_encode >>. +Write the octets given in C<$octets> to the tty (i.e. as user input +to the program, see C for the opposite direction). To pass +characters instead of octets, you should convert your strings first to the +locale-specific encoding using C<< $term->locale_encode >>. =item $term->tt_write_user_input ($octets) @@ -1552,31 +1640,32 @@ Deliver various fake events to to terminal. -=item $window_width = $term->width +=item $window_width = $term->width ([$new_value]) -=item $window_height = $term->height +=item $window_height = $term->height ([$new_value]) -=item $font_width = $term->fwidth +=item $font_width = $term->fwidth ([$new_value]) -=item $font_height = $term->fheight +=item $font_height = $term->fheight ([$new_value]) -=item $font_ascent = $term->fbase +=item $font_ascent = $term->fbase ([$new_value]) -=item $terminal_rows = $term->nrow +=item $terminal_rows = $term->nrow ([$new_value]) -=item $terminal_columns = $term->ncol +=item $terminal_columns = $term->ncol ([$new_value]) -=item $has_focus = $term->focus +=item $has_focus = $term->focus ([$new_value]) -=item $is_mapped = $term->mapped +=item $is_mapped = $term->mapped ([$new_value]) -=item $max_scrollback = $term->saveLines +=item $max_scrollback = $term->saveLines ([$new_value]) -=item $nrow_plus_saveLines = $term->total_rows +=item $nrow_plus_saveLines = $term->total_rows ([$new_value]) -=item $topmost_scrollback_row = $term->top_row +=item $topmost_scrollback_row = $term->top_row ([$new_value]) -Return various integers describing terminal characteristics. +Return various integers describing terminal characteristics. If an +argument is given, changes the value and returns the previous one. =item $x_display = $term->display_id @@ -1623,11 +1712,22 @@ Returns whether the cursor is currently hidden or not. +=item $priv_modes = $term->priv_modes + +Returns a bitset with the state of DEC private modes. + +Example: + + if ($term->priv_modes & urxvt::PrivMode_mouse_report) { + # mouse reporting is turned on + } + =item $view_start = $term->view_start ([$newvalue]) -Returns the row number of the topmost displayed line. Maximum value is -C<0>, which displays the normal terminal contents. Lower values scroll -this many lines into the scrollback buffer. +Returns the row number of the topmost displayed line and changes it, +if an argument is given. Values greater than or equal to C<0> display +the terminal contents. Lower values scroll this many lines into the +scrollback buffer. =item $term->want_refresh @@ -1637,6 +1737,10 @@ Used after changing terminal contents to display them. +=item $term->refresh_check + +Checks if a refresh has been requested and, if so, schedules one. + =item $text = $term->ROW_t ($row_number[, $new_text[, $start_col]]) Returns the text of the entire row with number C<$row_number>. Row C<< $term->top_row >>