xref: /openbsd-src/gnu/usr.bin/perl/dist/Term-Complete/lib/Term/Complete.pm (revision b8851fcc53cbe24fd20b090f26dd149e353f6174)
1898184e3Ssthenpackage Term::Complete;
2898184e3Ssthenrequire 5.000;
3898184e3Ssthenrequire Exporter;
4898184e3Ssthen
5898184e3Ssthenuse strict;
6898184e3Ssthenour @ISA = qw(Exporter);
7898184e3Ssthenour @EXPORT = qw(Complete);
8*b8851fccSafresh1our $VERSION = '1.403';
9898184e3Ssthen
10898184e3Ssthen#      @(#)complete.pl,v1.2            (me@anywhere.EBay.Sun.COM) 09/23/91
11898184e3Ssthen
12898184e3Ssthen=head1 NAME
13898184e3Ssthen
14898184e3SsthenTerm::Complete - Perl word completion module
15898184e3Ssthen
16898184e3Ssthen=head1 SYNOPSIS
17898184e3Ssthen
18898184e3Ssthen    $input = Complete('prompt_string', \@completion_list);
19898184e3Ssthen    $input = Complete('prompt_string', @completion_list);
20898184e3Ssthen
21898184e3Ssthen=head1 DESCRIPTION
22898184e3Ssthen
23898184e3SsthenThis routine provides word completion on the list of words in
24898184e3Ssthenthe array (or array ref).
25898184e3Ssthen
26898184e3SsthenThe tty driver is put into raw mode and restored using an operating
27898184e3Ssthensystem specific command, in UNIX-like environments C<stty>.
28898184e3Ssthen
29898184e3SsthenThe following command characters are defined:
30898184e3Ssthen
31898184e3Ssthen=over 4
32898184e3Ssthen
33898184e3Ssthen=item E<lt>tabE<gt>
34898184e3Ssthen
35898184e3SsthenAttempts word completion.
36898184e3SsthenCannot be changed.
37898184e3Ssthen
38898184e3Ssthen=item ^D
39898184e3Ssthen
40898184e3SsthenPrints completion list.
41898184e3SsthenDefined by I<$Term::Complete::complete>.
42898184e3Ssthen
43898184e3Ssthen=item ^U
44898184e3Ssthen
45898184e3SsthenErases the current input.
46898184e3SsthenDefined by I<$Term::Complete::kill>.
47898184e3Ssthen
48898184e3Ssthen=item E<lt>delE<gt>, E<lt>bsE<gt>
49898184e3Ssthen
50898184e3SsthenErases one character.
51898184e3SsthenDefined by I<$Term::Complete::erase1> and I<$Term::Complete::erase2>.
52898184e3Ssthen
53898184e3Ssthen=back
54898184e3Ssthen
55898184e3Ssthen=head1 DIAGNOSTICS
56898184e3Ssthen
57898184e3SsthenBell sounds when word completion fails.
58898184e3Ssthen
59898184e3Ssthen=head1 BUGS
60898184e3Ssthen
61898184e3SsthenThe completion character E<lt>tabE<gt> cannot be changed.
62898184e3Ssthen
63898184e3Ssthen=head1 AUTHOR
64898184e3Ssthen
65898184e3SsthenWayne Thompson
66898184e3Ssthen
67898184e3Ssthen=cut
68898184e3Ssthen
69898184e3Ssthenour($complete, $kill, $erase1, $erase2, $tty_raw_noecho, $tty_restore, $stty, $tty_safe_restore);
70898184e3Ssthenour($tty_saved_state) = '';
71898184e3SsthenCONFIG: {
72898184e3Ssthen    $complete = "\004";
73898184e3Ssthen    $kill     = "\025";
74898184e3Ssthen    $erase1 =   "\177";
75898184e3Ssthen    $erase2 =   "\010";
76898184e3Ssthen    foreach my $s (qw(/bin/stty /usr/bin/stty)) {
77898184e3Ssthen	if (-x $s) {
78898184e3Ssthen	    $tty_raw_noecho = "$s raw -echo";
79898184e3Ssthen	    $tty_restore    = "$s -raw echo";
80898184e3Ssthen	    $tty_safe_restore = $tty_restore;
81898184e3Ssthen	    $stty = $s;
82898184e3Ssthen	    last;
83898184e3Ssthen	}
84898184e3Ssthen    }
85898184e3Ssthen}
86898184e3Ssthen
87898184e3Ssthensub Complete {
88898184e3Ssthen    my($prompt, @cmp_lst, $cmp, $test, $l, @match);
89898184e3Ssthen    my ($return, $r) = ("", 0);
90898184e3Ssthen
91898184e3Ssthen    $return = "";
92898184e3Ssthen    $r      = 0;
93898184e3Ssthen
94898184e3Ssthen    $prompt = shift;
95898184e3Ssthen    if (ref $_[0] || $_[0] =~ /^\*/) {
96898184e3Ssthen	@cmp_lst = sort @{$_[0]};
97898184e3Ssthen    }
98898184e3Ssthen    else {
99898184e3Ssthen	@cmp_lst = sort(@_);
100898184e3Ssthen    }
101898184e3Ssthen
102898184e3Ssthen    # Attempt to save the current stty state, to be restored later
103898184e3Ssthen    if (defined $stty && defined $tty_saved_state && $tty_saved_state eq '') {
104898184e3Ssthen	$tty_saved_state = qx($stty -g 2>/dev/null);
105898184e3Ssthen	if ($?) {
106898184e3Ssthen	    # stty -g not supported
107898184e3Ssthen	    $tty_saved_state = undef;
108898184e3Ssthen	}
109898184e3Ssthen	else {
110898184e3Ssthen	    $tty_saved_state =~ s/\s+$//g;
111898184e3Ssthen	    $tty_restore = qq($stty "$tty_saved_state" 2>/dev/null);
112898184e3Ssthen	}
113898184e3Ssthen    }
114898184e3Ssthen    system $tty_raw_noecho if defined $tty_raw_noecho;
115898184e3Ssthen    LOOP: {
116898184e3Ssthen        local $_;
117898184e3Ssthen        print($prompt, $return);
118898184e3Ssthen        while (($_ = getc(STDIN)) ne "\r") {
119898184e3Ssthen            CASE: {
120898184e3Ssthen                # (TAB) attempt completion
121898184e3Ssthen                $_ eq "\t" && do {
122898184e3Ssthen                    @match = grep(/^\Q$return/, @cmp_lst);
123898184e3Ssthen                    unless ($#match < 0) {
124898184e3Ssthen                        $l = length($test = shift(@match));
125898184e3Ssthen                        foreach $cmp (@match) {
126898184e3Ssthen                            until (substr($cmp, 0, $l) eq substr($test, 0, $l)) {
127898184e3Ssthen                                $l--;
128898184e3Ssthen                            }
129898184e3Ssthen                        }
130898184e3Ssthen                        print("\a");
131898184e3Ssthen                        print($test = substr($test, $r, $l - $r));
132898184e3Ssthen                        $r = length($return .= $test);
133898184e3Ssthen                    }
134898184e3Ssthen                    last CASE;
135898184e3Ssthen                };
136898184e3Ssthen
137898184e3Ssthen                # (^D) completion list
138898184e3Ssthen                $_ eq $complete && do {
139898184e3Ssthen                    print(join("\r\n", '', grep(/^\Q$return/, @cmp_lst)), "\r\n");
140898184e3Ssthen                    redo LOOP;
141898184e3Ssthen                };
142898184e3Ssthen
143898184e3Ssthen                # (^U) kill
144898184e3Ssthen                $_ eq $kill && do {
145898184e3Ssthen                    if ($r) {
146898184e3Ssthen                        $r	= 0;
147898184e3Ssthen			$return	= "";
148898184e3Ssthen                        print("\r\n");
149898184e3Ssthen                        redo LOOP;
150898184e3Ssthen                    }
151898184e3Ssthen                    last CASE;
152898184e3Ssthen                };
153898184e3Ssthen
154898184e3Ssthen                # (DEL) || (BS) erase
155898184e3Ssthen                ($_ eq $erase1 || $_ eq $erase2) && do {
156898184e3Ssthen                    if($r) {
157898184e3Ssthen                        print("\b \b");
158898184e3Ssthen                        chop($return);
159898184e3Ssthen                        $r--;
160898184e3Ssthen                    }
161898184e3Ssthen                    last CASE;
162898184e3Ssthen                };
163898184e3Ssthen
164898184e3Ssthen                # printable char
165*b8851fccSafresh1                ord >= ord(" ") && do {
166898184e3Ssthen                    $return .= $_;
167898184e3Ssthen                    $r++;
168898184e3Ssthen                    print;
169898184e3Ssthen                    last CASE;
170898184e3Ssthen                };
171898184e3Ssthen            }
172898184e3Ssthen        }
173898184e3Ssthen    }
174898184e3Ssthen
175898184e3Ssthen    # system $tty_restore if defined $tty_restore;
176898184e3Ssthen    if (defined $tty_saved_state && defined $tty_restore && defined $tty_safe_restore)
177898184e3Ssthen    {
178898184e3Ssthen	system $tty_restore;
179898184e3Ssthen	if ($?) {
180898184e3Ssthen	    # tty_restore caused error
181898184e3Ssthen	    system $tty_safe_restore;
182898184e3Ssthen	}
183898184e3Ssthen    }
184898184e3Ssthen    print("\n");
185898184e3Ssthen    $return;
186898184e3Ssthen}
187898184e3Ssthen
188898184e3Ssthen1;
189