URxvt: tabbedex updated.

This commit is contained in:
Kolan Sh 2013-03-27 17:38:10 +04:00
parent 12b2ceb9f2
commit bd5fc24a5c
1 changed files with 122 additions and 62 deletions

View File

@ -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
## <steven dot merrill at gmail.com>
## (mail4stb/AT/gmail.com), Steven Merrill
## <steven dot merrill at gmail.com>, Mark Pustjens
## <pustjens@dds.nl> and more...
##
## The following has been added:
##
@ -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 <pustjens@dds.nl>
##
## 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 $@;
}
}