This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Fix ext/XS-APItest/t/multicall.t warning
[perl5.git] / lib / Term / Complete.pm
1 package Term::Complete;
2 require 5.000;
3 require Exporter;
4
5 use strict;
6 our @ISA = qw(Exporter);
7 our @EXPORT = qw(Complete);
8 our $VERSION = '1.402';
9
10 #      @(#)complete.pl,v1.2            (me@anywhere.EBay.Sun.COM) 09/23/91
11
12 =head1 NAME
13
14 Term::Complete - Perl word completion module
15
16 =head1 SYNOPSIS
17
18     $input = Complete('prompt_string', \@completion_list);
19     $input = Complete('prompt_string', @completion_list);
20
21 =head1 DESCRIPTION
22
23 This routine provides word completion on the list of words in
24 the array (or array ref).
25
26 The tty driver is put into raw mode and restored using an operating
27 system specific command, in UNIX-like environments C<stty>.
28
29 The following command characters are defined:
30
31 =over 4
32
33 =item E<lt>tabE<gt>
34
35 Attempts word completion.
36 Cannot be changed.
37
38 =item ^D
39
40 Prints completion list.
41 Defined by I<$Term::Complete::complete>.
42
43 =item ^U
44
45 Erases the current input.
46 Defined by I<$Term::Complete::kill>.
47
48 =item E<lt>delE<gt>, E<lt>bsE<gt>
49
50 Erases one character.
51 Defined by I<$Term::Complete::erase1> and I<$Term::Complete::erase2>.
52
53 =back
54
55 =head1 DIAGNOSTICS
56
57 Bell sounds when word completion fails.
58
59 =head1 BUGS
60
61 The completion character E<lt>tabE<gt> cannot be changed.
62
63 =head1 AUTHOR
64
65 Wayne Thompson
66
67 =cut
68
69 our($complete, $kill, $erase1, $erase2, $tty_raw_noecho, $tty_restore, $stty, $tty_safe_restore);
70 our($tty_saved_state) = '';
71 CONFIG: {
72     $complete = "\004";
73     $kill     = "\025";
74     $erase1 =   "\177";
75     $erase2 =   "\010";
76     foreach my $s (qw(/bin/stty /usr/bin/stty)) {
77         if (-x $s) {
78             $tty_raw_noecho = "$s raw -echo";
79             $tty_restore    = "$s -raw echo";
80             $tty_safe_restore = $tty_restore;
81             $stty = $s;
82             last;
83         }
84     }
85 }
86
87 sub Complete {
88     my($prompt, @cmp_lst, $cmp, $test, $l, @match);
89     my ($return, $r) = ("", 0);
90
91     $return = "";
92     $r      = 0;
93
94     $prompt = shift;
95     if (ref $_[0] || $_[0] =~ /^\*/) {
96         @cmp_lst = sort @{$_[0]};
97     }
98     else {
99         @cmp_lst = sort(@_);
100     }
101
102     # Attempt to save the current stty state, to be restored later
103     if (defined $stty && defined $tty_saved_state && $tty_saved_state eq '') {
104         $tty_saved_state = qx($stty -g 2>/dev/null);
105         if ($?) {
106             # stty -g not supported
107             $tty_saved_state = undef;
108         }
109         else {
110             $tty_saved_state =~ s/\s+$//g;
111             $tty_restore = qq($stty "$tty_saved_state" 2>/dev/null);
112         }
113     }
114     system $tty_raw_noecho if defined $tty_raw_noecho;
115     LOOP: {
116         local $_;
117         print($prompt, $return);
118         while (($_ = getc(STDIN)) ne "\r") {
119             CASE: {
120                 # (TAB) attempt completion
121                 $_ eq "\t" && do {
122                     @match = grep(/^\Q$return/, @cmp_lst);
123                     unless ($#match < 0) {
124                         $l = length($test = shift(@match));
125                         foreach $cmp (@match) {
126                             until (substr($cmp, 0, $l) eq substr($test, 0, $l)) {
127                                 $l--;
128                             }
129                         }
130                         print("\a");
131                         print($test = substr($test, $r, $l - $r));
132                         $r = length($return .= $test);
133                     }
134                     last CASE;
135                 };
136
137                 # (^D) completion list
138                 $_ eq $complete && do {
139                     print(join("\r\n", '', grep(/^\Q$return/, @cmp_lst)), "\r\n");
140                     redo LOOP;
141                 };
142
143                 # (^U) kill
144                 $_ eq $kill && do {
145                     if ($r) {
146                         $r      = 0;
147                         $return = "";
148                         print("\r\n");
149                         redo LOOP;
150                     }
151                     last CASE;
152                 };
153
154                 # (DEL) || (BS) erase
155                 ($_ eq $erase1 || $_ eq $erase2) && do {
156                     if($r) {
157                         print("\b \b");
158                         chop($return);
159                         $r--;
160                     }
161                     last CASE;
162                 };
163
164                 # printable char
165                 ord >= 32 && do {
166                     $return .= $_;
167                     $r++;
168                     print;
169                     last CASE;
170                 };
171             }
172         }
173     }
174
175     # system $tty_restore if defined $tty_restore;
176     if (defined $tty_saved_state && defined $tty_restore && defined $tty_safe_restore)
177     {
178         system $tty_restore;
179         if ($?) {
180             # tty_restore caused error
181             system $tty_safe_restore;
182         }
183     }
184     print("\n");
185     $return;
186 }
187
188 1;