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