1package Vimana::Installer::Text;
2use warnings;
3use strict;
4use base qw(Vimana::Installer);
5use Vimana::Record;
6
7sub read_text {
8    my $self =shift;
9    local $/;
10    open IN , "<" , $self->target;
11    my $text = <IN>;
12    close IN;
13    return $text;
14}
15
16sub script_type {
17    my $self = shift;
18    if( $self->script_info->{type} ) {
19        return 'colors' if $self->script_info->{type} eq 'color scheme' ;
20        return undef if $self->script_info->{type} =~ m/(?:utility|patch)/;
21        return $self->script_info->{type};
22    }
23    else {
24        return undef;
25    }
26}
27
28
29use File::Path qw(rmtree mkpath);
30
31sub copy_to {
32    my ( $self , $path ) = @_;
33    my $src = $self->target;
34
35    my ( $v, $dir, $file ) = File::Spec->splitpath($path);
36    File::Path::mkpath [ $dir ];
37
38    my $ret = File::Copy::copy( $src => $path );
39    if( $ret ) {
40        my (@parts)= File::Spec->splitpath( $src );
41        return File::Spec->join($path,$parts[2]);
42    }
43    print STDERR $! if $!;
44    return;
45}
46
47sub copy_to_rtp {
48    my ( $self, $to ) = @_ ;
49    return $self->copy_to($to);
50}
51
52sub run {
53    my $self = shift;
54    my $verbose = $self->verbose;
55    my $text_content = $self->read_text();
56
57    # XXX: try to use rebless.
58    if( $self->target =~ m/\.vba$/ ) {
59        print "Found Vimball File\n";
60        my $installer = $self->get_installer( 'vimball',
61            package_name => $self->package_name,
62            target       => $self->target,
63            verbose      => $self->verbose
64        );
65        $installer->run();
66        return 1;
67    }
68
69
70    print "Inspecting script content.\n";
71    my $arg = $self->inspect_text_content( $text_content );
72    my $type = $self->script_type();
73
74
75    if ( $arg->{version} ) {
76        # XXX: check version from record.
77
78    }
79
80    if ( $arg->{deps} ) {
81        print "Script dependency tag found. Installing script dependencies.\n";
82        for my $dep ( @{ $arg->{deps} } ) {
83            print "Installing $dep\n";
84            Vimana::Installer->install( $dep );
85        }
86    }
87
88    my $target;
89    if( $type ) {
90        $target = $self->copy_to_rtp(
91                File::Spec->join( $self->runtime_path , $type ));
92        print "Installing script to " . File::Spec->join( $self->runtime_path , $type ) . "\n";
93    }
94    else {
95        # Can't found script ype,
96        # inspect text filetype here.  (colorscheme, ftplugin ...etc)
97        $type = $arg->{type};
98
99        if ($type) {
100            print "Script type found: $type.\n";
101            print "Installing..\n";
102            $target = $self->copy_to_rtp(
103                    File::Spec->join( $self->runtime_path, $type ));
104        }
105        else {
106            print <<END;
107Error: Script type not found.
108File Stored at: @{[ $self->target ]}
109
110We can't get the script type of this plugin "@{[ $self->package_name ]}".
111Please infom the plugin author to add a script type tag like this:
112
113    " ScriptType: [script type]
114
115For example:
116
117    " ScriptType: ftplugin/perl
118
119Thanks.
120END
121            exit;
122            # XXX: more useful message.
123        }
124    }
125
126    if( $type and $target ) {
127        # make record:
128        my @e = Vimana::Record->mk_file_digests( $target );
129        Vimana::Record->add( {
130                version => 0.3,    # record spec version
131                package => $self->package_name,
132                generated_by => 'Vimana-' . $Vimana::VERSION,
133                # Installer type:
134                #   auto , make , rake, text ... etc
135                installer_type =>  $self->installer_type ,
136                files => \@e
137        } );
138    }
139    return $target;
140}
141
142=head2 inspect_text_content
143
144you can add something like this to your vim script file:
145
146    " script type: plugin
147
148    " ScriptType: plugin
149
150    " Script Type: plugin
151
152then the file will be installed into ~/.vim/plugin/
153
154=cut
155
156sub inspect_text_content {
157    my ($self,$content) = @_;
158    my $arg =  {};
159    if( $content =~ m{^"\s*script\s*type:\s*(\w+)}im  ){
160        my $type = $1;
161        $arg->{type} = $type;
162    }
163    else {
164        $arg->{type} = 'colors'   if $content =~ m/^let\s+(g:)?colors_name\s*=/;
165        $arg->{type} = 'syntax'   if $content =~ m/^syn[tax]* (?:match|region|keyword)/;
166        $arg->{type} = 'compiler' if $content =~ m/^let\s+current_compiler\s*=/;
167        $arg->{type} = 'indent'   if $content =~ m/^let\s+b:did_indent/;
168        # XXX: inspect more types.
169    }
170
171    if( $content =~ m{^"\s*(?:script\s*)?(?:deps|dependency|dependencies):\s*(.*)}im ) {
172        my $deps_str = $1;
173        my @deps = split /\s*,\s*/,$deps_str;
174        $arg->{deps} = \@deps;
175    }
176
177    if( $content =~ m{^"\s*tutorial:\s*(.*)}im ) {
178        $arg->{tutorial} = $1;  # URL
179    }
180
181    if( $content =~ m{^"\s*repository:\s*(.*)}im ) {
182        $arg->{repository} = $1;
183    }
184
185    if( $content =~ m{^"\s*(?:script\s*)?version:\s*([.0-9]+)}im ) {
186        $arg->{version} = $1;
187    }
188
189    return $arg;
190}
191
1921;
193