From: Ailin Nemui Date: Tue, 25 Sep 2018 11:00:51 +0000 (+0200) Subject: [adv_windowlist] update to adv_windowlist 1.6 X-Git-Url: http://git.99rst.org/?a=commitdiff_plain;h=75f4d7af4ee407d0d237c7325f4c763f8ebb92ee;p=irssi-scripts.irssi.org.git [adv_windowlist] update to adv_windowlist 1.6 * add detach setting to hide windows * fix race condition when loading the script, reported by madduck * improve compatibility with Irssi 1.2 --- diff --git a/scripts/adv_windowlist.pl b/scripts/adv_windowlist.pl index 91afa1c..9a8fb5c 100644 --- a/scripts/adv_windowlist.pl +++ b/scripts/adv_windowlist.pl @@ -1,7 +1,7 @@ use strict; use warnings; -our $VERSION = '1.5'; # 5df597ac461465e +our $VERSION = '1.6'; # 8f71fef5a41b370 our %IRSSI = ( authors => 'Nei', contact => 'Nei @ anti@conference.jabber.teamidiot.de', @@ -97,6 +97,18 @@ our %IRSSI = ( # 1 to hide visible windows without items (negative exempt # active window) # +# /set awl_detach +# * list of windows that should be hidden from the window list. you +# can also use /awl detach and /awl attach to manage this +# setting. an optional data_level can be specified with ",num" +# +# /set awl_detach_data +# * num : hide the detached window if its data_level is below num +# +# /set awl_detach_aht +# * if enabled, also detach all windows listed in the +# activity_hide_targets setting +# # /set awl_hide_data # * num : hide the window if its data_level is below num # set it to 0 to basically disable this feature, @@ -244,6 +256,16 @@ our %IRSSI = ( # Commands # ======== +# /awl detach +# * hide the current window from the window list. num specifies the +# data_level (optional) +# +# /awl attach +# * unhide the current window from the window list +# +# /awl ack +# * change to the next window with activity, ignoring detached windows +# # /awl redraw # * redraws the windowlist. There may be occasions where the # windowlist can get destroyed so you can use this command to @@ -293,8 +315,8 @@ BEGIN { *CORE::GLOBAL::length = *CORE::GLOBAL::length = sub (_) { defined $_[0] ? CORE::length($_[0]) : undef }; - *Irssi::active_win = {}; # hide incorrect warning } + *Irssi::active_win = {}; # hide incorrect warning } unless (IN_IRSSI) { @@ -330,6 +352,7 @@ my %viewer; my (%keymap, %nummap, %wnmap, %specialmap, %wnmap_exp, %custom_key_map); my %banned_channels; +my %detach_map; my %abbrev_cache; use constant setc => 'awl'; @@ -347,7 +370,7 @@ sub add_statusbar { no strict 'refs'; *{$l} = sub { awl($close, @_) }; } - Irssi::command("statusbar $l reset"); + Irssi::command("^statusbar $l reset"); Irssi::command("statusbar $l enable"); if (lc $S{placement} eq 'top') { Irssi::command("statusbar $l placement top"); @@ -752,6 +775,29 @@ sub _get_format { Irssi::current_theme->get_format(__PACKAGE__, @_) } +sub _is_detached { + my ($win, $active_number) = @_; + my $level = $win->{data_level} // 0; + my $number = $win->{refnum}; + my $name = lc1459( as_uni($win->{name}) ); + my $active = lc1459( as_uni($win->get_active_name) // '' ); + my $tag = $win->{active} && $win->{active}{server} ? lc1459( as_uni($win->{active}{server}{tag}) // '' ) : ''; + my @cond = ($number); + push @cond, "$name" if length $name; + push @cond, "$tag/$active" if length $tag && length $active; + push @cond, "$active" if length $active; + push @cond, "$tag/*", "$tag/::all" if length $tag; + push @cond, "*", "::all"; + for my $cond (@cond) { + if (exists $detach_map{ $cond }) { + my $dd = $detach_map{ $cond } // $S{detach_data}; + return $win->{data_level} < abs $dd + && ($number != $active_number || 0 <= $dd); + } + } + return; +} + sub _calculate_items { my ($wins, $abbrevList) = @_; @@ -809,6 +855,8 @@ sub _calculate_items { elsif (exists $awins{$win->{refnum}} && $S{hide_empty} && !$win->items && ($win->{refnum} != $active->{refnum} || 0 <= $S{hide_empty})) { next; } + elsif (_is_detached($win, $active->{refnum})) { + next; } my $colour = $win->{hilight_color} // ''; my $hilight = do { @@ -1287,6 +1335,9 @@ sub reset_awl { hide_data => Irssi::settings_get_int( set 'hide_data'), hide_name => Irssi::settings_get_int( set 'hide_name_data'), hide_empty => Irssi::settings_get_int( set 'hide_empty'), + detach => Irssi::settings_get_str( set 'detach'), + detach_data => Irssi::settings_get_int( set 'detach_data'), + detach_aht => Irssi::settings_get_bool(set 'detach_aht'), sbar_maxlen => Irssi::settings_get_bool(set 'sbar_maxlength'), placement => Irssi::settings_get_str( set 'placement'), position => Irssi::settings_get_int( set 'position'), @@ -1412,9 +1463,16 @@ return sub { stop_viewer(); } - %banned_channels = map { lc1459(to_uni($_)) => undef } + %banned_channels = map { lc1459(as_uni($_)) => undef } split ' ', Irssi::settings_get_str('banned_channels'); + %detach_map = ($S{detach_aht} + ? (map { ( lc1459(as_uni($_)) => undef ) } + split ' ', Irssi::settings_get_str('activity_hide_targets')) : (), + (map { my ($k, $v) = (split /(?:,(-?\d+))$/, $_)[0, 1]; + ( lc1459(as_uni($k)) => $v ) } + split ' ', $S{detach})); + my @sb_base = split /\177/, sb_format_expand("{sbstart}{sb \177}{sbend}"), 2; $sb_base_width_pre = sb_length($sb_base[0]); $sb_base_width_post = max 0, sb_length($sb_base[1])-1; @@ -1427,6 +1485,228 @@ return sub { $CHANGED{AWINS} = 1; } +sub hide_window { + my ($data) = @_; + my $ent; + + $data =~ s/\s*$//; + my $win = Irssi::active_win; + my $number = $win->{refnum}; + my $name = as_uni($win->{name}); + my $active = as_uni($win->get_active_name) // ''; + my $tag = $win->{active} && $win->{active}{server} ? as_uni($win->{active}{server}{tag}) // '' : ''; + if (length $name) { + $ent = "$name"; + } + elsif (length $tag && length $active) { + $ent = "$tag/$active"; + } + else { + $ent = "$number"; + } + + my $found = 0; + my @setting; + for my $s (split ' ', $S{detach}) { + my ($k, $v) = (split /(?:,(-?\d+))$/, $s)[0, 1]; + if (lc1459(as_uni($k)) eq lc1459($ent)) { + unless ($found) { + if ($data =~ /^(-?\d+)$/) { + $ent .= ",$1"; + } + if (defined $v && 0 == abs $v) { + $win->print("Hiding window $ent"); + } + push @setting, as_tc($ent); + $found = 1; + } + } + else { + push @setting, defined $v ? "$k,$v" : $k; + } + } + unless ($found) { + $win->print("Hiding window $ent"); + if ($data =~ /^(-?\d+)$/) { + $ent .= ",$1"; + } + push @setting, as_tc($ent); + } + + if (@setting) { + Irssi::command("^set ".(set 'detach')." @setting"); + } else { + Irssi::command("^set -clear ".(set 'detach')); + } +} + +sub unhide_window { + my ($data, $server, $witem) = @_; + my $win = Irssi::active_win; + my $number = $win->{refnum}; + my $name = as_uni($win->{name}); + my $active = as_uni($win->get_active_name) // ''; + my $tag = $win->{active} && $win->{active}{server} ? as_uni($win->{active}{server}{tag}) // '' : ''; + + my @setting; + my %detach_aht; + if ($S{detach_aht}) { + %detach_aht = (map { ( lc1459(as_uni($_)) => undef ) } + split ' ', Irssi::settings_get_str('activity_hide_targets')); + } + my @setting; + my @kills = (length $name ? $name : undef, + length $tag && length $active ? "$tag/$active" : undef, + length $active ? $active : undef, + $number); + my @was_unhidden = (0) x @kills; + for my $s (split ' ', $S{detach}) { + my ($k, $v) = (split /(?:,(-?\d+))$/, $s)[0, 1]; + my $k2 = lc1459(as_uni($k)); + my $kill; + for my $ki (0..$#kills) { + if (defined $kills[$ki] && $k2 eq lc1459($kills[$ki])) { + $kill = $ki; + } + } + + if (defined $kill) { + if (defined $v && 0 == abs $v) { + $was_unhidden[$kill] = 1; + push @setting, defined $v ? "$k,$v" : $k; + } else { + $win->print("Unhiding window $kills[$kill]"); + } + } + else { + push @setting, defined $v ? "$k,$v" : $k; + } + } + my @is_hidden = (defined $kills[0] && (exists $detach_map{"*"} || exists $detach_map{"::all"}), + defined $kills[1] && (exists $detach_map{lc1459("$tag/*")} || exists $detach_map{lc1459("$tag/::all")} + || exists $detach_map{"*"} || exists $detach_map{"::all"}), + defined $kills[2] && (exists $detach_map{"*"} || exists $detach_map{"::all"}), + (exists $detach_map{"*"} || exists $detach_map{"::all"}) + ); + for my $ki (1, 2, 0, 3) { + if ($is_hidden[$ki]) { + unless ($was_unhidden[$ki]) { + $win->print("Unhiding window $kills[$ki]"); + push @setting, "$kills[$ki],0"; + $was_unhidden[$ki] = 1; + } + last; + } + } + my @is_hidden_aht = (defined $kills[0] && (exists $detach_aht{lc1459($name)} + || exists $detach_aht{"*"} || exists $detach_aht{"::all"}), + defined $kills[1] && (exists $detach_aht{lc1459("$tag/$active")} + || exists $detach_aht{lc1459($active)} + || exists $detach_aht{lc1459("$tag/*")} || exists $detach_aht{lc1459("$tag/::all")} + || exists $detach_aht{"*"} || exists $detach_aht{"::all"}), + defined $kills[2] && (exists $detach_aht{lc1459($active)} + || exists $detach_aht{"*"} || exists $detach_aht{"::all"}), + (exists $detach_aht{$number} || exists $detach_aht{"*"} || exists $detach_aht{"::all"}) + ); + for my $ki (1, 2, 0, 3) { + if ($is_hidden_aht[$ki]) { + unless ($was_unhidden[$ki]) { + $win->print("Unhiding window $kills[$ki], it is hidden because ".(set 'detach_aht')." is ON"); + push @setting, "$kills[$ki],0"; + $was_unhidden[$ki] = 1; + } + last; + } + } + + if (@setting) { + Irssi::command("^set ".(set 'detach')." @setting"); + } else { + Irssi::command("^set -clear ".(set 'detach')); + } +} + +sub ack_window { + my ($data, $server, $witem) = @_; + my $win = Irssi::active_win; + my $number = $win->{refnum}; + if (grep { $_->{cmd} eq 'ack' } Irssi::commands) { + my $Orig_Irssi_windows = \&Irssi::windows; + local *Irssi::windows = sub () { grep { !_is_detached($_, $number) } $Orig_Irssi_windows->() }; + Irssi::command("ack" . (length $data ? " $data" : "")); + } else { + my $ignore_refnum = Irssi::settings_get_bool('active_window_ignore_refnum'); + my $max_win; + my $max_act = 0; + my $max_ref = 0; + for my $rec (Irssi::windows) { + next if _is_detached($rec, $number); + + # ignore refnum + if ($ignore_refnum && + $rec->{data_level} > 0 && $max_act < $rec->{data_level}) { + $max_act = $rec->{data_level}; + $max_win = $rec; + } + + # windows with lower refnums break ties + elsif (!$ignore_refnum && + $rec->{data_level} > 0 && + ($rec->{data_level} > $max_act || + ($rec->{data_level} == $max_act && $rec->{refnum} < $max_ref))) { + $max_act = $rec->{data_level}; + $max_win = $rec; + $max_ref = $rec->{refnum}; + } + } + $max_win->set_active if defined $max_win; + } +} + +sub refnum_changed { + my ($win, $old_refnum) = @_; + my @old_setting = split ' ', $S{detach}; + my @setting = map { + my ($k, $v) = (split /(?:,(-?\d+))$/, $_)[0, 1]; + if ($k eq $old_refnum) { + $win->{refnum} . (defined $v ? ",$v" : "") + } + else { + $_ + } + } @old_setting; + if ("@old_setting" ne "@setting") { + $S{detach} = "@setting"; + Irssi::settings_set_str(set 'detach', "@setting"); + &setup_changed; + } + else { + &wl_changed; + } +} + +sub window_destroyed { + my ($win) = @_; + my @old_setting = split ' ', $S{detach}; + my @setting = grep { + my ($k, $v) = (split /(?:,(-?\d+))$/, $_)[0, 1]; + if ($k eq $win->{refnum}) { + 0; + } + else { + 1; + } + } @old_setting; + if ("@old_setting" ne "@setting") { + $S{detach} = "@setting"; + Irssi::settings_set_str(set 'detach', "@setting"); + &setup_changed; + } + else { + &awins_changed; + } +} + sub stop_mouse_tracking { print STDERR "\e[?1005l\e[?1000l"; } @@ -1610,7 +1890,11 @@ sub queue_refresh { sub awl_init { termsize_changed(); + setup_changed(); update_keymap(); + Irssi::timeout_remove($globTime) + if defined $globTime; + awl_refresh(); } sub runsub { @@ -1646,6 +1930,9 @@ Irssi::signal_register({ Irssi::settings_add_bool(setc, set 'prefer_name', 0); # Irssi::settings_add_int( setc, set 'hide_empty', 0); # Irssi::settings_add_int( setc, set 'hide_data', 0); # +Irssi::settings_add_str( setc, set 'detach', ''); # +Irssi::settings_add_int( setc, set 'detach_data', -3); # +Irssi::settings_add_bool(setc, set 'detach_aht', 0); # Irssi::settings_add_int( setc, set 'hide_name_data', 0); # Irssi::settings_add_int( setc, set 'maxlines', 9); # Irssi::settings_add_int( setc, set 'maxcolumns', 4); # @@ -1688,9 +1975,9 @@ Irssi::signal_add({ 'window item changed' => 'wl_changed', 'window changed automatic' => 'window_changed', 'window created' => 'awins_changed', - 'window destroyed' => 'awins_changed', + 'window destroyed' => 'window_destroyed', 'window name changed' => 'wl_changed', - 'window refnum changed' => 'wl_changed', + 'window refnum changed' => 'refnum_changed', }); Irssi::signal_add_last('gui mouse' => 'mouse_escape'); Irssi::signal_add_last('gui mouse' => 'mouse_scroll_event'); @@ -1698,6 +1985,9 @@ Irssi::signal_add_last('gui mouse' => 'awl_mouse_event'); Irssi::command_bind( setc() => runsub(setc()) ); Irssi::command_bind( setc() . ' redraw' => 'screenFullRedraw' ); Irssi::command_bind( setc() . ' restart' => 'restartViewerServer' ); +Irssi::command_bind( setc() . ' attach' => 'unhide_window' ); +Irssi::command_bind( setc() . ' detach' => 'hide_window' ); +Irssi::command_bind( setc() . ' ack' => 'ack_window' ); { my $l = set 'shared'; @@ -2436,16 +2726,27 @@ UNITCHECK # Changelog # ========= -# 1.5 - improve compat. with sideways splits +# 1.6 +# - add detach setting to hide windows +# - fix race condition when loading the script, reported by madduck +# - improve compatibility with irssi 1.2 +# +# 1.5 +# - improve compat. with sideways splits # # 1.4 # - fix line wrapping in some themes, reported by justanotherbody # - fix named window key detection, reported by madduck # - make title (in viewer and shared_sbar) configurable # -# 1.3 - workaround for irssi issue #572 -# 1.2 - new format to choose abbreviation character -# 1.1 - infinite loop on shortening certain window names reported by Kalan +# 1.3 +# - workaround for irssi issue #572 +# +# 1.2 +# - new format to choose abbreviation character +# +# 1.1 +# - infinite loop on shortening certain window names reported by Kalan # # 1.0 # - new awl_viewer_launch setting and an array of related settings