diff options
| author | Tom Feist <shabble@metavore.org> | 2010-12-10 01:51:12 +0000 | 
|---|---|---|
| committer | Tom Feist <shabble@metavore.org> | 2010-12-10 01:51:12 +0000 | 
| commit | 2f0847d401ba3091d3c1b2a4a687195894967e77 (patch) | |
| tree | d071419fe25114b182238bc600642b54f1c18f80 /ido-mode | |
| parent | test commit (diff) | |
| download | irssi-scripts-2f0847d401ba3091d3c1b2a4a687195894967e77.tar.gz irssi-scripts-2f0847d401ba3091d3c1b2a4a687195894967e77.zip | |
ido_switcher: implemented the bulk of the script. Tag specific and
tab-completion still todo.
Diffstat (limited to 'ido-mode')
| -rw-r--r-- | ido-mode/ido_switcher.pl | 171 | 
1 files changed, 118 insertions, 53 deletions
| diff --git a/ido-mode/ido_switcher.pl b/ido-mode/ido_switcher.pl index 5d75764..a994b5b 100644 --- a/ido-mode/ido_switcher.pl +++ b/ido-mode/ido_switcher.pl @@ -85,9 +85,16 @@ sub DEBUG () { $DEBUG_ENABLED }  # check we have uberprompt loaded. +sub _print { +    my (@args) = @_; + +    my $win = Irssi::active_win; +    $win->print(@args); +} +  sub script_is_loaded {      my $name = shift; -    print "Checking if $name is loaded" if DEBUG; +    _print "Checking if $name is loaded" if DEBUG;      no strict 'refs';      my $retval = defined %{ "Irssi::Script::${name}::" };      use strict 'refs'; @@ -97,7 +104,7 @@ sub script_is_loaded {  unless (script_is_loaded('uberprompt')) { -    print "This script requires 'uberprompt.pl' in order to work. " +    _print "This script requires 'uberprompt.pl' in order to work. "       . "Attempting to load it now...";      Irssi::signal_add('script error', 'load_uberprompt_failed'); @@ -111,7 +118,7 @@ unless (script_is_loaded('uberprompt')) {  sub load_uberprompt_failed {      Irssi::signal_remove('script error', 'load_uberprompt_failed'); -    print "Script could not be loaded. Script cannot continue. " +    _print "Script could not be loaded. Script cannot continue. "        . "Check you have uberprompt.pl installed in your path and "          .  "try again.";      die "Script Load Failed: " . join(" ", @_); @@ -147,15 +154,23 @@ sub ido_switch_start {      # set startup flags      $ido_switch_active = 1;      $search_str = ''; -    $match_index = -1; +    $match_index = 0; -    @window_cache = get_all_windows(); -    print "Win cache: " . join(", ", @window_cache) if DEBUG; +    # refresh in case we toggled it last time. +    $ido_use_flex   = Irssi::settings_get_bool('ido_use_flex'); + +    _print "Win cache: " . join(", ", @window_cache) if DEBUG; + +    _update_cache();      update_matches();      update_prompt();  } +sub _update_cache { +    @window_cache = get_all_windows(); +} +  sub get_all_windows {      my @ret; @@ -163,13 +178,30 @@ sub get_all_windows {          my @items = $win->items();          if ($win->{name} ne '') { -            push @ret,  $win->{name}; +            push @ret, { +                        name   => $win->{name}, +                        type   => 'WINDOW', +                        num    => $win->{refnum}, +                        server => $win->{active_server}, +                       }; +          } elsif (scalar @items) { -            push @ret, map {  $_->{visible_name} } @items; +            foreach my $item (@items) { +                push @ret, { +                            name   => $item->{visible_name}, +                            type   => $item->{type}, +                            server => $item->{server}, +                            num    => $win->{refnum}, +                            itemname => $item->{name}, +                           }; +            }          } else { -            push @ret, '???'; +            #_print "Error occurred reading info from window: $win"; +            #_print Dumper($win);          }      } + +    @ret = sort { $b->{num} <=> $a->{num} } @ret;      return @ret;  } @@ -178,7 +210,13 @@ sub ido_switch_select {      # /window goto $refnum      # or      # /window item goto $itemname -    Irssi::command("/echo Selecting!"); +    _print "Selecting window: " . $selected->{name}; +    Irssi::command("WINDOW GOTO " . $selected->{name}); +    if ($selected->{type} ne 'WINDOW') { +        _print "Selecting window item: " . $selected->{itemname}; +        Irssi::command("WINDOW ITEM GOTO " . $selected->{itemname}); +    } +      ido_switch_exit();  } @@ -187,7 +225,6 @@ sub ido_switch_exit {      Irssi::gui_input_set($input_copy);      Irssi::gui_input_set_pos($input_pos_copy); -      Irssi::signal_emit('change prompt', '', 'UP_INNER');  } @@ -201,7 +238,7 @@ sub update_prompt {      $show_num = $match_num if $match_num < $show_num;      if ($show_num > 0) { -        print "Showing: $show_num matches" if DEBUG; +        _print "Showing: $show_num matches" if DEBUG;          my @ordered_matches           = @search_matches[$match_index .. $#search_matches, @@ -209,20 +246,48 @@ sub update_prompt {          my @show = @ordered_matches[0..$show_num - 1]; -        $show[0] = '%g' . $show[0] . '%n'; -        @show[1..$#show] -         = map { '%r' . $_ . '%n' } @show[1..$#show]; +        $show[0] = sprintf '%%g%d:%s%%n', $show[0]->{num}, $show[0]->{name}; +        @show[1..$#show] = map +          { +              sprintf '%%r%d:%s%%n', $_->{num}, $_->{name}; +          } @show[1..$#show];          $show_str = join ', ', @show;      } - +    my $flex = sprintf(' [%s]', $ido_use_flex ? 'F' : 'E'); +    my $search = ''; +    $search = ' `' . $search_str . "'" if length $search_str;      Irssi::signal_emit('change prompt', -                       ' win: ' . $show_str, +                       $flex . $search . ' win: ' . $show_str,                         'UP_INNER');  }  sub update_matches { -    @search_matches = grep { m/\Q$search_str\E/ } @window_cache; +    if ($ido_use_flex) { +        @search_matches = grep { flex_match($search_str, $_->{name}) } @window_cache; +    } else { +        @search_matches = grep { $_->{name} =~ m/\Q$search_str\E/ } @window_cache; +    } + +} + +sub flex_match { +    my ($pattern, $source) = @_; + +    my @chars = split '', $pattern; +    my $i = -1; +    my $ret = 1; +    foreach my $char (@chars) { +        my $pos = index($source, $char, $i); +        if ($pos > -1) { +            $i = $pos; +        } else { +            $ret = 0; +            last; +        } +    } + +    return $ret;  }  sub prev_match { @@ -231,7 +296,7 @@ sub prev_match {      if ($match_index > $#search_matches) {          $match_index = 0;      } -    print "index now: $match_index" if DEBUG; +    _print "index now: $match_index" if DEBUG;  }  sub next_match { @@ -240,7 +305,7 @@ sub next_match {      if ($match_index < 0) {          $match_index = $#search_matches;      } -    print "index now: $match_index" if DEBUG; +    _print "index now: $match_index" if DEBUG;  }  sub get_window_match { @@ -253,30 +318,48 @@ sub handle_keypress {      return unless $ido_switch_active;      if ($key == 0) { # C-SPC? -        print "Ctrl-space"; +        _print "Ctrl-space"; + +        $search_str = ''; +        @window_cache = @search_matches; +        update_prompt(); + +        Irssi::signal_stop(); +        return; +    } + +    if ($key == 6) { # C-f + +        $ido_use_flex = not $ido_use_flex; +        _update_cache(); + +        update_matches(); +        update_prompt(); +          Irssi::signal_stop();          return;      }  	if ($key == 10) { # enter -        print "selecting history and quitting" if DEBUG; -        ido_switch_select(get_window_match); +        _print "selecting history and quitting" if DEBUG; +        my $selected_win = get_window_match(); +        ido_switch_select($selected_win);          return;  	}      if ($key == 18) { # Ctrl-R -        print "skipping to prev match" if DEBUG; +        _print "skipping to prev match" if DEBUG;          prev_match(); -        update_matches(); +        #update_matches();          update_prompt();          Irssi::signal_stop(); # prevent the bind from being re-triggered.          return;      }      if ($key == 19) {  # Ctrl-S -        print "skipping to next match" if DEBUG; +        _print "skipping to next match" if DEBUG;          next_match(); -        update_matches(); +        #update_matches();          update_prompt();          Irssi::signal_stop(); @@ -284,7 +367,7 @@ sub handle_keypress {      }      if ($key == 7) { # Ctrl-G -        print "aborting search" if DEBUG; +        _print "aborting search" if DEBUG;          ido_switch_exit();          Irssi::signal_stop();          return; @@ -294,8 +377,9 @@ sub handle_keypress {          if (length $search_str) {              $search_str = substr($search_str, 0, -1); -            print "Deleting char, now: $search_str" if DEBUG; +            _print "Deleting char, now: $search_str" if DEBUG;          } +          update_matches();          update_prompt(); @@ -305,6 +389,11 @@ sub handle_keypress {      # TODO: handle esc- sequences and arrow-keys? +    if ($key == 27) { # Esc +        ido_switch_exit(); +        return; +    } +      if ($key >= 32) { # printable          $search_str .= chr($key); @@ -321,27 +410,3 @@ sub handle_keypress {  ido_switch_init(); -# sub update_history_matches { -#     my ($match_str) = @_; -#     $match_str = $search_str unless defined $match_str; - -#     my %unique; -#     my @matches = grep { m/\Q$match_str/i } @history_cache; - -#     @search_matches = (); - -#     # uniquify the results, whilst maintaining order. -#     foreach my $m (@matches) { -#         unless (exists($unique{$m})) { -#             # add them in reverse order. -#             unshift @search_matches, $m; -#         } -#         $unique{$m}++; -#     } - -#     print "updated matches: ", scalar(@search_matches), " ", -#       join(", ", @search_matches) if DEBUG; -# } - - - | 
