diff options
| -rw-r--r-- | vim-mode/vim_mode.pl | 120 | 
1 files changed, 88 insertions, 32 deletions
| diff --git a/vim-mode/vim_mode.pl b/vim-mode/vim_mode.pl index 85965c5..085ea78 100644 --- a/vim-mode/vim_mode.pl +++ b/vim-mode/vim_mode.pl @@ -18,6 +18,8 @@  # * change/change/yank line: cc dd yy S  # * Combinations like in Vi, e.g. d5fx  # * window selection: :b<num>, :b#, :b <match-str> +# +# * special registers: "* "+ (contain irssi's cut-buffer)  # TODO:  # * History: @@ -62,6 +64,10 @@  # /statusbar window add vim_mode to get the status. +# And the following to let :b name display a list of matching channels + +# /statusbar window add vim_windows +  # NOTE: This script is still under heavy development, and there may be bugs.  # Please submit reproducible sequences to the bug-tracker at:  # http://github.com/shabble/shab-irssi-scripts/issues @@ -680,6 +686,12 @@ sub cmd_movement_tilde {  sub cmd_movement_register {      my ($count, $pos, $char) = @_; +    # + and * contain both irssi's cut-buffer +    if ($char eq '+' or $char eq '*') { +        $registers->{'+'} = Irssi::parse_special('$U'); +        $registers->{'*'} = $registers->{'+'}; +    } +      $register = $char;      print "Changing register to $register" if DEBUG;  } @@ -727,38 +739,10 @@ sub cmd_ex_command {              Irssi::command('window last');          # Go to best regex matching window.          } else { -            my $regex = qr/\Q$buffer\E/; - -            my @matches; -            foreach my $window (Irssi::windows()) { -                # Matching window names. -                if ($window->{name} =~ /$regex/) { -                    my $ratio = ($+[0] - $-[0]) / length($window->{name}); -                    push @matches, { window => $window, -                                     item => undef, -                                     ratio => $ratio }; -                    print ":b $window->{name}: $ratio" if DEBUG; -                } -                # Matching Window item names (= channels). -                foreach my $item ($window->items()) { -                    if ($item->{name} =~ /$regex/) { -                        my $length = length($item->{name}); -                        $length-- if index($item->{name}, '#') == 0; -                        my $ratio = ($+[0] - $-[0]) / $length; -                        push @matches, { window => $window, -                                         item => $item, -                                         ratio => $ratio }; -                        print ":b $window->{name} $item->{name}: $ratio" -                            if DEBUG; -                    } -                } -            } - -            if (scalar @matches > 0) { -                @matches = sort {$b->{ratio} <=> $a->{ratio}} @matches; - -                $window = $matches[0]->{window}; -                $item = $matches[0]->{item}; +            my $matches = _matching_windows($buffer); +            if (scalar @$matches > 0) { +                $window = @$matches[0]->{window}; +                $item = @$matches[0]->{item};              }          } @@ -771,6 +755,55 @@ sub cmd_ex_command {      }  } +sub _matching_windows { +    my ($buffer) = @_; + +    my $server; + +    if ($buffer =~ m{^(.+)/(.+)}) { +        $server = $1; +        $buffer = $2; +    } + +    print ":b searching for channel $buffer" if DEBUG; +    print ":b on server $server" if $server and DEBUG; + +    my @matches; +    foreach my $window (Irssi::windows()) { +        # Matching window names. +        if ($window->{name} =~ /$buffer/i) { +            my $ratio = ($+[0] - $-[0]) / length($window->{name}); +            push @matches, { window => $window, +                               item => undef, +                              ratio => $ratio, +                               text => $window->{name} }; +            print ":b $window->{name}: $ratio" if DEBUG; +        } +        # Matching Window item names (= channels). +        foreach my $item ($window->items()) { +            # Wrong server. +            if ($server and (!$item->{server} or +                              $item->{server}->{chatnet} !~ /^$server/i)) { +                next; +            } +            if ($item->{name} =~ /$buffer/i) { +                my $length = length($item->{name}); +                $length-- if index($item->{name}, '#') == 0; +                my $ratio = ($+[0] - $-[0]) / $length; +                push @matches, { window => $window, +                                   item => $item, +                                  ratio => $ratio, +                                   text => $item->{name} }; +                print ":b $window->{name} $item->{name}: $ratio" if DEBUG; +            } +        } +    } + +    @matches = sort {$b->{ratio} <=> $a->{ratio}} @matches; + +    return \@matches; +} +  # vi mode status item.  sub vim_mode_cb { @@ -802,6 +835,26 @@ sub vim_mode_cb {      $sb_item->default_handler($get_size_only, "{sb $mode_str}", '', 0);  } +# :b window list item. +sub b_windows_cb { +    my ($sb_item, $get_size_only) = @_; + +    my $windows = ''; + +    # A little code duplication of cmd_ex_command()! +    my $arg_str = join '', @ex_buf; +    if ($arg_str =~ m|b(?:uffer)?\s*(.+)$|) { +        my $buffer = $1; +        if ($buffer !~ /^[0-9]$/ and $buffer ne '#') { +            # Display matching windows. +            my $matches = _matching_windows($buffer); +            $windows = join ',', map { $_->{text} } @$matches; +        } +    } + +    $sb_item->default_handler($get_size_only, "{sb $windows}", '', 0); +} +  sub got_key {      my ($key) = @_; @@ -955,6 +1008,8 @@ sub handle_command {              _set_prompt(':' . join '', @ex_buf);          } +        Irssi::statusbar_items_redraw("vim_windows"); +      } else {          my $char = chr($key); @@ -1109,6 +1164,7 @@ sub vim_mode_init {      Irssi::signal_add_first 'gui key pressed' => \&got_key;      Irssi::signal_add 'setup changed' => \&setup_changed;      Irssi::statusbar_item_register ('vim_mode', 0, 'vim_mode_cb'); +    Irssi::statusbar_item_register ('vim_windows', 0, 'b_windows_cb');      Irssi::settings_add_str('vim_mode', 'vim_mode_cmd_seq', '');      Irssi::settings_add_bool('vim_mode', 'vim_mode_debug', 0); | 
