From 69aa9875427df8519a0202587abc2646ea05a2a9 Mon Sep 17 00:00:00 2001 From: Tom Feist Date: Sat, 9 Apr 2011 13:05:45 +0100 Subject: rl_history_search: added a new "view history" option, available by pressing tab when completion is active. --- history-search/rl_history_search.pl | 113 ++++++++++++++++++++++++++++++------ 1 file changed, 95 insertions(+), 18 deletions(-) diff --git a/history-search/rl_history_search.pl b/history-search/rl_history_search.pl index 2df9171..dc3d91a 100644 --- a/history-search/rl_history_search.pl +++ b/history-search/rl_history_search.pl @@ -74,6 +74,9 @@ my @history_cache = (); my @search_matches = (); my $match_index = 0; +# split info +my $split_ref; +my $original_win_ref; my $DEBUG_ENABLED = 0; sub DEBUG () { $DEBUG_ENABLED } @@ -125,11 +128,10 @@ sub setup_changed { $DEBUG_ENABLED = Irssi::settings_get_bool('histsearch_debug'); } - sub history_search { $search_active = 1; $search_str = ''; - $match_index = -1; + $match_index = 0; @history_cache = Irssi::active_win()->get_history_lines(); @search_matches = (); @@ -139,6 +141,7 @@ sub history_search { sub history_exit { $search_active = 0; + close_listing_split(); Irssi::signal_emit('change prompt', '', 'UP_INNER'); } @@ -160,6 +163,7 @@ sub update_history_matches { @search_matches = (); # uniquify the results, whilst maintaining order. + # TODO: duplicates should keep teh most recent one? foreach my $m (@matches) { unless (exists($unique{$m})) { # add them in reverse order. @@ -205,6 +209,29 @@ sub handle_keypress { return unless $search_active; + if ($key == 7) { # Ctrl-G + print "aborting search" if DEBUG; + history_exit(); + + # cancel empties the inputline. + Irssi::gui_input_set(''); + Irssi::gui_input_set_pos(0); + + Irssi::signal_stop(); + return; + } + + if ($key == 9) { # TAB + update_history_matches(); + if (not defined $split_ref) { + create_listing_split(); + } else { + print_current_matches(); + } + + Irssi::signal_stop(); + return; + } if ($key == 10) { # enter print "selecting history and quitting" if DEBUG; history_exit(); @@ -216,6 +243,7 @@ sub handle_keypress { prev_match(); update_input(); update_history_prompt(); + print_current_matches(); Irssi::signal_stop(); # prevent the bind from being re-triggered. return; } @@ -225,45 +253,43 @@ sub handle_keypress { next_match(); update_input(); update_history_prompt(); + print_current_matches(); Irssi::signal_stop(); return; } - if ($key == 7) { # Ctrl-G - print "aborting search" if DEBUG; - history_exit(); - - # cancel empties the inputline. - Irssi::gui_input_set(''); - Irssi::gui_input_set_pos(0); + # TODO: handle arrow-keys? + if ($key == 27) { + close_listing_split(); Irssi::signal_stop(); return; } - if ($key == 127) { # DEL - if (length $search_str) { - $search_str = substr($search_str, 0, -1); - print "Deleting char, now: $search_str" if DEBUG; - } + if ($key >= 32 and $key < 127) { # printable + $search_str .= chr($key); + update_history_matches(); update_history_prompt(); update_input(); + print_current_matches(); Irssi::signal_stop(); return; } - # TODO: handle esc- sequences and arrow-keys? - - if ($key >= 32) { # printable - $search_str .= chr($key); + if ($key == 127) { # DEL + if (length $search_str) { + $search_str = substr($search_str, 0, -1); + print "Deleting char, now: $search_str" if DEBUG; + } update_history_matches(); update_history_prompt(); update_input(); + print_current_matches(); Irssi::signal_stop(); return; @@ -273,3 +299,54 @@ sub handle_keypress { history_exit(); #Irssi::signal_stop(); } + +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; + + # restore original window focus + if (Irssi::active_win()->{refnum} != $original_win_ref->{refnum}) { + Irssi::command("window goto $original_win_ref->{refnum}"); + } +} + +sub sig_win_created { + my ($win) = @_; + $split_ref = $win; + # printing directly from this handler causes irssi to segfault. + Irssi::timeout_add_once(10, \&print_current_matches, {}); +} + +sub print_current_matches { + + return unless defined $split_ref; + return unless @search_matches > 0; + + $split_ref->command("clear"); + $split_ref->print('Current history matches. Press to close.'); + + my $hist_entry = get_history_match(); + + foreach my $i (0..$#search_matches) { + my $j = $#search_matches - $i; + my $entry = $search_matches[$j]; + + my $hilight = $hist_entry eq $entry + ? '%_' + : ''; + my $str = sprintf("%s%-6d %s%s", $hilight, $j, $entry, $hilight); + $split_ref->print($str); + } +} -- cgit v1.2.3