diff --git a/.urxvt/perl/tabbedex b/.urxvt/perl/tabbedex index 6c97395..7df49ef 100644 --- a/.urxvt/perl/tabbedex +++ b/.urxvt/perl/tabbedex @@ -15,8 +15,9 @@ ## ## Tabbed plugin for rxvt-unicode ## Modified by Michal Nazarewicz (mina86/AT/mina86.com), StephenB -## (mail4stb/AT/gmail.com) and Steven Merrill -## +## (mail4stb/AT/gmail.com), Steven Merrill +## , Mark Pustjens +## and more... ## ## The following has been added: ## @@ -51,7 +52,7 @@ ## title is displayed). This make tab bar look nicer. ## ## Added by StephenB: -## +## ## 7. Tabs can be named with Shift+Up (Enter to confirm, Escape to ## cancel). ## @@ -68,7 +69,33 @@ ## to other extension packages if the mouse was not over the urxvt ## window. ## +## Added by Thomas Jost: +## +## 11. Add several user commands: tabbedex:rename_tab, +## tabbedex:move_tab_(left|right). +## e.g. (see 9.) URxvt.keysym.C-S-Left: perl:tabbex:move_tab_left +## +## 12. Ability to disable the default keybindings using the +## no-tabbedex-keys resource. +## +## Added by xanf (Illya Klymov): +## +## 13. Ability to display non-latin characters in tab title. +## +## Added by jpkotta: +## +## 14. Tabs inherit command line options. +## +## Added by Mark Pustjens +## +## 15. Resources are now read respecting the -name option. +## +## 16. Ability to prevent the last tab from closing. +## Use the following in your ~/.Xdefaults to enable: +## URXvt.tabbed.reopen-on-close: yes +## +use Encode qw(decode); sub update_autohide { my ($self, $reconfigure) = @_; @@ -141,7 +168,7 @@ sub refresh { my $term = $self->{term}; my @str = $term->XGetWindowProperty($term->parent, $self->{tab_title}); if (@str && $str[2]) { - my $str = '| ' . $str[2]; + my $str = '| ' . decode("utf8", $str[2]); my $len = length $str; $len = $ncol - $ofs if $ofs + $len > $ncol; substr $text, $ofs, $len, substr $str, 0, $len; @@ -178,6 +205,11 @@ sub new_tab { if defined $value; } + foreach my $opt (keys %urxvt::OPTION) { + my $value = $self->{option}{$opt}; + $term->option($urxvt::OPTION{$opt}, $value); + } + $term->resource (perl_ext_2 => $term->resource ("perl_ext_2") . ",-tabbedex"); }; @@ -244,6 +276,12 @@ sub copy_properties { } +sub my_resource { + my $self = shift; + $self->x_resource ("tabbed.$_[0]"); +} + + sub make_current { my ($self, $tab) = @_; @@ -319,17 +357,22 @@ sub on_init { $self->{resource} = [map $self->resource ("+$_"), 0 .. urxvt::NUM_RESOURCES - 1]; $self->resource (int_bwidth => 0); - $self->resource (name => "URxvt.tabbed"); $self->resource (pty_fd => -1); + $self->{option} = {}; + for my $key (keys %urxvt::OPTION) { + $self->{option}{$key} = $self->option($urxvt::OPTION{$key}); + } + + # this is for the tabs terminal; order is important $self->option ($urxvt::OPTION{scrollBar}, 0); - my $fg = $self->x_resource ("tabbar-fg"); - my $bg = $self->x_resource ("tabbar-bg"); - my $tabfg = $self->x_resource ("tab-fg"); - my $tabbg = $self->x_resource ("tab-bg"); - my $titfg = $self->x_resource ("title-fg"); - my $titbg = $self->x_resource ("title-bg"); + my $fg = $self->my_resource ("tabbar-fg"); + my $bg = $self->my_resource ("tabbar-bg"); + my $tabfg = $self->my_resource ("tab-fg"); + my $tabbg = $self->my_resource ("tab-bg"); + my $titfg = $self->my_resource ("title-fg"); + my $titbg = $self->my_resource ("title-bg"); defined $fg or $fg = 3; defined $bg or $bg = 0; @@ -343,7 +386,7 @@ sub on_init { $self->{rs_title} = urxvt::SET_COLOR (urxvt::DEFAULT_RSTYLE, $titfg + 2, $titbg + 2); - my $timeouts = $self->x_resource ("tabbar-timeouts"); + my $timeouts = $self->my_resource ("tabbar-timeouts"); $timeouts = '16:.:8:::4:+' unless defined $timeouts; if ($timeouts ne '') { my @timeouts; @@ -357,11 +400,15 @@ sub on_init { } $self->{new_button} = - ($self->x_resource ('new-button') or 'false') !~ /^(?:false|0|no)/i; + ($self->my_resource ('new-button') or 'false') !~ /^(?:false|0|no)/i; $self->{tab_title} = - ($self->x_resource ('title') or 'true') !~ /^(?:false|0|no)/i; + ($self->my_resource ('title') or 'true') !~ /^(?:false|0|no)/i; $self->{autohide} = - ($self->x_resource ('autohide') or 'false') !~ /^(?:false|0|no)/i; + ($self->my_resource ('autohide') or 'false') !~ /^(?:false|0|no)/i; + $self->{no_default_keys} = + ($self->my_resource ('no-tabbedex-keys') or 'false') !~ /^(?:false|0|no)/i; + $self->{reopen_on_close} = + ($self->my_resource ('reopen-on-close') or 'false') !~ /^(?:false|0|no)/i; (); } @@ -384,7 +431,7 @@ sub on_start { } while @argv && $argv[0] ne "-e"; if ($self->{tab_title}) { - $self->{tab_title} = $self->{term}->XInternAtom("WM_NAME", 1); + $self->{tab_title} = $self->{term}->XInternAtom("_NET_WM_NAME", 1); } $self->new_tab (@argv); @@ -444,6 +491,11 @@ sub tab_start { sub tab_destroy { my ($self, $tab) = @_; + if ($self->{reopen_on_close} && $#{ $self->{tabs} } == 0) { + $self->new_tab; + $self->make_current ($self->{tabs}[-1]); + } + $self->{tabs} = [ grep $_ != $tab, @{ $self->{tabs} } ]; $self->update_autohide (); @@ -491,31 +543,36 @@ sub tab_key_press { return 1; } - if ($event->{state} & urxvt::ControlMask) { + return () if ($self->{no_default_keys}); - # previous tab + if ($event->{state} & urxvt::ControlMask) { if ($keysym == 0x004a || $keysym == 0x006a) { if (@{ $self->{tabs} } > 1) { $self->change_tab($tab, -1); } return 1; - } - # next tab - elsif ($keysym == 0x004b || $keysym == 0x006b) { + } elsif ($keysym == 0x004b || $keysym == 0x006b) { if (@{ $self->{tabs} } > 1) { $self->change_tab($tab, 1); } return 1; - } - - - # new tab - elsif ($keysym == 0x003b) { + } elsif ($keysym == 0x003b) { $self->new_tab; return 1; - # tab title + } elsif ($keysym == 0xff52) { + $self->rename_tab($tab); + return 1; + } elsif ($keysym == 0x0047 || $keysym == 0x0067) { + $self->move_tab($tab, 1); + return 1; + } elsif ($keysym == 0x0048 || $keysym == 0x0068) { + $self->move_tab($tab, -1); + return 1; + } elsif ($keysym == 0x0044) { + $tab->destroy; + return 1; } elsif ($keysym == 0x0054 || $keysym == 0x0074) { $tab->{is_inputting_name} = 1; $tab->{old_name} = $tab->{name} ? $tab->{name} : ""; @@ -526,40 +583,7 @@ sub tab_key_press { return 1; } - # move tab left - elsif ($keysym == 0x0048 || $keysym == 0x0068) { - if (@{ $self->{tabs} } > 1) { - my $idx1 = 0; - ++$idx1 while $self->{tabs}[$idx1] != $tab; - my $idx2 = ($idx1 - 1) % @{ $self->{tabs} }; - ($self->{tabs}[$idx1], $self->{tabs}[$idx2]) = - ($self->{tabs}[$idx2], $self->{tabs}[$idx1]); - $self->make_current ($self->{tabs}[$idx2]); - } - return 1; - } - - # move tab right - elsif ($keysym == 0x0047 || $keysym == 0x0067) { - if (@{ $self->{tabs} } > 1) { - my $idx1 = 0; - ++$idx1 while $self->{tabs}[$idx1] != $tab; - my $idx2 = ($idx1 + 1) % @{ $self->{tabs} }; - - ($self->{tabs}[$idx1], $self->{tabs}[$idx2]) = - ($self->{tabs}[$idx2], $self->{tabs}[$idx1]); - $self->make_current ($self->{tabs}[$idx2]); - } - return 1; - } - - # kill tab - elsif ($keysym == 0x0044) { - $tab->destroy; - - return 1; - } } (); @@ -597,6 +621,15 @@ sub tab_user_command { elsif ($cmd eq 'tabbedex:prev_tab') { $self->change_tab($tab, -1); } + elsif ($cmd eq 'tabbedex:move_tab_left') { + $self->move_tab($tab, -1); + } + elsif ($cmd eq 'tabbedex:move_tab_right') { + $self->move_tab($tab, 1); + } + elsif ($cmd eq 'tabbedex:rename_tab') { + $self->rename_tab($tab); + } else { # Proxy the user command through to the tab's term, while taking care not # to get caught in an infinite loop. @@ -621,6 +654,35 @@ sub change_tab { (); } +sub move_tab { + my ($self, $tab, $direction) = @_; + + if (@{ $self->{tabs} } > 1) { + my $idx1 = 0; + ++$idx1 while $self->{tabs}[$idx1] != $tab; + my $idx2 = ($idx1 + $direction) % @{ $self->{tabs} }; + + ($self->{tabs}[$idx1], $self->{tabs}[$idx2]) = + ($self->{tabs}[$idx2], $self->{tabs}[$idx1]); + $self->make_current ($self->{tabs}[$idx2]); + } + + (); +} + +sub rename_tab { + my ($self, $tab) = @_; + + $tab->{is_inputting_name} = 1; + $tab->{old_name} = $tab->{name} ? $tab->{name} : ""; + $tab->{new_name} = ""; + $tab->{name} = "█"; + $self->update_autohide (1); + $self->refresh; + + (); +} + package urxvt::ext::tabbedex::tab; # helper extension implementing the subwindows of a tabbed terminal. @@ -638,5 +700,3 @@ package urxvt::ext::tabbedex::tab; die if $@; } } - -