Commit | Line | Data |
---|---|---|
86530b38 AT |
1 | #!/usr/local/bin/perl |
2 | # | |
3 | # Complete.pm : | |
4 | # | |
5 | # $Id: Complete.pm,v 1.11 2001/10/09 16:33:10 warp Exp $ | |
6 | ||
7 | package Psh::Builtins::Complete; | |
8 | ||
9 | =item * C<complete module MODULE> | |
10 | ||
11 | Load a pre-defined completion module | |
12 | ||
13 | =item * C<complete module list> | |
14 | ||
15 | Lists pre-defined completion modules | |
16 | ||
17 | =item * C<complete ...> | |
18 | ||
19 | Define programmable completion method. | |
20 | ||
21 | complete [-abcdefjkvu] [-A ACTION] [-G GLOBPAT] [-W WORDLIST] | |
22 | [-P PREFIX] [-S SUFFIX] [-X FILTERPAT] [-x FILTERPAT] | |
23 | [-F FUNCTION] [-C COMMAND] NAME [NAME] .. | |
24 | ||
25 | =item * C<complete -p [NAME ...]> | |
26 | ||
27 | Print completion spec for commands NAME | |
28 | ||
29 | =item * C<complete -r NAME> | |
30 | ||
31 | Delete completion spec for command NAME | |
32 | ||
33 | =cut | |
34 | ||
35 | sub bi_complete { | |
36 | my $cs; | |
37 | ||
38 | if ($_[1] and $_[1][0] and | |
39 | $_[1][0] eq 'module' and | |
40 | $_[1][1]) { | |
41 | my @dirs= | |
42 | ( | |
43 | Psh::OS::catdir(Psh::OS::rootdir(),'usr','share', | |
44 | 'psh','complete'), | |
45 | Psh::OS::catdir(Psh::OS::rootdir(),'usr','local','share', | |
46 | 'psh','complete'), | |
47 | Psh::OS::catdir(Psh::OS::get_home_dir(),'.psh','share','complete'), | |
48 | Psh::OS::catdir(Psh::OS::rootdir(),'psh','complete') | |
49 | ); | |
50 | if ($_[1][1] eq 'list') { | |
51 | my %result=(); | |
52 | foreach my $dir (@dirs) { | |
53 | next unless -r $dir; | |
54 | my @tmp= Psh::OS::glob('*',$dir); | |
55 | foreach my $file (@tmp) { | |
56 | my $full= Psh::OS::catfile($dir,$file); | |
57 | next if !-r $full or -d _; | |
58 | next if $file=~/\~$/; | |
59 | $result{$file}=1; | |
60 | } | |
61 | } | |
62 | Psh::Util::print_list( sort keys %result); | |
63 | return (1,undef); | |
64 | } else { | |
65 | my $file=$_[1][1]; | |
66 | my @lines; | |
67 | foreach my $dir (@dirs) { | |
68 | my $full= Psh::OS::catfile($dir,$file); | |
69 | if (-r $full and !-d $full) { | |
70 | $file= $full; | |
71 | last; | |
72 | } | |
73 | } | |
74 | ||
75 | open(THEME,"< $file"); | |
76 | @lines= <THEME>; | |
77 | close(THEME); | |
78 | if (!@lines) { | |
79 | Psh::Util::print_error("Could not find completion module '$file'.\n"); | |
80 | return (0,undef); | |
81 | } | |
82 | if ($lines[0]=~/^\#\!.*pshcomplete/) { # psh-script | |
83 | my $tmp= $lines[1]; | |
84 | $tmp=~s/^\s*\#//; | |
85 | my @commands= split /\s+/, $tmp; | |
86 | foreach (@commands) { | |
87 | $Psh::Completion::modules{$_}= $file; | |
88 | } | |
89 | return (1,undef); | |
90 | } else { | |
91 | Psh::Util::print_error("Completion module '$file' is not in a valid format.\n"); | |
92 | return (0,undef); | |
93 | } | |
94 | } | |
95 | } | |
96 | elsif (!$_[1]) { | |
97 | require Psh::Builtins::Help; | |
98 | Psh::Builtins::Help::bi_help('complete'); | |
99 | return (0,undef); | |
100 | } | |
101 | ||
102 | require Psh::PCompletion; | |
103 | if (!($cs= Psh::PCompletion::pcomp_getopts($_[1]))) { | |
104 | require Psh::Builtins::Help; | |
105 | Psh::Builtins::Help::bi_help('complete'); | |
106 | return (0,undef); | |
107 | } | |
108 | ||
109 | ||
110 | @_ = @{$_[1]}; | |
111 | ||
112 | if (! $cs->{remove} && $#_ < 0) { | |
113 | # no option or only -p | |
114 | foreach (sort keys(%Psh::PCompletion::COMPSPEC)) { | |
115 | print_compspec($_); | |
116 | } | |
117 | } elsif ($cs->{print}) { | |
118 | foreach (@_) { | |
119 | print_compspec($_); | |
120 | } | |
121 | } elsif ($cs->{remove}) { | |
122 | @_ = keys %Psh::PCompletion::COMPSPEC if ($#_ < 0); | |
123 | foreach (@_) { | |
124 | delete $Psh::PCompletion::COMPSPEC{$_}; | |
125 | } | |
126 | } else { | |
127 | foreach (@_) { | |
128 | $Psh::PCompletion::COMPSPEC{$_} = $cs; | |
129 | } | |
130 | } | |
131 | return (1,undef); | |
132 | } | |
133 | ||
134 | sub print_compspec ($) { | |
135 | my ($cmd) = @_; | |
136 | require Psh::PCompletion; | |
137 | ||
138 | my $cs = $Psh::PCompletion::COMPSPEC{$cmd}; | |
139 | print 'complete'; | |
140 | foreach (sort keys(%Psh::PCompletion::ACTION)) { | |
141 | print " -A $_" if ($cs->{action} & $Psh::PCompletion::ACTION{$_}); | |
142 | } | |
143 | print " -G \'$cs->{globpat}\'" if defined $cs->{globpat}; | |
144 | print " -W \'$cs->{wordlist}\'" if defined $cs->{wordlist}; | |
145 | print " -C $cs->{command}" if defined $cs->{command}; | |
146 | print " -F $cs->{function}" if defined $cs->{function}; | |
147 | print " -X \'$cs->{filterpat}\'" if defined $cs->{filterpat}; | |
148 | print " -x \'$cs->{ffilterpat}\'" if defined $cs->{ffilterpat}; | |
149 | print " -P \'$cs->{prefix}\'" if defined $cs->{prefix}; | |
150 | print " -S \'$cs->{suffix}\'" if defined $cs->{suffix}; | |
151 | print " -o $cs->{option}" if defined $cs->{option}; | |
152 | print " $cmd\n"; | |
153 | } | |
154 | ||
155 | sub cmpl_complete { | |
156 | my ($cur, $dummy, $start, $line) = @_; | |
157 | ||
158 | my ($prev) = $start =~ /(\S+)\s+$/; | |
159 | ||
160 | require Psh::PCompletion; | |
161 | ||
162 | my @COMPREPLY = Psh::PCompletion::redir_test($cur, $prev); | |
163 | return @COMPREPLY if @COMPREPLY; | |
164 | ||
165 | if ($start =~ /^\s*(\S+)\s+$/ || $cur eq '-' ) { | |
166 | return qw(-a -b -c -d -e -f -j -k -v -u -r -p -A -G -W -P -S -X -F -C);; | |
167 | } | |
168 | ||
169 | if ($prev eq '-A') { | |
170 | return qw(alias arrayvar binding builtin command directory | |
171 | disabled enabled export file function helptopic hostname | |
172 | job keyword running setopt shopt signal stopped variable); | |
173 | } elsif ($prev eq '-F') { | |
174 | return compgen('-A', 'function', $cur); | |
175 | # } elsif ($prev eq '-C') { | |
176 | # return compgen('-c', $cur); | |
177 | } else { | |
178 | return compgen('-c', $cur); | |
179 | } | |
180 | } | |
181 | ||
182 | 1; | |
183 |