home *** CD-ROM | disk | FTP | other *** search
/ PC World 2005 December (Special) / PCWorld_2005-12_Special_cd.bin / Bezpecnost / lsti / lsti.exe / framework-2.5.exe / ISearch.pm < prev    next >
Text File  |  2005-04-27  |  3KB  |  114 lines

  1. package Term::ReadLine::Zoid::ISearch;
  2.  
  3. use strict;
  4. use base 'Term::ReadLine::Zoid';
  5. no warnings; # undef == '' down here
  6.  
  7. our $VERSION = 0.06;
  8.  
  9. our %_keymap = (
  10.     backspace  => 'backward_delete_char',
  11.     ctrl_R     => 'isearch_again',
  12.     _on_switch => 'is_switch',
  13.     _default   => 'self_insert'
  14. );
  15.  
  16. sub keymap { return \%_keymap }
  17.  
  18. sub 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.  
  25. sub 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.  
  33. sub 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.  
  66. sub 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.  
  74. sub isearch_again { $_[0]{is_hist_p} = $_[0]{last_search}[-1] if $_[0]{last_search} }
  75.  
  76. 1;
  77.  
  78. __END__
  79.  
  80. =head1 NAME
  81.  
  82. Term::ReadLine::Zoid::ISearch - a readline incremental search mode
  83.  
  84. =head1 SYNOPSIS
  85.  
  86. This class is used as a mode under L<Term::ReadLine::Zoid>,
  87. see there for usage details.
  88.  
  89. =head1 DESCRIPTION
  90.  
  91. This mode is intended as a work alike for the incremental search
  92. found in the gnu readline library.
  93.  
  94. In this mode the string you enter is regarded as a B<perl regex> which is used
  95. to do an incremental histroy search.
  96.  
  97. Pressing '^R' repeatingly will give alternative results.
  98.  
  99. Special keys like movements or the C<return> drop you out of this mode
  100. and set the edit line to the last search result.
  101.  
  102. =head1 AUTHOR
  103.  
  104. Jaap Karssenberg || Pardus [Larus] E<lt>pardus@cpan.orgE<gt>
  105.  
  106. Copyright (c) 2004 Jaap G Karssenberg. All rights reserved.
  107. This program is free software; you can redistribute it and/or
  108. modify it under the same terms as Perl itself.
  109.  
  110. =head1 SEE ALSO
  111.  
  112. =cut
  113.  
  114.