1package Term::Choose::Opt::Search; 2 3use warnings; 4use strict; 5use 5.10.0; 6 7our $VERSION = '1.745'; 8 9use Term::Choose::Constants qw( ROW COL ); 10use Term::Choose::Screen qw( up clear_to_end_of_screen show_cursor hide_cursor ); 11 12 13sub __user_input { 14 my ( $self, $prompt, $error, $default ) = @_; 15 $self->{plugin}->__reset_mode( { mouse => $self->{mouse}, hide_cursor => $self->{hide_cursor} } ); 16 my $string; 17 if ( ! eval { 18 require Term::Form; 19 Term::Form->VERSION(0.530); 20 my $term = Term::Form->new(); 21 $string = $term->readline( 22 $prompt, 23 { info => $error, default => $default, hide_cursor => 2, clear_screen => length $error ? 1 : 2, 24 color => $self->{color} } 25 ); 26 1 } 27 ) { 28 print "\r", clear_to_end_of_screen(); 29 if ( length $error ) { 30 print $error, "\n\r"; 31 } 32 print show_cursor() if ! $self->{hide_cursor}; 33 print $prompt; 34 $string = <STDIN>; 35 print hide_cursor() if ! $self->{hide_cursor}; 36 chomp $string; 37 } 38 $self->__init_term(); 39 return $string; 40} 41 42 43sub __search_begin { 44 my ( $self ) = @_; 45 my ($search_regex, $error, $default ); 46 47 USER_INPUT: while ( 1 ) { 48 my $search_str = $self->Term::Choose::Opt::Search::__user_input( '> search-pattern: ', $error, $default ); 49 $error = ''; 50 if ( ! length $search_str ) { 51 $self->Term::Choose::Opt::Search::__search_end(); 52 return; 53 } 54 if ( ! eval { 55 if ( $self->{search} == 1 ) { 56 $search_regex = "(?i)$search_str"; 57 $self->{search_info} = 'm/' . $search_str . '/i'; 58 } 59 else { 60 $search_regex = $search_str; 61 $self->{search_info} = 'm/' . $search_str . '/'; 62 } 63 'Teststring' =~ $search_regex; 64 1 } 65 ) { 66 $error = $@; 67 $default = $default eq $search_str ? '' : $search_str; 68 next USER_INPUT; 69 } 70 last USER_INPUT; 71 } 72 $self->{map_search_list_index} = []; 73 my $filtered_list = []; 74 for my $i ( 0 .. $#{$self->{list}} ) { 75 if ( $self->{list}[$i] =~ /$search_regex/ ) { 76 push @{$self->{map_search_list_index}}, $i; 77 push @$filtered_list, $self->{list}[$i]; 78 } 79 } 80 if ( ! @$filtered_list ) { 81 $filtered_list = [ 'No matches found.' ]; 82 $self->{map_search_list_index} = [ 0 ]; 83 } 84 $self->{mark} = $self->__marked_rc2idx(); 85 $self->{backup_list} = [ @{$self->{list}} ]; 86 $self->{list} = $filtered_list; 87 $self->{backup_width_elements} = [ @{$self->{width_elements}} ]; 88 $self->{backup_col_width} = $self->{col_width}; 89 $self->__length_list_elements(); 90 $self->{default} = 0; 91 for my $opt ( qw(meta_items no_spacebar mark) ) { 92 if ( defined $self->{$opt} ) { 93 $self->{'backup_' . $opt} = [ @{$self->{$opt}} ]; 94 my $tmp = []; 95 for my $orig_idx ( @{$self->{$opt}} ) { 96 for my $i ( 0 .. $#{$self->{map_search_list_index}} ) { 97 if ( $self->{map_search_list_index}[$i] == $orig_idx ) { 98 push @$tmp, $i; 99 } 100 } 101 } 102 $self->{$opt} = $tmp; 103 } 104 } 105 my $up = $self->{i_row} + $self->{count_prompt_lines} + 1; # + 1 => readline 106 print up( $up ) if $up; 107 $self->__wr_first_screen(); 108} 109 110 111sub __search_end { 112 my ( $self ) = @_; 113 $self->{search_info} = ''; 114 if ( @{$self->{map_search_list_index}||[]} ) { 115 my $curr_idx = $self->{rc2idx}[ $self->{pos}[ROW] ][ $self->{pos}[COL] ]; 116 $self->{default} = $self->{map_search_list_index}[$curr_idx]; 117 $self->{mark} = $self->__marked_rc2idx(); 118 my $tmp_mark = []; 119 for my $i ( @{$self->{mark}} ) { 120 push @$tmp_mark, $self->{map_search_list_index}[$i]; 121 } 122 my %seen; 123 $self->{mark} = [ grep !$seen{$_}++, @$tmp_mark, defined $self->{backup_mark} ? @{$self->{backup_mark}} : () ]; 124 } 125 delete $self->{map_search_list_index}; 126 delete $self->{backup_mark}; 127 for my $key ( qw(list width_elements col_width meta_items no_spacebar) ) { 128 my $key_backup = 'backup_' . $key; 129 $self->{$key} = $self->{$key_backup} if defined $self->{$key_backup}; 130 delete $self->{$key_backup}; 131 } 132 my $up = $self->{i_row} + $self->{count_prompt_lines}; 133 print up( $up ) if $up; 134 print "\r" . clear_to_end_of_screen(); 135 $self->__wr_first_screen(); 136} 137 138 139 140 141 142 143 1441; 145 146__END__ 147