Commit | Line | Data |
---|---|---|
86530b38 AT |
1 | package Psh::Completion; |
2 | ||
3 | use strict; | |
4 | require Psh::Util; | |
5 | require Psh::OS; | |
6 | ||
7 | my $APPEND="not_implemented"; | |
8 | ||
9 | @Psh::Completion::bookmarks= (); | |
10 | @Psh::Completion::autoload=(); | |
11 | ||
12 | my %module_loaded=(); | |
13 | ||
14 | sub init | |
15 | { | |
16 | my $attribs=$Psh::term->Attribs; | |
17 | ||
18 | # The following is ridiculous, but.... | |
19 | if( $Psh::term->ReadLine eq 'Term::ReadLine::Perl') { | |
20 | $APPEND='completer_terminator_character'; | |
21 | } elsif( $Psh::term->ReadLine eq 'Term::ReadLine::Gnu') { | |
22 | $APPEND='completion_append_character'; | |
23 | } | |
24 | ||
25 | # Only ::Gnu understand it, and ::Perl ignores it silently. | |
26 | $attribs->{completion_display_matches_hook} | |
27 | = \&display_match_list; | |
28 | } | |
29 | ||
30 | sub start_module { | |
31 | my $command= shift; | |
32 | my $file= $Psh::Completion::modules{$command}; | |
33 | return unless $file; | |
34 | return if $module_loaded{$file}; | |
35 | open(FILE, "< $file"); | |
36 | my @lines= <FILE>; | |
37 | close(FILE); | |
38 | if (@lines) { | |
39 | my $text= join('',@lines); | |
40 | Psh::process_variable($text); | |
41 | $module_loaded{$file}=1; | |
42 | } | |
43 | } | |
44 | ||
45 | { | |
46 | my $kh_loaded=0; | |
47 | sub bookmarks { | |
48 | return @Psh::Completion::bookmarks if $kh_loaded; | |
49 | push @Psh::Completion::bookmarks, Psh::OS::get_known_hosts(); | |
50 | $kh_loaded=1; | |
51 | return @Psh::Completion::bookmarks; | |
52 | } | |
53 | } | |
54 | ||
55 | # Returns a list of possible file completions | |
56 | sub cmpl_filenames | |
57 | { | |
58 | my $text= shift; | |
59 | my $executable_only= shift||0; | |
60 | ||
61 | my $exclam=0; | |
62 | ||
63 | # HACK HACK HACK - this needs to be fixed some other way - | |
64 | # the completion code is severly messed I fear | |
65 | $text= Psh::Parser::unquote($text); | |
66 | $text=~ s/\\//g; | |
67 | # HACK END | |
68 | ||
69 | if ( $executable_only) { | |
70 | if ($text=~s/^\!//) { | |
71 | $exclam=1; | |
72 | } | |
73 | } | |
74 | ||
75 | my $globtext= $text; | |
76 | my $prepend= ''; | |
77 | ||
78 | if( substr($text,0,1) eq '"') { | |
79 | $prepend='"'; | |
80 | $globtext= substr($text,1); | |
81 | } | |
82 | ||
83 | my @result; | |
84 | ||
85 | if (substr($globtext,0,1) eq '~' and !($globtext=~/\//)) { | |
86 | # after ~ try username completion | |
87 | @result= cmpl_usernames($globtext); | |
88 | $Psh::Completion::ac="/" if @result; | |
89 | return @result; | |
90 | } | |
91 | ||
92 | @result= Psh::OS::glob("$globtext*"); | |
93 | ||
94 | if( Psh::Options::has_option('fignore')) { | |
95 | my @ignore= Psh::Options::get_option('fignore'); | |
96 | @result= grep { | |
97 | my $item= $_; | |
98 | my $result= ! grep { Psh::Util::ends_with($item,$_) } @ignore; | |
99 | $result; | |
100 | } @result; | |
101 | } | |
102 | ||
103 | if ( $executable_only) { | |
104 | @result= grep { -x $_ || -d _ } @result; | |
105 | } | |
106 | ||
107 | @result= map { -d $_ ? "$_/" : $_ } @result; | |
108 | ||
109 | # HACK: This won't help much if user tries to do another completion | |
110 | # on the same item afterwards | |
111 |