| 1 |
root |
1.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; |