aboutsummaryrefslogtreecommitdiffstats
path: root/history-search
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--history-search/rl_history_search.pl113
1 files 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 <esc> 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);
+ }
+}