diff options
| -rw-r--r-- | history-search/complete_test.pl | 27 | ||||
| -rw-r--r-- | history-search/expando_test.pl | 58 | ||||
| -rw-r--r-- | history-search/frog_reload.pl | 99 | ||||
| -rw-r--r-- | history-search/help_a.pl | 15 | ||||
| -rw-r--r-- | history-search/help_b.pl | 15 | ||||
| -rw-r--r-- | history-search/key_test.pl | 100 | ||||
| -rw-r--r-- | history-search/prompt_info.pl | 77 | ||||
| -rw-r--r-- | history-search/rl_history_search.pl | 228 | ||||
| -rw-r--r-- | history-search/subtest.pl | 76 | 
9 files changed, 695 insertions, 0 deletions
| diff --git a/history-search/complete_test.pl b/history-search/complete_test.pl new file mode 100644 index 0000000..a8ae485 --- /dev/null +++ b/history-search/complete_test.pl @@ -0,0 +1,27 @@ +use strict; +use vars qw($VERSION %IRSSI); + +use Irssi; +$VERSION = '2.1'; +%IRSSI = ( +    authors     => 'Daenyth', +    contact     => 'Daenyth /at/ gmail /dot/ com', +    name        => 'Complete Last-Spoke', +    description => 'When using tab completion on an empty input buffer, complete to the nick of the person who spoke most recently.', +    license     => 'GPL2', +); + +sub do_complete { +	my ($strings, $window, $word, $linestart, $want_space) = @_; +	return unless ($linestart eq '' && $word eq ''); + +#	my $suffix = Irssi::settings_get_str('completion_char'); +#	@$strings = $last_speaker . $suffix; +    push @$strings, qw|/foo /bar /baz /bacon|; + +#	$$want_space = 1; +#	Irssi::signal_stop(); +} + + Irssi::signal_add_first( 'complete word',  \&do_complete); + diff --git a/history-search/expando_test.pl b/history-search/expando_test.pl new file mode 100644 index 0000000..0d5456a --- /dev/null +++ b/history-search/expando_test.pl @@ -0,0 +1,58 @@ +use strict; +use Irssi; +use Irssi::TextUI; # for sbar_items_redraw + +use vars qw($VERSION %IRSSI); +$VERSION = "1.0.1"; +%IRSSI = ( +	authors         => "shabble", +	contact         => 'shabble+irssi@metavore.org, shabble@#irssi/Freenode', +	name            => "", +	description     => "", +	license         => "Public Domain", +	changed         => "" +); + +my $prompt_additional_content = ''; + +Irssi::expando_create('prompt_additional', \&expando_prompt, {}); + +#TODO: necessary? +#Irssi::signal_add_last 'gui print text finished' => \&redraw_prompts; + +sub expando_prompt { +    my ($server, $witem, $arg) = @_; +    return $prompt_additional_content; +} + +sub redraw_prompts { +    Irssi::statusbar_items_redraw ('prompt'); +    Irssi::statusbar_items_redraw ('prompt_empty'); +} + +sub handle_change_prompt_sig { +    my ($text) = @_; + +    print "Got prompt change sig with: $text"; + +    my $expanded_text = Irssi::parse_special($text); +    my $changed = ($expanded_text ne $prompt_additional_content); + +    $prompt_additional_content = $expanded_text; + +    if ($changed) { +        print "Redrawing prompts"; +        redraw_prompts(); +    } +} + +sub prompt_additional_cmd { +    my ($str) = @_; +    print "Setting prompt to: $str"; +    Irssi::signal_emit('change prompt', $str); +} + +Irssi::signal_register({'change prompt' => [qw/string/]}); +Irssi::signal_add('change prompt' => \&handle_change_prompt_sig); + +Irssi::command_bind('set_prompt' => \&prompt_additional_cmd); diff --git a/history-search/frog_reload.pl b/history-search/frog_reload.pl new file mode 100644 index 0000000..678c87d --- /dev/null +++ b/history-search/frog_reload.pl @@ -0,0 +1,99 @@ +use strict; +use warnings; + +use Irssi; +use File::ChangeNotify(); +use File::Spec (); +use File::Basename qw(basename); + +#my $THIS_SCRIPT = basename __FILE__; + +my $irssi_dir = Irssi::get_irssi_dir(); +my @watch_dirs = ($irssi_dir, $irssi_dir . '/scripts', +                  $irssi_dir . '/scripts/autorun'); + +my $watcher = File::ChangeNotify->instantiate_watcher +  ( +   directories => \@watch_dirs, +   filter => qr/\.(?:pl|py)$/, +  ); + +my @watchers = File::ChangeNotify->usable_classes(); +print "Started reloader watching: ", join(", ", @watch_dirs), " using $watchers[0]"; + +my %action_for = ( +	create => sub { +		my ($path) = @_; +		Irssi::print ("CREATE: Loading $path"); +        load_script($path); +	}, + +	modify => sub { +		my ($path) = @_; +		Irssi::print ("MODIFY: reloading $path"); +        reload($path); +    }, + +	delete => sub { +		my ($path) = @_; +		Irssi::print ("DELETE: Unloading $path"); +        unload_script($path); +	}, +); + +#TODO: change me back. +Irssi::timeout_add(3000, \&timer_sub, undef); + +sub timer_sub { +    print "Timer sub called"; +    my @new_events = $watcher->new_events; +	for my $event (@new_events) { + +        print "Handling event: ", $event->type, " path: ", $event->path; + +		if (my $callback = $action_for{$event->type}) { +			$callback->($event->path); +		} +	} +} + +sub reload { +    my ($path) = @_; + +    unload_script($path); +    load_script($path); +} + +sub unload_script { +    my ($script_path) = @_; +    my $name = filepath_to_script($script_path); + +    if (script_is_loaded($name)) { +        Irssi::print ("unloading $name..."); +        Irssi::command("script unload $name"); +    } +} + +sub load_script { +    my ($script_path) = @_; +    Irssi::command("script load \"$script_path\""); +} + +sub filepath_to_script { +    my ($path) = @_; + +    my $name = basename $path; +    $name =~ s/\.pl$//i; + +    return $name; +} + +sub script_is_loaded { +    my $name = shift; +    print "Checking if $name is loaded"; +    no strict 'refs'; +    my $retval = defined %{ "Irssi::Script::${name}::" }; +    use strict 'refs'; + +    return $retval; +} diff --git a/history-search/help_a.pl b/history-search/help_a.pl new file mode 100644 index 0000000..53d902c --- /dev/null +++ b/history-search/help_a.pl @@ -0,0 +1,15 @@ +use strict; +use warnings; + +use Irssi; + +our $help = "this is help for a"; + +Irssi::command_bind('help', sub { +        if ($_[0] eq 'test_a') { +            Irssi::print($help, MSGLEVEL_CLIENTCRAP); +            Irssi::signal_stop(); +            return; +        } +  } +); diff --git a/history-search/help_b.pl b/history-search/help_b.pl new file mode 100644 index 0000000..8b57a45 --- /dev/null +++ b/history-search/help_b.pl @@ -0,0 +1,15 @@ +use strict; +use warnings; + +use Irssi; + +our $help = "this is help for b"; + +Irssi::command_bind('help', sub { +        if ($_[0] eq 'test_b') { +            Irssi::print($help, MSGLEVEL_CLIENTCRAP); +            Irssi::signal_stop(); +            return; +        } +  } +); diff --git a/history-search/key_test.pl b/history-search/key_test.pl new file mode 100644 index 0000000..b16ff00 --- /dev/null +++ b/history-search/key_test.pl @@ -0,0 +1,100 @@ +use strict; +use Irssi; +use Irssi::TextUI; # for sbar_items_redraw + +use vars qw($VERSION %IRSSI); +$VERSION = "1.0.1"; +%IRSSI = ( +	authors         => "shabble", +	contact         => 'shabble+irssi@metavore.org, shabble@#irssi/Freenode', +	name            => "", +	description     => "", +	license         => "Public Domain", +	changed         => "" +); + + +Irssi::signal_add_last 'gui key pressed' => \&got_key; + +my $buf = ''; + +sub got_key { +    my ($key) = @_; +    $buf .= " $key"; +    my $res = decode_keypress($key); +    if (defined $res) { +        print "codes: $buf"; +        print "Keypress: $res"; +        $buf = ''; +    } +} + +# 1 means we've seen an esc, 2 means we've +# seen an esc,[. 0 is normal. + +my $decoder_state = 0; + +sub decode_keypress { +    my ($code) = @_; + +    if ($decoder_state == 1) { + +        # seen esc/meta. +        if ($code == ord('[')) { +            $decoder_state = 2; +            return undef; +        } else { +            $decoder_state = 0; +            return 'meta-' . chr($code); +        } + +    } elsif ($decoder_state == 2) { + +        if ($code == ord('A')) { +            $decoder_state = 0; +            return 'up-arrow'; +        } elsif ($code == ord('B')) { +            $decoder_state = 0; +            return 'dn-arrow' +        } elsif ($code == ord('C')) { +            $decoder_state = 0; +            return 'right-arrow' +        } elsif ($code == ord('D')) { +            $decoder_state = 0; +            return 'left-arrow' +        } + +        $decoder_state = 0; +        return undef; + +    } else { + +        if ($code < 27) { + +            if ($code == 9) { +                return 'tab'; +            } + +            return 'ctrl-' . chr($code + ord('a') -1); +        } + +        if ($code > 32 && $code < 127) { +            return chr($code); +        } + +        if ($code == 32) { +            return 'space'; +        } + +        if ($code == 127) { +            return 'backspace'; +        } + +        if ($code == 27) { +            $decoder_state = 1; +            return undef; +        } + +        return 'unknown ' . $code; +    } +} diff --git a/history-search/prompt_info.pl b/history-search/prompt_info.pl new file mode 100644 index 0000000..ad5321b --- /dev/null +++ b/history-search/prompt_info.pl @@ -0,0 +1,77 @@ +# Usage: + +# edit your theme, find the line beginning: +# +#    prompt = "..." +# +# and add the string `$prompt_additional' somewhere inside it. +# If using the default: prompt = "[$*] ", then a good value would be: +# +#    prompt = "[$*$prompt_additional] " +# +# Then add this script to your autorun directory (~/.irssi/scripts/autorun/) +# +# You can modify your prompt content by using the '/set_prompt <string>' command, +# or from scripts by Irssi:signal_emit('change prompt', $string); + +use strict; +use warnings; + +use Irssi; +use Irssi::TextUI; # for sbar_items_redraw + +use vars qw($VERSION %IRSSI); +$VERSION = "1.0.1"; +%IRSSI = +  ( +   authors         => "shabble", +   contact         => 'shabble+irssi@metavore.org, shabble@#irssi/Freenode', +   name            => "prompt_info", +   description     => "Helper script for dynamically adding text " +                    . "into the input-bar prompt.", +   license         => "Public Domain", +   changed         => "24/7/2010" +  ); + +sub DEBUG () { 0 } + +my $prompt_additional_content = ''; + +Irssi::expando_create('prompt_additional', \&expando_prompt, {}); + +sub expando_prompt { +    my ($server, $witem, $arg) = @_; +    return $prompt_additional_content; +} + +sub redraw_prompts { +    Irssi::statusbar_items_redraw ('prompt'); +    Irssi::statusbar_items_redraw ('prompt_empty'); +} + +sub handle_change_prompt_sig { +    my ($text) = @_; + +    print "Got prompt change sig with: $text" if DEBUG; + +    my $expanded_text = Irssi::parse_special($text); +    my $changed = ($expanded_text ne $prompt_additional_content); + +    $prompt_additional_content = $expanded_text; + +    if ($changed) { +        print "Redrawing prompts" if DEBUG; +        redraw_prompts(); +    } +} + +sub prompt_additional_cmd { +    my ($str) = @_; +    print "Setting prompt to: $str" if DEBUG; +    Irssi::signal_emit('change prompt', $str); +} + +Irssi::signal_register({'change prompt' => [qw/string/]}); +Irssi::signal_add('change prompt' => \&handle_change_prompt_sig); + +Irssi::command_bind('set_prompt' => \&prompt_additional_cmd); diff --git a/history-search/rl_history_search.pl b/history-search/rl_history_search.pl new file mode 100644 index 0000000..9b58fd7 --- /dev/null +++ b/history-search/rl_history_search.pl @@ -0,0 +1,228 @@ +# Search within your typed history as you type (like ctrl-R in bash) +# 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) + +# * Hitting enter selects a match and terminates search mode. + +# * You can use ^G to exit search mode without selecting. + + +# Original script Copyright 2007  Wouter Coekaerts <coekie@irssi.org> +# Heavy modifications by Shabble <shabble+irssi@metavore.org>, 2010. + +# 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 + +use strict; +use Irssi; +use Irssi::TextUI; +use Data::Dumper; + +use vars qw($VERSION %IRSSI); +$VERSION = '1.0'; +%IRSSI = +  ( +   authors     => 'Wouter Coekaerts, Tom Feist', +   contact     => 'coekie@irssi.org', +   name        => 'rl_history_search', +   description => 'Search within your typed history as you type' +                . ' (like ctrl-R in readline applications)', +   license     => 'GPLv2 or later', +   url         => 'http://wouter.coekaerts.be/irssi/', +   changed     => '24/7/2010' +  ); + +my $search_str = ''; +my $search_active = 0; + +my @history_cache  = (); +my @search_matches = (); +my $match_index = 0; + + +sub DEBUG () { 0 } + +# check we have prompt_info 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; +} + +unless (script_is_loaded('prompt_info')) { +    die "This script requires 'prompt_info' in order to work. " +      . "Please load it and try again"; +} else { +    history_init(); +} + +sub history_init { +    Irssi::command_bind('history_search_start', \&history_search); +    #Irssi::command_bind('history_search_exit', \&history_search_exit); +    Irssi::signal_add_first('gui key pressed' => \&handle_keypress); +} + +sub history_search { +    $search_active = 1; +    $search_str = ''; +    $match_index = -1; + +    @history_cache = Irssi::active_win()->get_history_lines(); +    @search_matches = (); + +    update_history_prompt(); +} + +sub history_exit { +    $search_active = 0; +    Irssi::signal_emit('change prompt', ''); +} + +sub update_history_prompt { +    Irssi::signal_emit('change prompt', " reverse-i-search: \`$search_str'"); +} + +sub update_history_matches { +    my ($match_str) = @_; +    $match_str //= $search_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; +} + +sub get_history_match { +    return $search_matches[$match_index]; +} + +sub prev_match { + +    $match_index++; +    if ($match_index > $#search_matches) { +        $match_index = 0; +    } +    print "index now: $match_index" if DEBUG; +} + +sub next_match { + +    $match_index--; +    if ($match_index < 0) { +        $match_index = $#search_matches; +    } +    print "index now: $match_index" if DEBUG; +} + +sub update_input { +    my $match = get_history_match(); +    Irssi::gui_input_set($match); +	Irssi::gui_input_set_pos(length $match); +} + +sub handle_keypress { +	my ($key) = @_; + +    return unless $search_active; + +	if ($key == 10) { # enter +        print "selecting history and quitting" if DEBUG; +        history_exit(); +        return; +	} + +    if ($key == 18) { # Ctrl-R +        print "skipping to prev match" if DEBUG; +        prev_match(); +        update_input(); +        update_history_prompt(); +        Irssi::signal_stop(); # prevent the bind from being re-triggered. +        return; +    } + +    if ($key == 19) { # Ctrl-S +        print "skipping to next match" if DEBUG; +        next_match(); +        update_input(); +        update_history_prompt(); + +        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); + +        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; +        } +        update_history_matches(); +        update_history_prompt(); + +        Irssi::signal_stop(); +        return; +    } + +    # TODO: handle esc- sequences and arrow-keys? + +    if ($key >= 32) { # printable +        $search_str .= chr($key); + +        update_history_matches(); +        update_history_prompt(); +        update_input(); + +        Irssi::signal_stop(); +        return; +    } + +    # any other key exits, for now. +    history_exit(); +    #Irssi::signal_stop(); +} diff --git a/history-search/subtest.pl b/history-search/subtest.pl new file mode 100644 index 0000000..fd5a9cc --- /dev/null +++ b/history-search/subtest.pl @@ -0,0 +1,76 @@ +use strict; +use Irssi; +use Irssi::TextUI; +use Data::Dumper; + +use vars qw($VERSION %IRSSI); +$VERSION = '1.0'; +%IRSSI = ( +    authors     => 'Wouter Coekaerts', +    contact     => 'coekie@irssi.org', +    name        => 'history_search', +    description => 'Search within your typed history as you type (like ctrl-R in bash)', +    license     => 'GPLv2 or later', +    url         => 'http://wouter.coekaerts.be/irssi/', +    changed     => '04/08/07' +); + + +Irssi::command_bind("foo bar", \&subcmd_bar); +Irssi::command_bind("foo", \&subcmd_handler); + +sub subcmd_handler { +    my ($data, $server, $item) = @_; +    $data =~ s/\s+$//g; +    Irssi::command_runsub('foo', $data, $server, $item); +} + +sub subcmd_bar { +    my ($args) = @_; +    print "subcommand called with: $args"; +} + +# my $prev_typed; +# my $prev_startpos; +# my $enabled = 0; + +# Irssi::command_bind('history_search', sub { +# 	$enabled = ! $enabled; +# 	if ($enabled) { +# 		$prev_typed = ''; +# 		$prev_startpos = 0; +# 	} +# }); + +# Irssi::signal_add_last 'gui key pressed' => sub { +# 	my ($key) = @_; +	 +# 	if ($key == 10) { # enter +# 		$enabled = 0; +# 	} + +# 	return unless $enabled; +	 +# 	my $prompt = Irssi::parse_special('$L'); +# 	my $pos = Irssi::gui_input_get_pos(); +	 +# 	if ($pos < $prev_startpos) { +# 		$enabled = 0; +# 		return; +# 	} +	 +# 	my $typed = substr($prompt, $prev_startpos, ($pos-$prev_startpos)); +	 +# 	my $history = ($typed eq '') ? '' : Irssi::parse_special('$!' . $typed . '!'); +# 	if ($history eq '') { +# 		$history = $typed; +# 	} +	 +# 	my $startpos = index(lc($history), lc($typed)); +		 +# 	Irssi::gui_input_set($history); +# 	Irssi::gui_input_set_pos($startpos + length($typed)); +	 +# 	$prev_typed = $typed; +# 	$prev_startpos = $startpos; +# }; | 
