From 8a8ba2c51eadbc0a7ce0236ba6a04dd081f657e2 Mon Sep 17 00:00:00 2001 From: Tom Feist Date: Fri, 1 Apr 2011 06:43:04 +0100 Subject: modify all scripts to use the new script_is_loaded() function, since newer versions of perl get upset at defined(%hash). --- history-search/rl_history_search.pl | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) (limited to 'history-search') diff --git a/history-search/rl_history_search.pl b/history-search/rl_history_search.pl index ca45fe5..642b99c 100644 --- a/history-search/rl_history_search.pl +++ b/history-search/rl_history_search.pl @@ -81,13 +81,7 @@ sub DEBUG () { $DEBUG_ENABLED } # check we have uberprompt loaded. sub script_is_loaded { - my $name = shift; - print "Checking if $name is loaded" if DEBUG; - no strict 'refs'; - my $retval = defined %{ "Irssi::Script::${name}::" }; - use strict 'refs'; - - return $retval; + return exists($Irssi::Script::{shift . '::'}) ; } if (not script_is_loaded('uberprompt')) { @@ -103,7 +97,7 @@ if (not script_is_loaded('uberprompt')) { } history_init(); } else { - history_init(); + history_init(); } sub load_uberprompt_failed { -- cgit v1.2.3 From 9b4f3c204419e20bcb470b8aa04a6ffb4e35fdfb Mon Sep 17 00:00:00 2001 From: Tom Feist Date: Fri, 1 Apr 2011 07:26:42 +0100 Subject: Bah. more fixing of script_is_loaded. --- history-search/rl_history_search.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'history-search') diff --git a/history-search/rl_history_search.pl b/history-search/rl_history_search.pl index 642b99c..2df9171 100644 --- a/history-search/rl_history_search.pl +++ b/history-search/rl_history_search.pl @@ -81,7 +81,7 @@ sub DEBUG () { $DEBUG_ENABLED } # check we have uberprompt loaded. sub script_is_loaded { - return exists($Irssi::Script::{shift . '::'}) ; + return exists($Irssi::Script::{$_[0] . '::'}) ; } if (not script_is_loaded('uberprompt')) { -- cgit v1.2.3 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(-) (limited to 'history-search') 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 From eaf8973e9f8f141f8163d8897245c2263b13e34b Mon Sep 17 00:00:00 2001 From: Tom Feist Date: Sat, 9 Apr 2011 16:15:11 +0100 Subject: rl_history_search: added bits of flex-matching from ido_switcher. Permanently enabled so far, but soon to be optional/configurable. --- history-search/rl_history_search.pl | 83 +++++++++++++++++++++++++++++++++---- 1 file changed, 76 insertions(+), 7 deletions(-) (limited to 'history-search') diff --git a/history-search/rl_history_search.pl b/history-search/rl_history_search.pl index dc3d91a..7ce76d1 100644 --- a/history-search/rl_history_search.pl +++ b/history-search/rl_history_search.pl @@ -78,6 +78,11 @@ my $match_index = 0; my $split_ref; my $original_win_ref; +# formats +my $list_format; + +my $use_flex_match = 1; + my $DEBUG_ENABLED = 0; sub DEBUG () { $DEBUG_ENABLED } @@ -121,6 +126,7 @@ sub history_init { Irssi::signal_add ('setup changed' => \&setup_changed); Irssi::signal_add_first('gui key pressed' => \&handle_keypress); + $list_format = Irssi::theme_register([ list_format => '$*' ]); setup_changed(); } @@ -158,7 +164,13 @@ sub update_history_matches { $match_str = $search_str unless defined $match_str; my %unique; - my @matches = grep { m/\Q$match_str/i } @history_cache; + my @matches; + + if ($use_flex_match) { + @matches = grep { flex_match($_) >= 0 } @history_cache; + } else { + @matches = grep { m/\Q$match_str/i } @history_cache; + } @search_matches = (); @@ -176,6 +188,56 @@ sub update_history_matches { join(", ", @search_matches) if DEBUG; } +sub flex_match { + my ($obj) = @_; + + my $pattern = $search_str; + my $source = $obj; #->{name}; + + #_debug_print "Flex match: $pattern / $source"; + + # default to matching everything if we don't have a pattern to compare + # against. + + return 0 unless $pattern; + + my @chars = split '', lc($pattern); + my $ret = -1; + my $first = 0; + + my $lc_source = lc($source); + + #$obj->{hilight_field} = 'name'; + + foreach my $char (@chars) { + my $pos = index($lc_source, $char, $ret); + if ($pos > -1) { + + # store the beginning of the match + #$obj->{b_pos} = $pos unless $first; + $first = 1; + + #_debug_print("matched: $char at $pos in $source"); + $ret = $pos + 1; + + } else { + + #$obj->{b_pos} = $obj->{e_pos} = -1; + #_debug_print "Flex returning: -1"; + + return -1; + } + } + + #_debug_print "Flex returning: $ret"; + + #store the end of the match. + #$obj->{e_pos} = $ret; + + return $ret; +} + + sub get_history_match { return $search_matches[$match_index]; } @@ -318,7 +380,7 @@ sub close_listing_split { # restore original window focus if (Irssi::active_win()->{refnum} != $original_win_ref->{refnum}) { - Irssi::command("window goto $original_win_ref->{refnum}"); + $original_win_ref->set_active(); } } @@ -334,8 +396,12 @@ 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.'); + $split_ref->command("^clear"); + my $orig_ts_level = Irssi::parse_special('$timestamp_level'); + $split_ref->command("^set timestamp_level $orig_ts_level -CLIENTCRAP"); + + $split_ref->print('Current history matches. Press to close.', + Irssi::MSGLEVEL_CLIENTCRAP|Irssi::MSGLEVEL_NEVER); my $hist_entry = get_history_match(); @@ -344,9 +410,12 @@ sub print_current_matches { my $entry = $search_matches[$j]; my $hilight = $hist_entry eq $entry - ? '%_' + ? '%g' : ''; - my $str = sprintf("%s%-6d %s%s", $hilight, $j, $entry, $hilight); - $split_ref->print($str); + $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); } + $split_ref->command("^set timestamp_level $orig_ts_level"); + } -- cgit v1.2.3 From ec8a62c0225133a60396b81a38c46885134f306c Mon Sep 17 00:00:00 2001 From: Tom Feist Date: Wed, 13 Apr 2011 09:29:09 +0100 Subject: rl_history_search: make split info text bold --- history-search/rl_history_search.pl | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'history-search') diff --git a/history-search/rl_history_search.pl b/history-search/rl_history_search.pl index 7ce76d1..e0d73be 100644 --- a/history-search/rl_history_search.pl +++ b/history-search/rl_history_search.pl @@ -48,6 +48,13 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +# TODO: +# +# * document tab behaviour +# * add keys (C-n/C-p) to scroll history list +# * if list is bigger than split size, centre it so selected item is visible +# * allow a mechanism to select by number from list + use strict; use Irssi; use Irssi::TextUI; @@ -400,7 +407,7 @@ sub print_current_matches { my $orig_ts_level = Irssi::parse_special('$timestamp_level'); $split_ref->command("^set timestamp_level $orig_ts_level -CLIENTCRAP"); - $split_ref->print('Current history matches. Press to close.', + $split_ref->print('%_Current history matches. Press to close.%_', Irssi::MSGLEVEL_CLIENTCRAP|Irssi::MSGLEVEL_NEVER); my $hist_entry = get_history_match(); -- cgit v1.2.3 From 15b8c9cfe925b2fd214d5077726ab63e8e25ce60 Mon Sep 17 00:00:00 2001 From: Tom Feist Date: Wed, 13 Apr 2011 23:36:52 +0100 Subject: rl_history_search: make split ensure that selected item is always visible when nunber of matches > window size --- history-search/rl_history_search.pl | 88 ++++++++++++++++++++++++++++++------- 1 file changed, 73 insertions(+), 15 deletions(-) (limited to 'history-search') 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 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 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); } -- cgit v1.2.3 From e8fc333f3a28ae7a5c03952c66b528bfe31c7f75 Mon Sep 17 00:00:00 2001 From: Tom Feist Date: Wed, 13 Apr 2011 23:43:02 +0100 Subject: rl_history_search: intial search (no search string) now lets you cycle through all possible matches, rather than none. --- history-search/rl_history_search.pl | 1 + 1 file changed, 1 insertion(+) (limited to 'history-search') diff --git a/history-search/rl_history_search.pl b/history-search/rl_history_search.pl index a3651bc..ec8764e 100644 --- a/history-search/rl_history_search.pl +++ b/history-search/rl_history_search.pl @@ -151,6 +151,7 @@ sub history_search { $original_win_ref = Irssi::active_win; + update_history_matches(); update_history_prompt(); } -- cgit v1.2.3 From 54e5dd68538add429e3dba2c1a37c1ff34af03f2 Mon Sep 17 00:00:00 2001 From: Tom Feist Date: Thu, 14 Apr 2011 00:23:39 +0100 Subject: rl_history_search: added 'number select mode', accessible with C-f when the split list is displayed. Currently the numbers don't quite match up, but it appears to work. --- history-search/rl_history_search.pl | 82 ++++++++++++++++++++++++++++++++----- 1 file changed, 71 insertions(+), 11 deletions(-) (limited to 'history-search') diff --git a/history-search/rl_history_search.pl b/history-search/rl_history_search.pl index ec8764e..8da9584 100644 --- a/history-search/rl_history_search.pl +++ b/history-search/rl_history_search.pl @@ -28,6 +28,11 @@ # # * You can use ^G to exit search mode without selecting. # +# * Pressing whilst the search is active will open a new split +# window, showing all matching completions. will close the window +# again, as will any other action that exits history search mode. +# Possible candidates can be cycled through as normal using C-r and C-s. +# # * Any other ctrl- or meta- key binding will terminate search mode, leaving the # selected item in the input line. # @@ -50,9 +55,9 @@ # TODO: # -# * document tab behaviour +# * DONE document tab behaviour # * add keys (C-n/C-p) to scroll history list -# * if list is bigger than split size, centre it so selected item is visible +# * DONE if list is bigger than split size, centre it so selected item is visible # * allow a mechanism to select by number from list use strict; @@ -77,6 +82,9 @@ $VERSION = '2.0'; my $search_str = ''; my $search_active = 0; +my $select_num_active = 0; +my $num_buffer; + my @history_cache = (); my @search_matches = (); my $match_index = 0; @@ -146,10 +154,11 @@ sub history_search { $search_str = ''; $match_index = 0; - @history_cache = Irssi::active_win()->get_history_lines(); + my $win = Irssi::active_win; + @history_cache = $win->get_history_lines(); @search_matches = (); - $original_win_ref = Irssi::active_win; + $original_win_ref = $win; update_history_matches(); update_history_prompt(); @@ -158,15 +167,12 @@ sub history_search { sub history_exit { $search_active = 0; close_listing_split(); - Irssi::signal_emit('change prompt', '', 'UP_INNER'); + _set_prompt(''); } sub update_history_prompt { my $col = scalar(@search_matches) ? '%g' : '%r'; - Irssi::signal_emit('change prompt', - ' reverse-i-search: `' . $col . $search_str - . '%n' . "'", - 'UP_INNER'); + _set_prompt(' reverse-i-search: `' . $col . $search_str . '%n' . "'"); } sub update_history_matches { @@ -204,7 +210,7 @@ sub flex_match { my $pattern = $search_str; my $source = $obj; #->{name}; - #_debug_print "Flex match: $pattern / $source"; + #_debug("Flex match: $pattern / $source"); # default to matching everything if we don't have a pattern to compare # against. @@ -247,6 +253,30 @@ sub flex_match { return $ret; } +sub enter_select_num_mode { + # require that the list be shown. + return unless defined $split_ref; + return if $select_num_active; # TODO: should we prevent restarting? + + $num_buffer = 0; + _set_prompt("Num select: "); + $select_num_active = 1; +} + +sub exit_select_num_mode { + + $select_num_active = 0; + $num_buffer = 0; + update_history_prompt(); +} + +sub history_select_num { + if ($num_buffer > 0 && $num_buffer <= $#search_matches) { + $match_index = $num_buffer; + my $match = get_history_match(); + _debug("Num select: got $match"); + } +} sub get_history_match { return $search_matches[$match_index]; @@ -281,6 +311,32 @@ sub handle_keypress { return unless $search_active; + if ($select_num_active) { + if ($key >= 48 and $key <= 57) { # Number key + + $num_buffer = ($num_buffer * 10) + $key - 48; + _set_prompt("Num select: $num_buffer"); + + } elsif ($key == 10) { # ENTER + + history_select_num(); + update_input(); + exit_select_num_mode(); + history_exit(); + + } else { # anything else quits. + exit_select_num_mode(); + } + Irssi::signal_stop(); + return; + } + + if ($key == 6) { # Ctrl-F + enter_select_num_mode(); + Irssi::signal_stop(); + return; + } + if ($key == 7) { # Ctrl-G print "aborting search" if DEBUG; history_exit(); @@ -339,7 +395,6 @@ sub handle_keypress { return; } - if ($key >= 32 and $key < 127) { # printable $search_str .= chr($key); @@ -485,3 +540,8 @@ sub _debug { my $str = sprintf($msg, @args); $original_win_ref->print($str); } +sub _set_prompt { + my ($str) = @_; + $str = ' ' . $str if length $str; + Irssi::signal_emit('change prompt', $str, 'UP_INNER'); +} -- cgit v1.2.3 From 0c63d1e251c2e6b85a0306a7a0b191d2f8829cd1 Mon Sep 17 00:00:00 2001 From: Tom Feist Date: Thu, 14 Apr 2011 00:38:45 +0100 Subject: rl_history_search: clarify copyright, bump version number and add more things to TODO --- history-search/rl_history_search.pl | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) (limited to 'history-search') diff --git a/history-search/rl_history_search.pl b/history-search/rl_history_search.pl index 8da9584..4bb0fcd 100644 --- a/history-search/rl_history_search.pl +++ b/history-search/rl_history_search.pl @@ -37,7 +37,7 @@ # selected item in the input line. # # Original script Copyright 2007 Wouter Coekaerts -# Heavy modifications by Shabble , 2010. +# Heavy modifications Copyright 2010-11 Tom Feist # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -56,18 +56,20 @@ # TODO: # # * DONE document tab behaviour -# * add keys (C-n/C-p) to scroll history list +# * add keys (C-n/C-p) to scroll history list if necessary. # * DONE if list is bigger than split size, centre it so selected item is visible -# * allow a mechanism to select by number from list +# * INPROG allow a mechanism to select by number from list +# * steal more of the code from ido_switcher to hilight match positions. +# * make flex matching optional (key or setting) +# * add some online help (? or C-h triggered, maybe?) use strict; use Irssi; use Irssi::TextUI; use Data::Dumper; -use vars qw($VERSION %IRSSI); -$VERSION = '2.0'; -%IRSSI = +our $VERSION = '2.5'; +our %IRSSI = ( authors => 'Tom Feist, Wouter Coekaerts', contact => 'shabble+irssi@metavore.org, shabble@#irssi/freenode', @@ -76,7 +78,7 @@ $VERSION = '2.0'; . ' (like ctrl-R in readline applications)', license => 'GPLv2 or later', url => 'http://github.com/shabble/irssi-scripts/tree/master/history-search/', - changed => '24/7/2010' + changed => '14/4/2011' ); my $search_str = ''; @@ -149,6 +151,10 @@ sub setup_changed { $DEBUG_ENABLED = Irssi::settings_get_bool('histsearch_debug'); } +sub history_window_open { + return defined $split_ref; +} + sub history_search { $search_active = 1; $search_str = ''; @@ -255,7 +261,7 @@ sub flex_match { sub enter_select_num_mode { # require that the list be shown. - return unless defined $split_ref; + return unless history_window_open(); return if $select_num_active; # TODO: should we prevent restarting? $num_buffer = 0; @@ -351,7 +357,7 @@ sub handle_keypress { if ($key == 9) { # TAB update_history_matches(); - if (not defined $split_ref) { + if (not history_window_open()) { create_listing_split(); } else { print_current_matches(); @@ -438,7 +444,7 @@ sub create_listing_split { sub close_listing_split { - if (defined $split_ref) { + if (history_window_open()) { Irssi::command("window close $split_ref->{refnum}"); undef $split_ref; } @@ -458,7 +464,7 @@ sub sig_win_created { sub print_current_matches { - return unless defined $split_ref; + return unless history_window_open(); my $num_matches = scalar(@search_matches); return unless $num_matches > 0; -- cgit v1.2.3 From 8bd10e8beedd06465081b55581e64f590c60687f Mon Sep 17 00:00:00 2001 From: Tom Feist Date: Thu, 14 Apr 2011 06:29:44 +0100 Subject: rl_history_search: try to abstract the temporary split window concept so it can be used for help display as well (and hoepfully, be used in other scripts too) --- history-search/rl_history_search.pl | 82 ++++++++++++++++++++++++------------- 1 file changed, 53 insertions(+), 29 deletions(-) (limited to 'history-search') diff --git a/history-search/rl_history_search.pl b/history-search/rl_history_search.pl index 4bb0fcd..e9a365e 100644 --- a/history-search/rl_history_search.pl +++ b/history-search/rl_history_search.pl @@ -62,6 +62,14 @@ # * steal more of the code from ido_switcher to hilight match positions. # * make flex matching optional (key or setting) # * add some online help (? or C-h triggered, maybe?) +# * make temp_split stuff more generic (to be used by help, etc) +# * figure out why sometimes the split list doesn't update correctly (eg: no matches) +# * consider tracking history manually (via send command/send text) +# * Pro: we could timestamp it. +# * Con: Would involve catching up/down and all the other history selection +# mechanisms. +# * Compromise - tag history as it comes it (match it with data via sig handlers?) +# * Possibility of saving/restoring history over sessions? use strict; use Irssi; @@ -75,7 +83,7 @@ our %IRSSI = contact => 'shabble+irssi@metavore.org, shabble@#irssi/freenode', name => 'rl_history_search', description => 'Search within your typed history as you type' - . ' (like ctrl-R in readline applications)', + . ' (like ctrl-R in readline applications)', license => 'GPLv2 or later', url => 'http://github.com/shabble/irssi-scripts/tree/master/history-search/', changed => '14/4/2011' @@ -129,7 +137,7 @@ sub load_uberprompt_failed { Irssi::signal_remove('script error', 'load_prompt_failed'); print "Script could not be loaded. Script cannot continue. " - . "Check you have uberprompt.pl installed in your path and " + . "Check you have uberprompt.pl installed in your path and " . "try again."; die "Script Load Failed: " . join(" ", @_); @@ -151,7 +159,7 @@ sub setup_changed { $DEBUG_ENABLED = Irssi::settings_get_bool('histsearch_debug'); } -sub history_window_open { +sub temp_split_active () { return defined $split_ref; } @@ -172,7 +180,7 @@ sub history_search { sub history_exit { $search_active = 0; - close_listing_split(); + close_temp_split(); _set_prompt(''); } @@ -214,7 +222,7 @@ sub flex_match { my ($obj) = @_; my $pattern = $search_str; - my $source = $obj; #->{name}; + my $source = $obj; #->{name}; #_debug("Flex match: $pattern / $source"); @@ -261,7 +269,7 @@ sub flex_match { sub enter_select_num_mode { # require that the list be shown. - return unless history_window_open(); + return unless temp_split_active(); return if $select_num_active; # TODO: should we prevent restarting? $num_buffer = 0; @@ -323,27 +331,27 @@ sub handle_keypress { $num_buffer = ($num_buffer * 10) + $key - 48; _set_prompt("Num select: $num_buffer"); - } elsif ($key == 10) { # ENTER + } elsif ($key == 10) { # ENTER history_select_num(); update_input(); exit_select_num_mode(); history_exit(); - } else { # anything else quits. + } else { # anything else quits. exit_select_num_mode(); } Irssi::signal_stop(); return; } - if ($key == 6) { # Ctrl-F + if ($key == 6) { # Ctrl-F enter_select_num_mode(); Irssi::signal_stop(); return; } - if ($key == 7) { # Ctrl-G + if ($key == 7) { # Ctrl-G print "aborting search" if DEBUG; history_exit(); @@ -354,11 +362,15 @@ sub handle_keypress { Irssi::signal_stop(); return; } + if ($key == 8) { # C-h + $original_win_ref->print("This would show help, " + . "if there was any. Coming soon!"); + } - if ($key == 9) { # TAB + if ($key == 9) { # TAB update_history_matches(); - if (not history_window_open()) { - create_listing_split(); + if (not temp_split_active()) { + create_temp_split() if @search_matches > 0; } else { print_current_matches(); } @@ -366,23 +378,23 @@ sub handle_keypress { Irssi::signal_stop(); return; } - if ($key == 10) { # enter + if ($key == 10) { # enter print "selecting history and quitting" if DEBUG; history_exit(); return; } - if ($key == 18) { # Ctrl-R + if ($key == 18) { # Ctrl-R print "skipping to prev match" if DEBUG; prev_match(); update_input(); update_history_prompt(); print_current_matches(); - Irssi::signal_stop(); # prevent the bind from being re-triggered. + Irssi::signal_stop(); # prevent the bind from being re-triggered. return; } - if ($key == 19) { # Ctrl-S + if ($key == 19) { # Ctrl-S print "skipping to next match" if DEBUG; next_match(); update_input(); @@ -396,7 +408,7 @@ sub handle_keypress { # TODO: handle arrow-keys? if ($key == 27) { - close_listing_split(); + close_temp_split(); Irssi::signal_stop(); return; } @@ -413,7 +425,7 @@ sub handle_keypress { return; } - if ($key == 127) { # DEL + if ($key == 127) { # DEL if (length $search_str) { $search_str = substr($search_str, 0, -1); @@ -433,18 +445,16 @@ sub handle_keypress { #Irssi::signal_stop(); } -sub create_listing_split { - - return unless @search_matches > 0; +sub create_temp_split { 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 { +sub close_temp_split { - if (history_window_open()) { + if (temp_split_active()) { Irssi::command("window close $split_ref->{refnum}"); undef $split_ref; } @@ -464,10 +474,10 @@ sub sig_win_created { sub print_current_matches { - return unless history_window_open(); + return unless temp_split_active(); my $num_matches = scalar(@search_matches); - return unless $num_matches > 0; + #return unless $num_matches > 0; # for some woefully unobvious reason, we need to refetch # the window reference in order for its attribute hash @@ -491,7 +501,11 @@ sub print_current_matches { $s_win->print('%_Current history matches. Press to close.%_', MSGLEVEL_CLIENTCRAP | MSGLEVEL_NEVER); - $split_height -= 2; # account for header line; + if ($num_matches == 0) { + $s_win->print('(No Matches)', MSGLEVEL_CLIENTCRAP | MSGLEVEL_NEVER); + return; + } + $split_height -= 2; # account for header line; my $hist_entry = get_history_match(); @@ -518,7 +532,7 @@ sub print_current_matches { } _debug("sh: $split_height, hh: $half_height, " - . "mi: $match_index, start: $start, end: $end"); + . "mi: $match_index, start: $start, end: $end"); } else { $start = 0; $end = $#search_matches; @@ -540,11 +554,21 @@ sub print_current_matches { $s_win->command("^set timestamp_level $orig_ts_level"); } +sub print_help { + +} + +sub _print_to_active { + my ($msg, @args) = @_; + my $str = sprintf($msg, @args); + $original_win_ref->print($str,MSGLEVEL_CLIENTCRAP | MSGLEVEL_NEVER); +} + sub _debug { return unless DEBUG; my ($msg, @args) = @_; my $str = sprintf($msg, @args); - $original_win_ref->print($str); + $original_win_ref->print($str, MSGLEVEL_CLIENTCRAP | MSGLEVEL_NEVER); } sub _set_prompt { my ($str) = @_; -- cgit v1.2.3 From 218d26e7fa71af86c66c433a75a33d096402627a Mon Sep 17 00:00:00 2001 From: Tom Feist Date: Mon, 18 Apr 2011 15:06:04 +0100 Subject: trying out README's in pod now, to avoid the markdown pain. --- history-search/README.pod | 135 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 135 insertions(+) create mode 100644 history-search/README.pod (limited to 'history-search') diff --git a/history-search/README.pod b/history-search/README.pod new file mode 100644 index 0000000..ce0a42f --- /dev/null +++ b/history-search/README.pod @@ -0,0 +1,135 @@ +=pod + +=head1 NAME + +rl_history_search.pl + +=head1 DESCRIPTION + +Search within your typed history as you type (something like ctrl-R in bash or other +readline-type applications.) + +=head1 INSTALLATION + +Copy into your F<~/.irssi/scripts/> directory and load with +C>. + +This script requires that you have first installed and loaded F + +Uberprompt can be downloaded from: + +L + +and follow the instructions at the top of that file or its README for installation. + +If uberprompt.pl is available, but not loaded, this script will make one +attempt to load it before giving up. This eliminates the need to precisely +arrange the startup order of your scripts. + +=head1 SETUP + +C + +Where C<^R> is a key of your choice. + +=head1 USAGE + +Type C followed by your search string. The prompt line will show +you the most recent command to match the string you've typed. + +B You can cycle through multiple matches with C (to select older +matches), and (to select newer matches). Cycling off the end of the +history list returns you to the other end again. + +B C may not work if you have software flow control configured for +your terminal. It may appear to freeze irssi entirely. If this happens, it can +be restored with C, but you will be unable to use the C binding. +You can disable flow control by running the command C in your +terminal, or setting C in your F<~/.screenrc>if using GNU Screen. + +=head2 COMMANDS + +=over 4 + +=item C selects a match and terminates search mode. B + +=item C exits search mode without selecting. + +=item CTABE> will open a new split window, showing all matching + completions. CEscE> will close the window again, as will any other + action that exits history search mode. Possible candidates can be cycled + through as normal using C and . + +=item Any other ctrl- or meta- key binding will terminate search mode, leaving + the selected item in the input line. + +=back + +=head1 AUTHORS + +Original script L Copyright E 2007 Wouter Coekaerts + +Copyright E 2011 Tom Feist Cshabble+irssi@metavore.orgE> + +=head1 LICENCE + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=head1 BUGS + +faff + + +=head1 TODO + +=over 1 + +=item * DONE document tab behaviour + +=item * add keys (C-n/C-p) to scroll history list if necessary. + +=item * DONE if list is bigger than split size, centre it so selected item is visible + +=item * INPROG allow a mechanism to select by number from list + +=item * steal more of the code from ido_switcher to hilight match positions. + +=item * make flex matching optional (key or setting) + +=item * add some online help (? or C-h triggered, maybe?) + +=item * make temp_split stuff more generic (to be used by help, etc) + +=item * figure out why sometimes the split list doesn't update correctly (eg: no matches) + +=item * consider tracking history manually (via send command/send text) + +=item + +=over 4 + +=item * Pro: we could timestamp it. + +=item * Con: Would involve catching up/down and all the other history selection mechanisms. + +=item * Compromise - tag history as it comes it (match it with data via sig handlers?) + +=back + +=item * Possibility of saving/restoring history over sessions? + +=back + -- cgit v1.2.3 From 25af30751d22508bd7b89fbe2dc367ef8c657af1 Mon Sep 17 00:00:00 2001 From: Tom Feist Date: Mon, 18 Apr 2011 15:24:48 +0100 Subject: protecting my newly podded docs against a rogue README generator. --- history-search/rl_history_search.pl | 219 ++++++++++++++++++++++++------------ 1 file changed, 146 insertions(+), 73 deletions(-) (limited to 'history-search') diff --git a/history-search/rl_history_search.pl b/history-search/rl_history_search.pl index e9a365e..7561386 100644 --- a/history-search/rl_history_search.pl +++ b/history-search/rl_history_search.pl @@ -1,75 +1,147 @@ -# Search within your typed history as you type (like ctrl-R in bash) -# -# INSTALL: -# -# This script requires that you have first installed and loaded 'uberprompt.pl' -# Uberprompt can be downloaded from: -# -# http://github.com/shabble/irssi-scripts/raw/master/prompt_info/uberprompt.pl -# -# and follow the instructions at the top of that file for installation. -# -# USAGE: -# -# * Setup: /bind ^R /history_search_start -# -# * Then type ctrl-R and type what you're searching for -# -# * You can cycle through multiple matches with ^R (older matches), and -# ^S (newer matches) -# -# NOTE: Ctrl-S may not work if you have software flow control configured for -# your terminal. It may appear to freeze irssi entirely. If this happens, it can -# be restored with Ctrl-Q, but you will be unable to use the Ctrl-S binding. -# You can disable flow control by running the command `stty -ixon' in your -# terminal, or setting `defflow off' in your ~/.screenrc if using GNU Screen. -# -# * Hitting enter selects a match and terminates search mode. -# -# * You can use ^G to exit search mode without selecting. -# -# * Pressing whilst the search is active will open a new split -# window, showing all matching completions. will close the window -# again, as will any other action that exits history search mode. -# Possible candidates can be cycled through as normal using C-r and C-s. -# -# * Any other ctrl- or meta- key binding will terminate search mode, leaving the -# selected item in the input line. -# -# Original script Copyright 2007 Wouter Coekaerts -# Heavy modifications Copyright 2010-11 Tom Feist -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -# TODO: -# -# * DONE document tab behaviour -# * add keys (C-n/C-p) to scroll history list if necessary. -# * DONE if list is bigger than split size, centre it so selected item is visible -# * INPROG allow a mechanism to select by number from list -# * steal more of the code from ido_switcher to hilight match positions. -# * make flex matching optional (key or setting) -# * add some online help (? or C-h triggered, maybe?) -# * make temp_split stuff more generic (to be used by help, etc) -# * figure out why sometimes the split list doesn't update correctly (eg: no matches) -# * consider tracking history manually (via send command/send text) -# * Pro: we could timestamp it. -# * Con: Would involve catching up/down and all the other history selection -# mechanisms. -# * Compromise - tag history as it comes it (match it with data via sig handlers?) -# * Possibility of saving/restoring history over sessions? +=pod + +=head1 NAME + +rl_history_search.pl + +=head1 DESCRIPTION + +Search within your typed history as you type (something like ctrl-R in bash or other +readline-type applications.) + +=head1 INSTALLATION + +Copy into your F<~/.irssi/scripts/> directory and load with +C>. + +This script requires that you have first installed and loaded F + +Uberprompt can be downloaded from: + +L + +and follow the instructions at the top of that file or its README for installation. + +If uberprompt.pl is available, but not loaded, this script will make one +attempt to load it before giving up. This eliminates the need to precisely +arrange the startup order of your scripts. + +=head1 SETUP + +C + +Where C<^R> is a key of your choice. + +=head1 USAGE + +Type C followed by your search string. The prompt line will show +you the most recent command to match the string you've typed. + +B You can cycle through multiple matches with C (to select older +matches), and (to select newer matches). Cycling off the end of the +history list returns you to the other end again. + +B C may not work if you have software flow control configured for +your terminal. It may appear to freeze irssi entirely. If this happens, it can +be restored with C, but you will be unable to use the C binding. +You can disable flow control by running the command C in your +terminal, or setting C in your F<~/.screenrc>if using GNU Screen. + +=head2 COMMANDS + +=over 4 + +=item C + +Selects a match and terminates search mode. +B + +=item C + +Exits search mode without selecting. + +=item CTABE + +Opens a new split window, showing all matching completions. CEscE> +will close the window again, as will any other action that exits history search +mode. Possible candidates can be cycled through as normal using C and +. + +=item Any other ctrl- or meta- key + +This will terminate search mode, leaving the selected item in the input line. +It will not run the command (Except for C and C, which are +functionally equivalent to C). + +=back + +=head1 AUTHORS + +Original script L Copyright E 2007 Wouter Coekaerts + +Most of the other fancy stuff Copyright E 2011 Tom Feist +Cshabble+irssi@metavore.orgE> + +=head1 LICENCE + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +=head1 BUGS + +Yeah, probably. + +=head1 TODO + +=over 1 + +=item * B document tab behaviour + +=item * add keys (C-n/C-p) to scroll history list if necessary. + +=item * B if list is bigger than split size, centre it so selected item is visible + +=item * I allow a mechanism to select by number from list + +=item * steal more of the code from ido_switcher to hilight match positions. + +=item * make flex matching optional (key or setting) + +=item * add some online help (? or C-h triggered, maybe?) + +=item * make temp_split stuff more generic (to be used by help, etc) + +=item * figure out why sometimes the split list doesn't update correctly (eg: no matches) + +=item * consider tracking history manually (via send command/send text) + +=over 4 + +=item * Pro: we could timestamp it. + +=item * Con: Would involve catching up/down and all the other history selection mechanisms. + +=item * Compromise - tag history as it comes it (match it with data via sig handlers?) + +=back + +=item * Possibility of saving/restoring history over sessions? + +=back + +=cut + use strict; use Irssi; @@ -86,7 +158,8 @@ our %IRSSI = . ' (like ctrl-R in readline applications)', license => 'GPLv2 or later', url => 'http://github.com/shabble/irssi-scripts/tree/master/history-search/', - changed => '14/4/2011' + changed => '14/4/2011', + requires => [qw/uberprompt.pl/], ); my $search_str = ''; -- cgit v1.2.3