1package Term::ReadLine::Zoid::ISearch; 2 3use strict; 4use base 'Term::ReadLine::Zoid'; 5no warnings; # undef == '' down here 6 7our $VERSION = 0.06; 8 9our %_keymap = ( 10 backspace => 'backward_delete_char', 11 ctrl_R => 'isearch_again', 12 _on_switch => 'is_switch', 13 _default => 'self_insert' 14); 15 16sub keymap { return \%_keymap } 17 18sub is_switch { 19 my $self = shift; 20 $$self{is_lock} = undef; 21 $$self{is_hist_p} = -1; 22 $$self{is_save} = [[''], [0,0], undef]; 23} 24 25sub is_switch_back { 26 my ($self, $key) = @_; 27 $$self{_hist_save} = $self->save(); 28 @$self{qw/lines pos hist_p/} = @{$$self{is_save}}; 29 $self->switch_mode(); 30 $self->do_key($key); 31} 32 33sub draw { # rendering this inc mode is kinda consuming 34 my ($self, @args) = @_; 35 my $save = $self->save(); 36 my $string = join "\n", @{$$self{lines}}; 37 $$self{prompt} = "i-search qr($string): "; 38 goto DRAW unless length $string; 39 40 my ($result, $match, $hist_p) = (undef, '', $$self{is_hist_p}); 41 $$self{last_search} = ['b', $string]; 42 my $reg = eval { qr/^(.*?$string)/ }; 43 goto DRAW if $@; 44 45 while ($hist_p < $#{$$self{history}}) { 46 $hist_p++; 47 next unless $$self{history}[$hist_p] =~ $reg; 48 ($result, $match) = ($$self{history}[$hist_p], $1); 49 last; 50 } 51 52 if (defined $result) { 53 push @{$$self{last_search}}, $hist_p; 54 $$self{is_lock} = undef; 55 $$self{lines} = [ split /\n/, $result ]; 56 my @match = split /\n/, $match; 57 $$self{pos} = [length($match[-1]), $#match]; 58 } 59 else { $$self{is_lock} = 1 } 60 61 DRAW: Term::ReadLine::Zoid::draw($self, @args); 62 $$self{is_save} = [ $$self{lines}, $$self{pos}, $hist_p]; 63 $self->restore($save); 64} 65 66sub self_insert { 67 if ($_[0]{is_lock}) { $_[0]->bell } 68 elsif ($_[0]->key_binding($_[1], $_[0]{config}{default_mode})) { 69 goto \&is_switch_back; 70 } 71 else { goto \&Term::ReadLine::Zoid::self_insert } 72} 73 74sub isearch_again { $_[0]{is_hist_p} = $_[0]{last_search}[-1] if $_[0]{last_search} } 75 761; 77 78__END__ 79 80=head1 NAME 81 82Term::ReadLine::Zoid::ISearch - a readline incremental search mode 83 84=head1 SYNOPSIS 85 86This class is used as a mode under L<Term::ReadLine::Zoid>, 87see there for usage details. 88 89=head1 DESCRIPTION 90 91This mode is intended as a work alike for the incremental search 92found in the gnu readline library. 93 94In this mode the string you enter is regarded as a B<perl regex> which is used 95to do an incremental histroy search. 96 97Pressing '^R' repeatingly will give alternative results. 98 99Special keys like movements or the C<return> drop you out of this mode 100and set the edit line to the last search result. 101 102=head1 AUTHOR 103 104Jaap Karssenberg || Pardus [Larus] E<lt>pardus@cpan.orgE<gt> 105 106Copyright (c) 2004 Jaap G Karssenberg. All rights reserved. 107This program is free software; you can redistribute it and/or 108modify it under the same terms as Perl itself. 109 110=head1 SEE ALSO 111 112=cut 113 114