diff options
| author | Tom Feist <shabble@metavore.org> | 2011-04-13 22:36:52 +0000 | 
|---|---|---|
| committer | Tom Feist <shabble@metavore.org> | 2011-04-13 22:36:52 +0000 | 
| commit | 15b8c9cfe925b2fd214d5077726ab63e8e25ce60 (patch) | |
| tree | b43c7f6024b6dd37aafa4ffe09265b55e5b05f04 | |
| parent | exec.pl: using open3, but horribly broken. Still not sure why. (diff) | |
| download | irssi-scripts-15b8c9cfe925b2fd214d5077726ab63e8e25ce60.tar.gz irssi-scripts-15b8c9cfe925b2fd214d5077726ab63e8e25ce60.zip | |
rl_history_search: make split ensure that selected item is always visible when
nunber of matches > window size
| -rw-r--r-- | history-search/rl_history_search.pl | 88 | 
1 files changed, 73 insertions, 15 deletions
| diff --git a/history-search/rl_history_search.pl b/history-search/rl_history_search.pl index e0d73be..a3651bc 100644 --- a/history-search/rl_history_search.pl +++ b/history-search/rl_history_search.pl @@ -149,6 +149,8 @@ sub history_search {      @history_cache = Irssi::active_win()->get_history_lines();      @search_matches = (); +    $original_win_ref = Irssi::active_win; +      update_history_prompt();  } @@ -373,17 +375,17 @@ sub create_listing_split {      return unless @search_matches > 0; -    $original_win_ref = Irssi::active_win; -      Irssi::signal_add_first('window created', 'sig_win_created');      Irssi::command('window new split');      Irssi::signal_remove('window created', 'sig_win_created');  }  sub close_listing_split { -    return unless defined $split_ref; -    Irssi::command("window close $split_ref->{refnum}"); -    undef $split_ref; + +    if (defined $split_ref) { +        Irssi::command("window close $split_ref->{refnum}"); +        undef $split_ref; +    }      # restore original window focus      if (Irssi::active_win()->{refnum} != $original_win_ref->{refnum}) { @@ -401,28 +403,84 @@ sub sig_win_created {  sub print_current_matches {      return unless defined $split_ref; -    return unless @search_matches > 0; -    $split_ref->command("^clear"); +    my $num_matches = scalar(@search_matches); +    return unless $num_matches > 0; + +    # for some woefully unobvious reason, we need to refetch +    # the window reference in order for its attribute hash +    # to be regenerated. +    my $s_win = Irssi::window_find_refnum($split_ref->{refnum}); + +    my $split_height = $s_win->{height}; + +    $s_win->command("^scrollback clear"); + +    # disable timestamps to ensure a clean window.      my $orig_ts_level = Irssi::parse_special('$timestamp_level'); -    $split_ref->command("^set timestamp_level $orig_ts_level -CLIENTCRAP"); +    $s_win->command("^set timestamp_level $orig_ts_level -CLIENTCRAP"); + -    $split_ref->print('%_Current history matches. Press <esc> to close.%_', -                      Irssi::MSGLEVEL_CLIENTCRAP|Irssi::MSGLEVEL_NEVER); +    $original_win_ref->print("Num matches: $num_matches, height: $split_height") +      if DEBUG; + +    # print header +    # TODO: make this a format? +    $s_win->print('%_Current history matches. Press <esc> to close.%_', +                  MSGLEVEL_CLIENTCRAP | MSGLEVEL_NEVER); + +    $split_height -= 2; # account for header line;      my $hist_entry = get_history_match(); -    foreach my $i (0..$#search_matches) { -        my $j =  $#search_matches - $i; -        my $entry = $search_matches[$j]; +    my ($start, $end); + +    if ($num_matches > $split_height) { +        # we have too many matches to fit in the window. decide on a new +        # start and end point. + +        my $half_height = int ($split_height / 2); + +        # initial start pos is in the middle of the screen. +        $start = $match_index >= $half_height +          ? $match_index - $half_height +          : 0; +        # and ends with the max number of matches we can fit +        $end   = $start + $split_height > $num_matches - 1 +          ? $num_matches - 1 +          : $start + $split_height; + +        # readjust start if the screen isn't filled. +        if ($end - $start < $split_height) { +            $start = $end - $split_height; +        } + +        _debug("sh: $split_height, hh: $half_height, " +                . "mi: $match_index, start: $start, end: $end"); +    } else { +        $start = 0; +        $end   = $#search_matches; +    } + +    foreach my $i ($start..$end) { +        my $j =  $num_matches - $i; +        my $entry = $search_matches[$i];          my $hilight = $hist_entry eq $entry            ? '%g'            : '';          $hilight = Irssi::parse_special($hilight);          my $str = sprintf("%s%-6d %s%%n", $hilight, $j, $entry); -        $split_ref->print($str, Irssi::MSGLEVEL_CLIENTCRAP|Irssi::MSGLEVEL_NEVER); +        $s_win->print($str, MSGLEVEL_CLIENTCRAP|MSGLEVEL_NEVER);      } -    $split_ref->command("^set timestamp_level $orig_ts_level"); +    # restore timestamp settings. +    $s_win->command("^set timestamp_level $orig_ts_level"); +} + +sub _debug { +    return unless DEBUG; +    my ($msg, @args) = @_; +    my $str = sprintf($msg, @args); +    $original_win_ref->print($str);  } | 
