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